7.4 函数与数组

    前面已经讨论过数组和指针的关系,知道数组名实际上是指向数组所占内存单元的常指针,由此可知,同指针一样,数组既可以作为函数的参数,也可以作为函数的返回值。

    7.4.1 数组名作为函数参数

    数组名用作函数参数时,用以向程序传递数组所占内存单元的首地址,数组名参数与指针参数的用法几乎一致。有数组参数的函数原型的一般形式如下所示。


    返回类型函数名(数组名[],其他参数)

    习惯上在参数列表中要指明数组元素的个数,在本章前面已经说明,在函数内部使用sizeof(数组名)返回的只是指针大小,而不是数组大小,因此,在参数列表中显式注明数组元素的个数是个好的编程习惯,当然,如果能保证不会出现越界访问的情况,这个参数可以省略。理论上,“数组名[]”中[]是空的,没有数字,如果在其中写明元素大小,编译器也不予理会,不会进行错误检验。

    代码7.13 演示了如何使用数组名作为函数参数。

    代码7.13 数组名作为函数参数CallByArray


    <————————————文件名:example713.cpp———————————————> 01 #include<iostream> 02 using namespace std; 03 int search(int v[],int n,int val)//search函数定义,数组v作为参数 04 { 05 int i; 06 for(i=0;i<n;i++) 07 if(val==v[i]) 08 return(i+1); 09 return-1; 10 } 11 int main() 12 { 13 int sz[6]={1,6,3,5,4,2};//创建了数组sz,大小为6 14 int*pInt=sz;//数组名等价于指针,为int型指针pInt赋值 15 int num;//声明int型变量num 16 cout<<"请输入你要检索的数字(1~6):"<<endl; 17 cin>>num; 18 int res=search(sz,sizeof(sz)/sizeof(int),num);//在数组sz中查num的索引号,传递数组 19 //名常指针 20 cout<<num<<"是数组中的第"<<res<<"个元素"<<endl; 21 cout<<"请输入另一个你要检索的数字(1~6):"<<endl; 22 cin>>num; 23 res=search(pInt,sizeof(sz)/sizeof(int),num);//传递指针变量与传递数组名常指针等价 24 cout<<num<<"是数组中的第"<<res<<"个元素"<<endl; 25 return 0; 26 }

    输出结果如下所示。


    请输入你要检索的数字(1~6): 2(注:键盘输入) 2是数组中的第6个元素 请输入另一个你要检索的数字(1~6): 5(注:键盘输入) 5是数组中的第4个元素

    【代码解析】代码第3行,search函数参数列表中,“int v[]”说明v是int型数组,在main()函数中可以用数组名sz做实参,也可用int型指针pInt做实参,再次验证了数组名和指针的等价性。

    用指针形式向函数传送参数还有一个优点,那就是调用参数不一定是数组的起始地址,还可以使用指向数组中某元素的指针,换言之,允许将数组的一部分传递给函数,如代码7.13中,可以将main()函数写为如下形式。


    int main() { int sz[6]={1,6,3,5,4,2}; int*pInt=&sz[2]; int num; cout<<"请输入你要检索的数字(1~6):"<<endl; cin>>num; int res=search(pInt,sizeof(sz)/sizeof(int)-2,num); cout<<num<<"是数组中的第"<<res<<"个元素"<<endl; return 0; }代码7.13中其他部分不变,编译运行后,

    输出结果如下所示。


    请输入你要检索的数字(1~6): 5(注:键盘输入) 5是数组中的第2个元素或者 请输入你要检索的数字(1~6): 6(注:键盘输入) 6是数组中的第-1个元素

    将sz数组中第3个元素(sz[2])的地址作为参数传递给函数search后,函数search只检索从sz[2]开始的部分,当然,要指定子数组的大小为“sizeof(sz)/sizeof(int)-2”,看出原来数组中第4个元素5在输入的子数组中排在第2个,而原来第2个元素6不在输入的子数组中,所以程序返回-1。

    注意

    以数组作为函数参数,通过指针进行通信,是上级调用函数向被调函数传送大量数据的一种方法。深入理解数组名和指针的等价性,有助于写出高质量的代码。

    多维数组也可作为函数参数,第一维的大小可以省略,其他维的大小不能省略,如代码7.14所示。

    代码7.14 多维数组作为函数参数CallByMultiDArray


    <————————————文件名:example714.cpp———————————————> 01 #include<iostream> 02 using namespace std; 03 int add(int x[][3][4],int n)//多维数组x作为形参 04 { 05 int res=0; 06 for(int i=0;i<n;i++) 07 for(int j=0;j<3;j++) 08 for(int k=0;k<4;k++) 09 res+=x[i][j][k]; 10 return res; 11 } 12 int main() 13 { 14 //创建多维数组sz,并初始化,作为add函数调用的实参 15 int sz[2][3][4]={{{1,2,3,4},{5,6,7,8},{9,10,11,12}}, 16 {{1,2,3,4},{5,6,7,8},{9,10,11,12}}}; 17 int res=add(sz,sizeof(sz)/sizeof(int[3][4])); 18 cout<<"加和:"<<res<<endl; 19 return 0; 20 }

    输出结果如下所示。


    加和:156

    【代码解析】代码第3行,在add函数定义时,形参3维数组x必须指明后面二维的大小,否则,编译器会报错。程序使用语句“sizeof(sz)/sizeof(int[3][4])”来计算数组sz第一维大小。