将数组作为参数传递

时间:2011-03-18 18:13:42

标签: c++

我在一本书中读到,int f (int P[2][4])无法接受A[2][3],但B[3][4]没问题。这是什么原因? 特别是当我们使用指针创建动态分配时,这应该不是问题。 谢谢

6 个答案:

答案 0 :(得分:5)

原因是     int f(int P [2] [4]); 是...的同义词     int f(int(* P)[4]); 函数声明中的第一个维度就是注释。

答案 1 :(得分:4)

原因是函数参数从未真正具有数组类型。编译器处理声明

int f(int P[2][4]);
好像它真的说了

int f(int (*P)[4]);

P是指向四个int的数组的指针。类型int [3][4]衰减到相同类型。但类型int [2][3]会衰减为int (*)[3]类型,而不兼容。

动态分配完全是另一回事,无论你怎么做,它都可能涉及数组数组类型。 (指针数组,更有可能。)

答案 2 :(得分:1)

不允许这样做的原因,因为f(int P[2][4])变为f(int (*P)[4]),因此您可以将int B[3][4]传递给int (*B)[4],但int A[2][3] 不能衰减到int (*A)[4],因此后者不会被f(int (*P)[4])接受。

int (*)[3]类型与int (*)[4]不兼容。一个人无法转换为另一个!

然而,有一个解决方案。你可以这样做:

 template<size_t M, size_t N>
 int f(int (&P)[M][N])
 {
      //Use M and N as dimensions of the 2D array!
 }

 //Usage
 int A[2][3];
 f(A); //M becomes 2, N becomes 3

 int  B[3][4];
 f(B); //M becomes 3, N becomes 4

它将接受所有二维数组!

答案 3 :(得分:1)

在C和C ++中,如果指定一个函数需要二维数组,那么必须给它一个明确的列大小(第二个[])。行大小(第一个[])是可选的。

答案 4 :(得分:1)

它与内存布局有关系。第一个数字基本上是您的行数,第二个数字是每行中有多少个元素。行直接放在一起。因此,偏移量由行中元素的数量乘以前面的行数确定。编译的函数将基于4个元素计算行偏移。当您传递具有另一行长度的数组时,这些计算将是错误的。

答案 5 :(得分:0)

第二个参数定义了2d数组类型,因为它与每列中的元素数量有所不同。

第一个参数只定义数组的大小,因为你可以向该函数发送更长的数组,就像传递参数类型:int * [3]类似于将大小为10的1d数组传递给函数期望得到更小尺寸的数组 - 这在c ++中是合法的。