9.5.4 数组名作为函数的参数(1)
在前面章节介绍函数时,曾介绍过用数组名作函数的实参和形参的情况。在学习指针变量之后,可以从指针角度对这种参数的传递进行理解。
数组名就是数组的首地址,当实参向形参传送数组名时,实际上就是传送数组的地址,形参得到该地址后就与主调函数中的实参指向同一数组。这样,在被调函数中对数组元素的值进行修改返回主调函数后,通过实参同样可以访问到。这就解决了C函数只能使用return语句返回一个值的问题。当函数需要返回多个值给主调函数时,可使用数组作为函数的形参。
同样,指针变量的值也是地址。在调用形参为数组的函数时,也可将指针作为实参传递给函数。
1.一维数组作参数
当向函数传递一维数组作实参时,只需要将数组名填入函数的形参部分即可。例如,编写一个函数,用于向屏幕中显示一个字符串。
【程序9-15】
- #include <stdio.h> //头文件
- #include <stdlib.h>
- int main()
- {
- void puts1(char s[]);
- char s1[]="Hello,C Programer!";
- puts1(s1); //输出字符串
- putchar('\n'); //输出换行符
- system("pause");
- return 0;
- }
- void puts1(char *s) //自定义函数
- {
- for(i=0;s[i]!='\0';i++)
- putchar(*s++);
- }
编译执行这段程序,得到如下结果,如图9-30所示。
图9-30 执行结果 |
在该程序中,编写自定义函数puts1(),用来输出一个字符串。在puts1()函数的定义部分,定义了该函数的形参为一个一维数组,该一维数组中保存着一个字符串。在函数中使用putchar()库函数逐个输出数组中的字符,直到字符串结束为止。字符串的最后一个字符为'\0',所以第14行的循环以s[i]!='\0'作为条件。
在main()函数中,调用puts()函数,将字符数组名s1作为实参传给函数,参数的传递过程相当于一个赋值语句
- s=s1;
即将main()函数中的数组名s1(数组的首地址)传给形参中的数组名s。前面介绍过,数组名是一个指针常量,不允许修改其值。在C语言中,当函数的形参设置为数组时,C编译器会将其转换为指针。例如,本例中函数puts1()的函数头中将形参定义为数组s,实质是函数头与以下形式等价:
- void puts1(char *s)
为了检验这种情况,可将函数puts1()代码改写为以下形式:
- void puts1(char s[])
- {
- for(;*s!='\0';)
- putchar(*s++);
- }
在函数头部分,形参仍然采用数组形式,但在函数体的代码中,即可以使用s++来修改数组首地址,逐个输出其值。如果数组s不是函数的形参,而是函数内部定义的数组,则不允许使用这种方式。
其实,在C语言程序设计中,程序员更喜欢用指针方式编写这类程序。例如,将puts1()函数改写为以下形式,应该更易读易懂。
- void puts1(char *s)
- {
- while(*s!='\0')
- putchar(*s++);
- }
而表达式*s!= '\0'更可以精简为*s,因为当*s的值为'\0'时,表达式的值也就为0,循环结束;当*s的值不为0时,循环继续执行。在C语言中,类似这样的比较运算都可简写,省去关系表达式运算的环节,可提高程序的效率,同时使程序更简洁。修改后的程序如下:
- void puts1(char *s)
- {
- while(*s) putchar(*s++);
- }
修改后的函数与程序9-15中函数完成相同的功能,main()函数不需要进行任何修改,即可得到同样的结果。
2.二维数组作参数
一维数组作为参数时比较简单,上面的例子演示了其使用方法。在使用一维数组作为参数时,也可使用指针的方式访问数组中的数据。
也可根据需要向函数传递二维数组作为实参,有两种方法:一是使用指向数组元素的指针变量,其本质就是将二维数组作为一维数组来使用;二是使用指向一维(行)数组的指针变量。
下面的程序演示使用指向一维数组的指针变量传递参数的形式。该程序让用户输入一个矩阵,然后计算矩阵对角线数据之和。
【程序9-16】
- #include <stdio.h> //头文件
- #include <stdlib.h>
- #define M 4
- void read(int a[][M],int n);
- int sum(int a[][M],int n);
- int main()
- {
- int a[M][M];
- read(a,M);
- printf("矩阵对角线元素之和为:%d\n",sum(a,M));
- system("pause");
- return 0;
- }
- void read(int a[][M],int n)
- {
- int i,j;
- for(i=0;i<n;i++)
- {
- printf("请输入矩阵第%d行的%d个数据:",i+1,n);
- for(j=0;j<n;j++)
- scanf("%d",&a[i][j]);
- }
- }
- int sum(int a[][M],int n)
- {
- int i,s=0;
- for(i=0;i<n;i++)
- s+=a[i][i];
- return s;
- }