我正在尝试将2D数组传递给函数。我尝试在互联网上提供不同的解决方案。
int arr[3][4];
fun (arr);
1) void fun(int *a[4]) {} -- result into a compilation error (cannot convert int (*)[4] to int **)
2) void fun(int(*a)[4]) {} -- works fine.
我想知道上述两个声明之间的区别是什么,以及1. case中的错误。
答案 0 :(得分:5)
嗯,这是有用的cdecl说的:
int *a[4]
表示“声明指向int的指针数组4”int(*a)[4]
表示“声明指向int”数组4的指针答案 1 :(得分:1)
这声明了一个指向整数的4个指针的数组:
int* a[4]; // (a)
另一方面,这是:
int (*a)[4]; // (b)
声明一个指向4个整数数组的指针。
由于数组在用作函数参数时会衰减为指针(指向第一个元素),因此将类型为int arr[3][4]
的对象传递给接受上述类型(b)的参数的函数将成功(衰减到指向int[4]
的指针,即int (*)[4])
,而当参数类型为(a)时它将失败。
答案 2 :(得分:0)
int* a[4]
是一个包含4 int*
s int (*a)[4]
是指向4 int
s 可以将数组的名称转换为指向其第一个元素的指针。那是arr
,因为它是int[3][4]
的名称,将被转换为指向arr
的第一个元素的指针,int[4]
本身就是int(*)[4]
。该类型是arr
。这就是为什么你可以在第二种情况下通过void fun(int(&a)[3][4]) {}
。
在C ++中,您可以像这样传递对完整数组的引用:
{{1}}
在这种情况下,不会发生数组到指针的转换。您只是引用2D数组本身。
答案 3 :(得分:0)
int *a[4]
是一个包含4个指向int
的数组,而int(*a)[4]
是指向4 int
数组的指针。
由于数组衰减到指向其第一个元素的指针(只要它不用作&
,sizeof
或_Alignof
)的操作数,a[3][4]
将被转换为(*a)[4]
。
答案 4 :(得分:0)
除非它是sizeof
,_Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,类型为“{-1}}的N元素数组”的表达式将转换为“指向T
的指针”类型的表达式,表达式的值将是数组中的第一个元素。
在函数调用中
T
表达式的类型 fun(arr);
是“arr
的4元素数组的3元素数组”。由于int
不是arr
,sizeof
或一元_Alignof
运算符的操作数,因此它将转换为“指向4元素数组的指针”的表达式&
“,写为int
,其值为int (*arr)[4]
的地址。
a[0]
和[]
等后缀运算符的优先级高于()
等一元运算符,因此*
是一个*a[N]
- 元素指针数组,而N
是指向(*a)[N]
- 元素数组的指针。类似地,N
是返回指针的函数,而*f()
是指向函数的指针。