Preface
因为只是用C++写写算法水题,代码行数鲜有破百的。
很多时候函数之间需要使用到某一个数组时,都偷懒写成全局了。一是因为代码量少,尚还不足以引起混乱,二则是因为有的时候题目测试数据比较大,数组也就开得比较大,可能会导致爆栈(new 是懒得new了)。参考我的C++内存分配管理。
本文对C++中数组参数的传递做一个记录。
一维数组
一维数组比较方便。有数组和指针两种方式,且数组不需要指定大小。
这里就用一段测试代码展示下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<iostream> using namespace std;
void test(int *a,int b[]){ cout<< a[2] <<endl; cout<< *a <<endl; cout<< *a + 2 <<endl; cout<<"==========="<<endl; cout<<b<<endl; cout<<b[1]<<endl; cout<<*b<<endl; cout<<*b + 2<<endl; cout<<*(b + 2)<<endl; }
int main(){ int a[] = {1,2,3,4}; int b[] = {9,8,7,6}; test(a,b); return 0; }
|
输出
1 2 3 4 5 6 7 8 9
| 3 1 3 =========== 0x24fe30 8 9 11 7
|
在大多数情况下,C++和C一样,也将数组名视为指针。C++将数组名解释为其第一个元素的地址
cookies == &cookies[0]
当然也不总是这样的。具体可以看《C++Primer Plus》。最近比较忙,就不展开了。
二维数组
同样也是数组和指针两种方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include<iostream> using namespace std;
void test(int **a,int b[][2]){ cout<<*((int*)a + 3*1 + 1)<<endl; cout<<*((int*)a + 3*1)<<endl; cout<<*((int*)a)<<endl; cout<<"==========="<<endl; cout<<b[0][0]<<endl; cout<<b[0]<<endl; cout<<*b<<endl; cout<<*(b+1)<<endl; }
int main(){ int a[3][3]; int b[2][2] = {{1,2},{3,4}}; for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ cin >> a[i][j]; } } test((int**)a,b); return 0; }
|
输入
输出
1 2 3 4 5 6 7 8
| 5 4 1 =========== 1 0x24fe30 0x24fe30 0x24fe38
|
将二维数组当作参数的时候,必须指明所有维数大小或者省略第一维的,但是不能省略第二维或者更高维的大小。
也就是在上面的代码中,test(int **a,int b[2][2])
也是可以的。
这是由编译器原理限制的
对于数组 int b[m][n]; 如果要取b[i][j]的值(i>=0 && i<m && 0<=j && j < n),编译器是这样寻址的,它的地址为:b + i*n + j
;
从以上可以看出,如果我们省略了第二维或者更高维的大小,编译器将不知道如何正确的寻址。
而在使用指针时,需要按照如下的方式进行调用
*((int*)b + n*i + j);
参考
C++: 二维数组作函数参数
C/C++如何传递二维数组?
C++,二维数组与指针,二维数组名是不是首地址?