有几点需要指出。
首先,你不能像这里那样分配一个数组对象:
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,上述 sn-p 中的 HEIGHT 必须是编译时常量整数表达式(宏、数字文字或由宏和/或数字文字组成的算术表达式)。我不确定 C99 是否也是如此。
根据您发布的 sn-p,您要做的是获取您已经分配的数组并初始化其内容。请记住,在大多数情况下,数组类型的表达式将隐式转换为指向基类型的指针。 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,这限制了函数的有用性。您想要的是一个可以处理任意大小的二维数组的函数。我知道实现这一点的最好方法不是传递指向数组的指针,而是传递数组 [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])。