为什么这些功能原型不相同?
void print_matrix(char *name, int SX, int SY, int m[SX][SY])
void print_matrix(char *name, int SX, int SY, int **m)
答案 0 :(得分:6)
即使两个函数参数可以以相同的方式消耗,即通过m[i][j]
,它们也完全不同:
int m[M][N]
是M
个N
个数组的数组。
int **m
是指向int的指针。
您不能将数组作为函数参数传递,因此“K
类型的T
元素数组”会衰减为“指针指向T
”,指向第一个元素数组。因此,允许并等效于在函数参数中将第一个表单写为int m[][N]
,因为值M
将丢失。但是,值N
不丢失;它是该类型的一部分!
因此,对于第一种形式,以下内容是可接受的/错误的:
void f(int arr[M][N]);
int a[M][N];
int b[2*M][N];
int c[M][N + 1];
f(a); // OK
f(b); // OK; slowest extent is forgotten in the decay
//f(c); // Error! 'c' is not an array of {array of N ints}.
对于第二种形式,含义相当不同:
void g(int **p);
int a;
int * pa = &a;
g(&pa); // fine, pointer to 'pa'
int arr[M][N];
// g(arr); // Error, makes no sense
表达式arr
指定指向N
整数数组数组的第一个元素的指针,即其类型为int (*)[N]
。取消引用它会得到一个N
整数数组,而不是指向整数的指针。
无法将表达式arr
转换为指向指针的指针:如果你说,
int ** fool = (int**)arr;
然后*fool
将指向第一个数组的第一个元素(arr[0]
),而指向int
指针。因此,您无法进一步取消引用该值,因为值不是指针。
将二维数组作为双指针传递的唯一正确方法是构造一个中间辅助数组:
int * helper[M]; // array of pointers
for (size_t i = 0; i != M; ++i)
{
helper[i] = arr[i]; // implicit decay
}
g(helper); // or "g(&helper[0])"