C++两种二维数组定义下行交换代码编译差异问题咨询
本人使用CodeBlocks IDE,通过rand()填充二维数组。学习C++指针与二维数组时,编写了如下行交换代码:
int *temp=arr[0]; arr[0]=arr[1]; arr[1]=temp;
该代码在动态分配的二维数组(定义如下)下可正常编译:
int a=5; int b=3; int **arr=new int*[a]; for(int i=0;i<a;i++){ *(arr+i)=new int[b]; for(int j=0;j<b;j++){ *(*(arr+i)+j)=rand()%(125-15+1)+15; cout<<*(*(arr+i)+j)<<" "; } cout<<endl; }
但在如下变长数组定义下编译报错:
int a=5; int b=3; int arr[a][b];
错误信息:invalid array assignment|incompatible types in assignment of 'int*' to 'int [b]'。想了解两种数组定义是否等价,为何出现该差异?
两种数组定义完全不等价,差异源于它们在内存中的存储结构和类型本质:
动态分配的
int** arr本质是指针数组
这段代码里,arr是指向指针的指针,它指向一块包含a个int*类型元素的内存。每个arr[i]都是独立分配的int[b]数组的首地址(即int*类型)。
交换代码里的arr[0]和arr[1]本质是两个指针变量的赋值,int*类型之间的赋值是C++允许的,因此代码能正常编译。变长数组
int arr[a][b]本质是连续存储的二维数组
首先说明:变长数组(VLA)是C99的标准特性,C官方标准并未包含,CodeBlocks能编译是因为GCC编译器提供了扩展支持。
这种二维数组在内存中是一块连续的空间,arr的类型是int[a][b],arr[0]的类型是int[b](长度为b的int数组类型)。
C中数组类型不能直接赋值(数组是不可修改的左值,无法作为赋值操作的目标),同时int*和int[b]是完全不同的类型,所以编译器会报类型不兼容的错误。如果要交换变长数组的行,需要逐个元素交换,或者用
memcpy批量复制:// 逐个元素交换示例 int temp; for(int j=0;j<b;j++){ temp = arr[0][j]; arr[0][j] = arr[1][j]; arr[1][j] = temp; }
内容的提问来源于stack exchange,提问作者plamen

