有几点要指出。
首先,您不能像在这里那样分配数组对象:
char A[WIDTH][HEIGHT];
A=rand_grid(WIDTH,HEIGHT);
数组类型的对象不可修改。
其次,C语言中的函数无法返回数组类型。 但是,它们可以返回指向数组的指针:
char (*foo(int width))[HEIGHT]
{
/**
* dynamically allocate memory for a widthxHEIGHT array of char
*/
char (*newArr)[HEIGHT] = malloc(sizeof *newArr * width);
/**
* initialize array contents here
*/
return newArr;
}
语法有点混乱; 它读为
foo -- foo
foo(int width) -- is a function
-- taking an int parameter
*foo(int width) -- returning a pointer
(*foo(int width))[HEIGHT] -- to a HEIGHT-element array
char (*foo(int width))[HEIGHT] -- of char
对于C89,以上代码段中的HEIGHT必须是编译时常量整数表达式(宏,数字文字或由宏和/或数字文字组成的算术表达式)。 我不确定C99是否也适用。
根据您发布的代码片段,您要做的是获取一个已经分配的数组并初始化其内容。 请记住,在大多数情况下,数组类型的表达式将隐式转换为指向基本类型的指针。 IOW,如果将T的N个元素数组传递给函数,则函数实际接收的是指向T的指针:
void foo (T *p) {...}
...
T arr[N];
foo(arr);
对于二维数组,这有点难看:
void foo (T (*p)[M]) {...}
...
T arr[N][M];
foo(arr);
这也依赖于在编译时已知M,这限制了函数的用途。 您想要的是一个可以处理任意大小的二维数组的函数。 我所知道的最好的方法是,不要将指针传递给数组,而是传递array [1]中第一个元素的地址,并将行数和列数作为单独的参数传递:
void foo(T *base, size_t rows, size_t cols) {...}
...
T arr[N][M];
foo (&arr[0][0], N, M);
因此,您的rand_grid函数将如下所示:
void rand_grid(char *base, size_t rows, size_t cols)
{
size_t i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
/**
* Since base is a simple char *, we must index it
* as though it points to a 1-d array. This works if
* base points to the first element of a 2-d array,
* since multi-dimensional arrays are contiguous.
*/
base[i*cols+j] = initial_value();
}
}
}
int main(void)
{
char A[WIDTH][HEIGHT];
rand_grid(&A[0][0], WIDTH, HEIGHT);
...
}
即使表达式&A[0][0]和A产生相同的值(A的基地址),两个表达式的类型也不同。 第一个表达式的结果为指向char的简单指针(char *),第二个表达式的结果为指向char的二维数组的指针(char (*)[HEIGHT])。