C/C++中数组传参问题
在C/C++的函数参数传递过程中,数组传参时会有较多的注意事项,以下代码是一个在函数中返回数组长度的常规错误代码。
int nu(int a1[][5]){
return sizeof(a1);
}
int main(){
int a[100][5];
cout << sizeof(a) <<endl << nu(a);
}
代码执行结果
该函数的目的是返回数组的长度,但是在参数传递时没有考虑到形参中的数组已经退化为普通指针,因此最后的输出结果为:
a的长度:1005sizeof(int)
nu(a)的返回值:sizeof(int*)
原因分析:
为什么在数组参数传递时需要将形参中的数组退化为指针呢?
我个人的理解是:
数组名是数组首元素的的指针,同时也是一个指针常量;如果形参作为指针常量而不退化,形参将无法接受实参中的数值传递。若是如此,编译器则会将此类传参视为非法语法而无法成功编译,因此采取了数组退化的方式。
此外,为什么退化后还需要对二维指针进行容量传递才合法呢(不能是 int a[][]),因为在函数中使用符号[ ]对数组进行访问时,编译器需要知道数组的大小才能确定访问时的具体函数偏移。(C/C++中二维数组是连续地址排列,JAVA则不是)
解决方案:
作为常规的函数数组参数传递,一般需要同时传递指针和长度(一般还会用const防止利用形参指针修改数组),或者直接传递数组的引用。 但是要注意引用传递时参数的维度必须完全一致。
int nu(const int a1[][5],int num){
cout << num;
}
int main(){
int a[100][5];
cout << sizeof(a) <<endl;
nu(a, sizeof(a));
}
或者
int nu(const int (&a1)[100][5]){//形参实参一致int[100][5]
return sizeof(a1);
}
int main(){
int a[100][5]; //形参实参一致int[100][5]
cout << sizeof(a) <<endl << nu(a);
}
以上所有代码仅作为事件举例,不具备规范性!