形参数组详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
可以用数组名作函数参数,此时实参与形参都应用数组名(或指针变量)。
例2:有一个一维数组score,内放10个学生成绩,求平均成绩。
float average(float array[10]){
int i;
float aver,sum=array[0];
for(i=1; i<10; i++)sum=sum+array[i];
aver=sum/10;
return aver;
}
main(){
float score[10],aver;
int i;
printf("input 10 scores:/n");
for(i=0; i<10; i++)scanf("%f",&score[i]);
printf("/n");
aver=average(score);//数组名作为函数参数
printf("average score is %5.2f",aver);
}
说明:
●用数组名称作函数参数,应该在主调函数和被调函数分别定义数组,本例中array是形
参数组名,score是实参数组名,分别在其所在的函数中定义,不能只在一方定义。
●实参数组与形参数组类型应该保持一致(这里都为float型),如不一致,结果将出错。
●在被调用函数中声明了形参数组的大小为10,但在实际上,指定其大小是不起任何作
用的,因为C编译器对形参数组大小不做检查,只是检查实参数组的首地址传给形参数组。因此,score[n]和array[n]指的是同一单元。
●形参数组也可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,有时为
了在被调用函数中处理数组元素的需要,可以另设一个参数,传递需要处理的数组元素的个数,上例可以改写为下面的形式:
float average(float array[], int n){
int i;
float aver,sum=array[0];
for(i=1; i aver=sum/n; return aver; } main(){ float score_1[5]={98.5,97,91.5,60,55}; float score_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99,5}; printf("the average of class A is %6.2f/n", average(score_1, 5)); printf("the average of class B is %6.2f/n", average(score_2, 10)); } 可以看出,两次调用average函数时,需要处理的数组元素是不同的,在第一次调用时用一个实参5传递给形参n,表示求前面5个学生的平均分数。第二次调用时,求10个学生平均分。 最后应该说明一点:用数组名作为函数实参的时,不是吧数组元素的值传递给形参,而是把实参数组的起始地址传递给形参数组,这样两个数组就共占同一段内存单元。见下图: 起始地址1000 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 2 4 6 8 10 12 14 16 18 20 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[ 8] b[9] 假如a的起始地址为1000,则b数组的起始地址也是1000,显然a和b同占一段内存单元,a[0]和b[0]同占一个内存单元……。由此,我们可以看到,形参数组中各个元素的值如果发生变化会使实参数组元素的值同时发生变化,从上图是很容易理解的。这一点与变量做函数参数的情况是不同的,务必注意!在程序设计中可以有意识地利用这一点,改变实参数组元素(如排序)。 最后,再给出一个例子:用选择排序法对数组中,10个整数按有小到大排序。所谓选择排序就是先将10个数中最小的数与a[0]对换;再将a[1]到a[9]中最小的数与a[1]对换……,每比较一轮,我们可以找出一个未经排序的数中最小的一个。共比较9论。 a[0] a[1] a[2] a[3] a[4] 3 6 1 9 4 1 6 3 9 4 1 3 6 9 4 1 3 4 9 6 1 3 4 6 9 我们可以看到在执行函数调用语句sort(a,10);之前和之后,a数组各元素的值是不一样的。原来是无序的,执行sort(a,10)之后是有序的。这也就是所谓的形参数组改变也可以使实参数组随之改变。 现在,我们已经知道了,当用数组名作函数参数时,如果形参数组中各元素的值发生了变化,实参数组元素的值也随之变化。那么这是为什么呢?如果你学过指针,这个问题就很容易来回答。 我们先看数组元素做实参时的情况。如果已经定义了一个函数,其原型为: Void swap(int x, int y); 假设函数的作用是将两个形参(x,y)的值进行交换,现在我们这样调用这个函数:Swap(a[1], a[2]); 用数组元素a[1], a[2]做实参的情况与变量做实参时一样,是“值传递”方式,我们将 a[1], a[2]的值单向传递给x,y。当x和y的值改变时a[1], a[2]的值并不改变。 我们现再看用数组名作函数参数的情况。前面已经介绍,实参数组名代表该数组首元素的地址。而形参是用来接收从实参传递过来的数组首元素的地址。因此形参应该是一个指针变量。实际上,C编译器都是将形参数组名作为指针变量来处理的。例如:我们定义一个被调函数f(int arr[], int n);,实际上,编译器是把arr按照指针变量来处理的,这相当于将函数f的首地址写成:f(int *arr,int n)。以上两种写法是等价的。 实际上,我们经常用这种方法调用一个函数来改变实参数组的值。 这里,给出一个表格,用于比较变量名作为函数参数和数组名作为函数参数。 实参类型变量名数组名 要求形参的类型变量名数组名或指针变量 传递的信息变量的值实参数组首元素的地址 不能能 通过函数调用能否改变实参的 值