首先二维数组有如下两种定义方式:
A.
int Arr[2][3]={{1,2,3},{4,5,6}};
B.
int **Arr=new int* [2];
for(int i=0;i<2;i++)
Arr[i]=new int[3];
//initialize
for(int i=0;i<2;i++)
for(int j=0;j<3;j++)
Arr[i][j]=i*3+j+1;
但是两种方式有一个重要的区别:方式A声明的二维数组是按行连续存储的,而方式B的每行之间一般并非连续存储!
例如:虽然两种方式都可以通过 Arr[i][j] 或 *(*(Arr+i)+j) 访问元素,但是方式A可以通过如下的类似一维数组的访问方式访问元素
*(Arr[0]+i*cols+j)
而这种访问方法对于方式B是不正确的。
利用方式A二维数组按行连续存储这种性质,可以将二维数组转为一维指针作为函数参数,且具有良好的扩展性:
1.如已知有一按方式A定义的二维数组Arr,具有rows行,cols列,那么欲将其作为函数Func的参数可以如下声明
void Func(int *A,int rows,int cols){
for(int i=0;i
也许我们还会想不用一维指针而是利用二维指针作为函数参数,如
void Func(int **A,int rows,int cols);
那么在引用时即 Func(Arr,2,3); 会报错提示“int (*)[3] 类型的实参与 int ** 类型的形参不兼容”即参数类型不匹配。所以,用方式A定义的二维数组只能按如上方式转为一维指针作函数参数。 而利用二维指针作函数参数这种方法适用的是方式B。
2.由于方式B定义的二维数组非按行连续存储,所以作函数参数的只能是二维指针,即如下声明
void Func(int **A,int rows,int cols){
for(int i=0;i
综上,想将二维数组作为函数参数,首先要明确二维数组是按那种方式定义的(A or B),然后再采用相应的函数声明方式。两种函数声明方式针对不同行列数都具有良好的扩展性。以上虽然是以二维数组为基础作讨论,但是原理可相通的
推广到三维及以上的多维数组,处理方式都是一样的。