我正在尝试将二维数组传递给函数。我尝试了互联网上提供的不同解决方案。
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. 案例中有什么错误。
我正在尝试将二维数组传递给函数。我尝试了互联网上提供的不同解决方案。
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. 案例中有什么错误。
好吧,这就是永远有用的cdecl所说的:
int *a[4]表示“将 a 声明为指向 int 的指针的数组 4”int(*a)[4]表示“将 a 声明为指向 int 数组 4 的指针”这声明了一个包含 4 个指向整数的指针的数组:
int* a[4]; // (a)
另一方面,这:
int (*a)[4]; // (b)
声明一个指向 4 个整数数组的指针。
由于数组在用作函数参数时衰减为指针(指向它们的第一个元素),因此将类型对象传递int arr[3][4]给接受上述类型(b)参数的函数将成功(衰减为指向 的指针int[4],即 an int (*)[4]),而它将当参数类型为(a)时失败。
除非它是、 或 一元运算符的操作数sizeof,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of ”类型的表达式将转换为“pointer”类型的表达式到",表达式的值将是数组中第一个元素的地址。_Alignof&TT
在函数调用中
fun(arr);
表达式 的类型arr是“4 元素数组的 3 元素数组int”。由于arr不是sizeof, _Alignof, 或一元运算符的操作数&,它将被转换为“指向 4 元素数组的指针”类型的表达式,int写为int (*arr)[4],其值将是 的地址a[0]。
后缀运算符 like[]和()比一元运算符 like 具有更高的优先级*,因此*a[N]是N-element 指针数组,而(*a)[N]是指向-element 数组的指针N。同样,*f()是一个函数返回一个指针,(*f)()而是一个指向函数的指针。
int* a[4]是一个 4 int*s的数组int (*a)[4]int是一个指向 4 s数组的指针数组的名称可以转换为指向其第一个元素的指针。也就是说arr,由于它是 an 的名称int[3][4],将转换为指向其第一个元素的指针,该元素arr本身就是 an int[4]。该类型是int(*)[4]. 这就是为什么你可以arr在第二种情况下通过。
在 C++ 中,您可以像这样传递对完整数组的引用:
void fun(int(&a)[3][4]) {}
在这种情况下,不会发生数组到指针的转换。您只是在引用 2D 数组本身。
int *a[4]是一个由 4 个指针组成的数组int,而int(*a)[4]是一个指向 4 个数组的指针int。
由于数组衰减为指向其第一个元素的指针(只要它不用作&,sizeof或的操作数_Alignof),a[3][4]将被转换为(*a)[4].