数组的存储空间很大,如果能够把它作为参数传递给函数,那么就能发挥很大的作用了。比如本来一个选出最大数的max函数只能在两个数或三个数里面选出一个最大的数字,如果我们把数组传递过去,它就能够在一堆数字中选出最大的数了,这大大提高了程序的效率。当函数中的某个参数是数组时,在参数名后加上一对中括号,比如int a[],表示参数a是一个数组。下面我们就来看这样一个在一堆正数里面找一个最大数的程序:(程序7.3.1)
#include "iostream.h"
int max(int a[],int size);//size是数组的大小
int main()
{
int number[]={2,45,12,6,23,98,13,3};
cout <<max(number,sizeof(number)/sizeof(int)) <<endl;
return 0;
}
int max(int a[],int size)
{
int max=0;
for (int i=0;i<size;i++)
{
if (a[i]>max)
max=a[i];
}
return max;
}
运行结果:98
我们发现,在函数里使用数组也是比较方便的。但大家有没有考虑过一个问题,我们为什么不在函数里面用sizeof算出数组的大小,而非要在函数外面算好了,再作为参数传递给函数呢?在这里,我们就有必要讲一下数组作为参数传递给函数的原理了。
我们以前说过,参数的传递是将实参的值赋给形参。然而对于数组来说却是一个例外,因为数组的数据太多了,将其一一赋值既麻烦又浪费空间,所以数组作为参数传递给函数的只是数组首元素的地址,函数在需要用到后面元素时再按照这个地址和数组下标去查找。也就是说后面的元素根本没到函数里来,所以在函数里求不出数组的大小也就不足为奇了。
所以,当一个函数的参数是一个数组时,我们必须注意要想办法让这个函数知道数组的大小。
不过,既然数组传递给函数的是数组首元素在内存中地址,而数据又都是存在内存里的,那么在函数中对数组参数的修改会不会影响到实参本身的值呢?让我们来看一段程序,验证一下我们的想法:(程序7.3.2)
#include "iostream.h"
#include "iomanip.h"
void sort(int a[],int size);//将数组中的元素从大到小排列
int main()
{
int num[]={2,3,8,6,4,1,7,9};
const int size=sizeof(num)/sizeof(int);
sort(num,size);
cout <<"排列后的数组元素" <<endl;
for (int i=0;i<size;i++)//输出排列好以后的数组元素
{
cout <<setw(2) <<num[i];
}
cout <<endl;
return 0;
}
void sort(int a[],int size)
{
cout <<"原来的数组元素" <<endl;
for (int i=0;i<size;i++)//输出原来的数组元素
{
cout <<setw(2) <<a[i];
}
cout <<endl;
for (int j=0;j<size;j++)
{
int min=a[j],mink=j;//先假设未排序的首元素是最小的数
for (int k=j;k<size;k++)//找到尚未排序的元素中最小的数
{
if (a[k]<min)
{
min=a[k];
mink=k;
}
}
int temp=a[j];//交换两个元素
a[j]=a[mink];
a[mink]=temp;
}
}
运行结果:
原来的数组元素
2 3 8 6 4 1 7 9
排列后的数组元素
1 2 3 4 6 7 8 9
算法时间:排序(Sort)
排序是经常要使用到的一项功能。排序的算法也有多种。程序7.3.2所使用的排序方法称为直接选择排序,即在未排序的元素中选择出最小的一个,与未排序的首元素交换,直到所有的元素都已经排序。(如右上表所示)以后大家还会在数据结构课程中学习到一些更高效的排序算法,如快速排序法,插入排序法等等。
我们交换了sort函数中参数数组a的顺序,却发现回到主函数以后,num数组的元素次序也发生了变化。正是因为我们在函数中将内存中的数据作了操作,所以影响到了实参。