(gcc)用于无警告编译的多点arrays或双指针

我有一个函数,有时会调用常规的,有时是动态的数组。

如果我将函数定义为

function_name(int[10][10] a) 

并发送int **作为参数,我得到一个警告。 相反,如果我宣布

 function_name(int** a) 

并发送int [] []作为参数(在转换后)我无法访问函数内部的数组元素。

最正确的方法是什么?

当一个数组传递给一个函数时,它“衰减”到指向它的第一个元素的指针。 所以,给出:

 T a[10]; f(a); 

在调用f(a)a实际上是&a[0] ,即指针,类型是T *&a[0]的类型)。

如果有arrays数组,则适用相同的规则:

 T a[10][5]; f(a); 

a再次衰减指针,等于&a[0]a[0]的类型为“ T [的数组[5]”。 因此, &a[0]的类型为“指向T数组[5]的指针”,即,如果要声明指针p设置为等于&a[0] ,则可以执行以下操作:

 T (*p)[5]; /* parentheses because [] binds tighter than * */ p = &a[0]; 

鉴于上述情况,并假设您的数组在调用代码中声明为int a[10][10]; ,你应该将你的function声明为:

 function_name(int (*a)[10]); 

有关更多信息,请参阅此

function_name(int[10][10] a)存在语法错误function_name(int[10][10] a) – 您需要在“变量”名称后面指定数组大小: function_name(int a[10][10]) 。 实际上,由于上​​面提到的“衰变”,上面等同于function_name(int (*a)[10])

编辑 :啊,我想我现在明白了。 由于上面提到的原因,你不能声明一个同时带有“二维”数组和指向指针的函数(指针的“衰减”只发生一次)。 指向指针的指针可能不指向连续数据,并且可能在每个“行”中具有不同数量的元素。 数组数组不能具有这些属性。 它们根本不同。

int **int [][]不一样。 前者是pointer to pointer to int而第二个是pointer to pointer to int 2-d数组。

当你将它作为参数传递给函数时, int[][]衰减为int (*)[]

 void func(int arr[][10]) { //decays to `int (*arr)[10]` printf("%d correct", arr[1][9]); //10th element of 2nd row //printf("%d correct", (*(arr + 1))[9]); //same as above } int main() { int (*arr)[10]; //pointer to array of ints arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast. arr[1][9] = 19; func(arr); return 0; }