
数组名作为函数参数
在上一小节中,我们谈到函数参数的传递过程是实参到形参的单向传递,所以,在函数体中对形参数据的改变对于实参来说没有影响。但是,如果使用数组作为函数参数时,会发生一些小小的变化,实参向形参传递的是数组的起始地址。我们来看这样一个选择排序的例子:
【例6-7】选择排序
#include<iostream.h>
void select_sort(int array[],int n); //函数声明
int main(){
int a[10],i;
cout<<"enter the originlarray:"<<endl;
for(i=0;i<10;i++) //输入10个数
cin>>a[i];
select_sort(a,10); //函数调用,数组名作实参
cout<<"the sortedarray:"<<endl;
for(i=0;i<10;i++)
cout<<a[i]<<" "; //输出10个已排好序的数
cout<<endl;
return 0;
}
我们读入10个整数到数组a中,将a作为参数传递给select_sort函数,然后将数组a中的元素输出。select_sort函数实现的排序算法是选择排序法,所谓选择排序,就是先将10个数中最小的数与a[0]对换;再将a[1]到a[9]中最小的数与a[1]对换……每比较一轮,找出一个未经排序的数中最小的一个,一共比较9轮。
select_sort函数实现如下:
void select_sort(int array[],int n) //形参array是数组名
{
int i,j,k,t;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++)
if(array[j]<array[k])
k=j;
t=array[k];
array[k]=array[i];
array[i]=t;
}
}
程序运行结果:
enter the originl array:
6 9 -2 56 87 11 -54 3 0 77↙ //输入10个数
the sorted array:
-54 -2 0 3 6 9 11 56 77 87
我们看到,将数组a传递给select_sort函数之后,在select_sort函数array数组的值发生了变化,进而改变了数组a中元素的值,这是否与我们所说的“函数参数的传递过程是实参到形参的单向传递”相矛盾呢?不是的。
数组名代表数组首元素的地址,并不代表数组中的全部元素。因此用数组名作函数实参时,不是把实参数组的值传递给形参,而只是将实参数组首元素的地址传递给形参。
形参可以是数组名,也可以是指针变量,它们用来接收实参传来的地址。如果形参是数组名,它代表的是形参数组首元素的地址。在调用函数时,将实参数组首元素的地址传递给形参数组名。这样,实参数组和形参数组就共占同一段内存单元,如图6-1所示。
图6-1 实参数组和形参数组调用
在用变量作函数参数时,只能将实参变量的值传给形参变量,在调用函数过程中如果改变了形参的值,对实参没有影响,即实参的值不因形参的值改变而改变。而用数组名作函数实参时,改变形参数组元素的值将同时改变实参数组元素的值。在程序设计中往往有意识地利用这一特点改变实参数组元素的值。
实际上,声明形参数组并不意味着真正建立一个包含若干元素的数组,在调用函数时也不对它分配存储单元,只是用array[]这样的形式表示array是一维数组名,以接收实参传来的地址。因此array[]中方括号内的数值并无实际作用,编译系统对一维数组方括号内的内容不予处理。形参一维数组的声明中可以写元素个数,也可以不写。
函数首部的下面几种写法都合法,作用相同。
void select_sort(int array[10],int n) //指定元素个数与实参数组相同
void select_sort(int array[],int n) //不指定元素个数
void select_sort(int array[5],int n) //指定元素个数与实参数组不同