我有一个函数,有时使用常规的,有时是动态的数组调用。
如果我将函数定义为
function_name(int[10][10] a)
并发送int **作为参数,我收到警告。相反,如果我宣布
function_name(int** a)
并发送int [] []作为参数(在转换后)我无法访问函数内的数组元素。
最正确的方法是什么?
答案 0 :(得分:1)
int **
和int [][]
不一样。
前者是pointer to pointer to int
,而第二个是int
的二维数组。
int[][]
decays to int (*)[]
when you pass it as argument to function.
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;
}
答案 1 :(得分:1)
当一个数组传递给一个函数时,它“衰减”到指向它的第一个元素的指针。所以,给定:
T a[10];
f(a);
在通话f(a)
中,a
实际上是&a[0]
,即指针,类型为T *
(&a[0]
的类型)。
如果有数组数组,则应用相同的规则:
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_name(int (*a)[10]);
有关详情,请参阅this。
function_name(int[10][10] a)
中存在语法错误 - 您需要在“变量”名称后指定数组大小:function_name(int a[10][10])
。事实上,由于上面提到的“腐朽”,上述内容相当于function_name(int (*a)[10])
。
编辑:啊,我想我现在明白了。由于上面提到的原因,你不能声明一个同时采用“二维”数组和指向指针的函数(指针的“衰减”只发生一次)。指向指针的指针可能不指向连续数据,并且可能在每个“行”中具有不同数量的元素。数组数组不能具有这些属性。它们根本不同。