Q当我将一个二维数组传递给一个期望接收指向指针的指针的函数时,我的编译器报错了。
A数组“退化”为指针的规则(参见问题 6.3)不是递归应用的。(一旦规则应用了一次,结果就是一个指针,该规则不再适用。)数组的数组(即 C 语言中的二维数组)会退化为指向数组的指针,而不是指向指针的指针。指向数组的指针可能会令人困惑,并且必须小心处理;另请参阅问题 6.13。
如果您正在将一个二维数组传递给一个函数
int array[NROWS][NCOLUMNS]; f(array);该函数的声明必须匹配
void f(int a[][NCOLUMNS]) { ... }或
void f(int (*ap)[NCOLUMNS]) /* ap is a pointer to an array */ { ... }在第一个声明中,编译器执行了通常的隐式参数重写,“数组的数组”被重写为“指向数组的指针”(参见问题 6.3 和 6.4);在第二种形式中,指针声明是显式的。由于被调用的函数不为数组分配空间,因此它不需要知道整个大小,所以行数,NROWS可以省略。数组的宽度仍然很重要,所以列的维度NCOLUMNS(对于三维或更高维度的数组,中间的维度)必须保留。
如果一个函数已经被声明为接受指向指针的指针,那么直接将其传递一个二维数组几乎肯定是无意义的。在尝试使用二维数组调用它时,必须使用一个中间指针
extern g(int **ipp); int *ip = &array[0][0]; g(&ip); /* PROBABLY WRONG */但这种用法是误导性的,而且几乎肯定是错误的,因为数组已经被“展平”(其形状已经丢失)。
参考文献:K&R1 第 5.10 节,第 110 页
K&R2 第 5.9 节,第 113 页
H&S 第 5.4.3 节,第 126 页