为编写将二维数组作为参数的函数,必须牢记,数组名被视为地址,因此相应的形参是一个指针,比较难处理的是如何正确声明指针。
在被调用函数中对形参数组定义时可以可以指定所有维数的大小,也可以省略第一维的大小说明。如:
void Func(int array[3][10]);
void Func(int array[][10]);
二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:
void Func(int array[][]);
将二维数组当作参数的时候,必须指明所有维数大小或者省略第一维的,但是不能省略第二维或者更高维的大小,这是由编译器原理限制的。编译器是这样处理数组的:对于数组 int p[m][n];
如果要取p[i][j]的值(i>=0 && i< m && 0<=j && j < n),编译器是这样寻址的,它的地址为: p + i*n + j;
从以上可以看出,如果我们省略了第二维或者更高维的大小,编译器将不知道如何正确的寻址。
下面我们提供三种方式对二维数组进行传参:
一、在声明的时候,给入第二维维数大小
void printArray(int (*arr)[9], int w, int h) {
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
二、在声明的时候,用一维指针去指向二维数组, 模拟编译器寻址
由一知道,如果要把这个数组进行封装,是不适用的,因为你直接函数中
写死了二维数组的第二维维数大小
void printArray2(int * arr, int w, int h) {
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
cout << arr[i*w+j] << " ";
}
cout << endl;
}
}
三、建立一个指针数组,进行指向原二维数组,同时在函数中传入二维指针
void printArray3(int ** arr, int w, int h) {
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
测试:
int main(void) {
int arr[][9] = { { 0,0,0,0,0,0,0,0,0 },
{ 0,1,1,0,1,1,1,1,0 },
{ 0,1,1,1,1,0,0,1,0 },
{ 0,1,1,0,1,0,0,0,0 },
{ 0,0,0,0,1,1,1,0,0 },
{ 0,0,0,0,1,1,1,0,0 },
{ 0,0,0,0,0,0,0,0,0 } };
cout << "=============== method 1 ===============" << endl;
printArray(arr, 9 ,7);
cout << "=============== method 2 ===============" << endl;
printArray2(*arr, 9, 7);
cout << "=============== method 3 ===============" << endl;
int *p[7]; // define array of pointers (指针数组)
for (int i = 0; i < 7; i++)
p[i] = arr[i];
printArray3(p, 9, 7);
system("pause");
return 0;
}