What is wrong with the following code? How to correct this?
How to return a static multidimensional array of characters?
#include<stdio.h>
#include<conio.h>
#define SIZE 3
char ** MyFunction(void)
{
static char arr[SIZE][SIZE]={
{'A', 'B', 'C'},
开发者_开发知识库 {'D', 'E', 'F'},
{'G', 'H', 'I'}
};
return arr;
}
void main(void)
{
char ** arr1 = NULL;
int i=0;
int j=0;
arr1 = MyFunction();
for(i=0 ; i<SIZE ; i++)
{
for(j=0 ; j<SIZE ; j++)
{
printf("%c, ", arr1[i][j]);
}
printf("\n");
}
getch();
}
First of all, arr can not be a char**
. It is an address, but it's not the address of a pointer -- it's the address of a char[SIZE].
I've always found it easier to deal with these by spliting the dimensions up using typedefs.
#define SIZE 3
typedef char ROW[SIZE]; // a ROW type is an array of chars
ROW* MyFunction(void)
{
static ROW arr[SIZE]={ // arr is an array of ROW objects
{'A', 'B', 'C'},
{'D', 'E', 'F'},
{'G', 'H', 'I'}
};
return arr;
}
void main(void)
{
ROW* arr1 = NULL;
// etc...
Given the declaration
char arr[SIZE][SIZE];
then the type of the expression arr
is char (*)[SIZE]
; therefore, the function type should be
char (*myFunction(void))[SIZE] // myFunction returns a pointer to a SIZE-element
{ // array of char
static char arr[SIZE][SIZE] = ...;
return arr;
}
Yes, the function type definition is ugly. James' typedef version reads more easily, but this is what's happening under the covers.
int main(void)
{
char (*arr1)[SIZE];
int i, j;
arr1 = myFunction();
...
}
change to static char ** arr[][]= ...
Who owns the array?
It is very important because some part of the code has to take full ownership (create, delete) of the array. Other parts of the code can read and write though.
With that philosophy, I would modify the code so that main
function (in reality, it can be any function) takes ownership of arr1
. main
creates arr1
, and passes it to other function (may be in other module) to "initialize" it. Here is a modified version of the program.
#include <stdio.h>
enum{ SIZE = 3 };
void initArray( char arr[ SIZE ][ SIZE ] ) {
char x = 'A';
for( int i = 0; i < SIZE; i++ ) {
for( int j = 0; j < SIZE; j++ ) {
arr[ i ][ j ] = x;
x += 1;
}
}
}
int main()
{
char arr1[ SIZE ][ SIZE ];
initArray( arr1 );
for( int i = 0; i < SIZE; i++ ) {
for( int j = 0; j < SIZE; j++ ) {
printf("%c, ", arr1[ i ][ j ]);
}
printf("\n");
}
}
Upon spending few minutes in searching, I found a good discussion on multi-dimensional array in C.
Another comment on the side. please note that I have done couple of other changes in the code, some are design (e.g. using enum
instead of #define
, declaring variables (i
, j
in most local scope) while some are formatting. Programs are mainly for communicating with other human programmers, so readability of code is very important.
conio.h + getch() is not ANSI C. void main is not ANSI C. Take a new type, it make it easier.
#include<stdio.h>
#include<conio.h>
#define SIZE 3
typedef char CHAR3[SIZE];
CHAR3 *MyFunction(void)
{
static CHAR3 arr[]={
{'A', 'B', 'C'},
{'D', 'E', 'F'},
{'G', 'H', 'I'}
};
return arr;
}
main(void)
{
CHAR3 *arr1 = NULL;
int i=0;
int j=0;
arr1 = MyFunction();
for(i=0 ; i<SIZE ; i++)
{
for(j=0 ; j<SIZE ; j++)
{
printf("%c, ", arr1[i][j]);
}
printf("\n");
}
getch();
}
精彩评论