1、C程序设计程序设计Programming in C函数之间实现批量数据传递函数之间实现批量数据传递1、用数组作为函数参数2、数组参数的传递机制C程序设计程序设计36.3 数组与函数数组与函数可以将数组对象作为函数的参数,但与变量作为函数的参数有明显的区别。46.3.1 数组作为函数的参数数组作为函数的参数一维数组元素可以直接作为函数实参使用,其用法与变量相同。假设有函数:那么:int max(int a,int b);int A5=1,2,3,4,5 , c=2, x;x=max(c,-10); /使用变量作为函数实参x=max(A2,-10); /使用数组元素作为函数实参56.3.1 数组作
2、为函数的参数数组作为函数的参数C语言不允许数组类型作为函数类型,但可以作为函数的形参,称为形参数组。形参数组可以是一维数组,也可以是多维数组,基本形式为:返回类型函数名(类型数组名常量表达式,.)函数体66.3.1 数组作为函数的参数数组作为函数的参数示例double average(double A100,int n). /函数体76.3.1 数组作为函数的参数数组作为函数的参数函数形参如果是数组类型时,则调用实参就不能是元素,而必须是数组对象(数组名)。因为此时的形参是一个数据集合,所以实参也应该是一个数据集合,C语言不会将基本类型隐式转换为构造类型,反之亦不成立。86.3.1 数组作为函
3、数的参数数组作为函数的参数例如有函数原型:则函数调用:double average(double A100,int n);double x, y, A100, B2100;int P100;x=average(y,100); /错误,double不能对应double数组x=average(A10,100); /错误,double元素不能对应double数组x=average(P,100); /错误,int数组不能对应double数组x=average(A,100); /正确,double数组对应double数组x=average(B1,100); /正确,double数组对应double数组9
4、6.3.2 数组参数的传递机制数组参数的传递机制前面讲过变量作为函数参数的传递机制是值传递,那么数组参数是否也是这样呢?例如:void fun(int A10,int n);int main()int a10=1,2,3,4,5 , x=5;fun(a,x); /实参分别是数组和整型变量106.3.2 数组参数的传递机制数组参数的传递机制分析一下函数调用栈,实参的值是通过进栈方式传递到函数中去的,进栈必须有栈空间。由于数组数据较多,如果采用一一进栈的方式,将使得函数在调用时光处理大批量数据的传递就要消耗无数的时间,这种方法显然不可取。而且为巨大的数据集合再来一个副本,内存开销太大而且也无必要。
5、所以数组实参不是将每个元素一一传递到函数中。116.3.2 数组参数的传递机制数组参数的传递机制图6.3 数组首地址传递示意C语言处理数组实参,实际上是将数组的首地址传到了函数形参中。126.3.2 数组参数的传递机制数组参数的传递机制尽管数组数据很多,但它们均从一个首地址连续存放,这个首地址对应的正是数组名。如果实参使用数组名调用,本质上是将这个数组的首地址(一个数值),像变量实参那样值传递到形参中。所以C语言传递数组时,依然是通过值传递方式。136.3.2 数组参数的传递机制数组参数的传递机制不过尽管都是通过值传递,但变量与数组实参还是有很大的不同。如图所示,变量x传的值是变量的数据值(1
6、0),这样形参n就是实参x的副本。数组实参a传的是数组首地址,形参A定义为数组形式,它现在的地址与实参数组a一样,则本质上形参数组对象A就是实参数组对象a(内存中两个对象所处位置相同,则它们实为同一个对象)。146.3.2 数组参数的传递机制数组参数的传递机制当数组作为函数参数时,有下面的特殊性。(1)由于形参数组就是实参数组,所以在被调函数中使用形参就是在间接使用实参,这点与变量作为函数参数的情况是不同的。156.3.2 数组参数的传递机制数组参数的传递机制例如:void fun(int A5,int n)A1=100; /A1实质就是实参a1n=10; /赋值给形参n,不影响实参xvoid
7、 caller()int a5=1,2,3,4,5,x=5;fun(a,x);printf(%d,%dn,a1,x); /a1=100,x=5166.3.2 数组参数的传递机制数组参数的传递机制实际编程中,可以用数组参数将被调函数处理过的数据返回到主调函数中。176.3.2 数组参数的传递机制数组参数的传递机制【例6.6】编写函数求一个二维数组中最大的元素及其下标。186.3.2 数组参数的传递机制数组参数的传递机制例题分析令max为元素最大值,采用枚举法逐一比较二维数组中的每一个元素Aij和max,若Aij大于max说明有一个更大的值出现,则令max=Aij且记录r=i和c=j,遍历完所有元
8、素,则Arc就是最大的元素。由于max必然是数组中的一个元素值,且先比较才有max=Aij,故设置max的初值为A中一个元素值,例如A00。由于函数需要返回最大元素值及下标行、列三个数据,而函数返回只能是一个数据,所以使用数组B传递到函数中,将下标行、列值“带回”。196.3.2 数组参数的传递机制数组参数的传递机制例6.61 #include2 int findmax(int A34,int B2)3 4 int i,j,max,r=0,c=0;5 max=Arc; /max初值设为A006 for (i=0; i3; i+) /枚举二维数组所有元素7 for (j=0; jmax) 9 r
9、 = i , c = j; /记录此时的下标10 max = Arc; /新的最大元素值;11 12 B0=r, B1=c; /下标行、列通过B数组返回到主调函数中13 return max; /最大值通过函数值返回到主调函数中14 15 int main()206.3.2 数组参数的传递机制数组参数的传递机制例6.616 17 int A34=7,5,-2,4,5,1,9,7,3,2,-1,6, B2, max;18 max=findmax(A,B);19 printf(max:A%d%d=%dn,B0,B1,max);20 return 0;21 216.3.2 数组参数的传递机制数组参数
10、的传递机制例6.61 #include2 int findmax(int A34,int B2)3 4 int i,j,max,r=0,c=0;5 max=Arc; /max初值设为A006 for (i=0; i3; i+) /枚举二维数组所有元素7 for (j=0; jmax) 9 r=i,c=j;/记录此时的下标10 max = Arc; /新的最大元素值;11 12 B0=r, B1=c; /下标行、列通过B数组返回到主调函数中13 return max; /最大值通过函数值返回到主调函数中14 15 int main()max:A12=9程序运行屏幕226.3.2 数组参数的传递机
11、制数组参数的传递机制(2)既然形参数组对象就是实参数组对象,所以函数定义中的形参数组就不像变量那样建立一个数组副本,即函数调用时不会为形参数组分配存储空间。形参数组不过是用数组定义这样的形式来表明它是个数组,能够接收实参传来的地址,形参数组的长度说明也无实际作用。236.3.2 数组参数的传递机制数组参数的传递机制因此,形参数组的长度与实参数组长度可以不相同,形参数组的长度可以是任意值,形参数组甚至可以不用给出长度。246.3.2 数组参数的传递机制数组参数的传递机制假设有函数调用:则以下函数定义:均是正确的。int a15;f(a);void f(int A100);/形参数组长度完全由实参
12、数组确定,因此函数中并不能按100个元素处理void f(int A10);/形参数组长度完全由实参数组确定,因此函数中并不能按10个元素处理void f(int A); /表明形参是数组形式即可256.3.2 数组参数的传递机制数组参数的传递机制(3)虽然实参数组将地址传到了被调函数中,但被调函数并不知道实参数组的具体长度,那么假定的大小对于实参数组来说容易数组越界。实际编程中可以采用下面两个方法来解决:函数调用时再给出一个参数来表示实参数组的长度;在实参数组中(一般是末尾)放上一个约定条件的数据,被调函数只要遇到这样的数据就结束对数组的遍历。266.3.2 数组参数的传递机制数组参数的传递
13、机制【例6.7】编写average函数求一组数据的平均值。276.3.2 数组参数的传递机制数组参数的传递机制例题分析为了让average函数能够适用于任意长度的数组,需要将数组的长度当作一个参数传入到函数中。286.3.2 数组参数的传递机制数组参数的传递机制例6.71 #include2 double average(double A,int n)3 4 int i; double s=0; /累加初值为05 for (i=0; in; i+) s=s+Ai; /先累加6 return n!=0 ? s/n : 0.0; /计算平均值7 8 int main()9 10 double A3
14、=1,2,3;11 double B5=1,2,3,4,5;12 printf(A=%lfn,average(A,3); /传递数组长度即可正确计算13 printf(B=%lfn,average(B,5); /传递数组长度即可正确计算14 return 0;15 296.3.2 数组参数的传递机制数组参数的传递机制例6.71 #include2 double average(double A,int n)3 4 int i; double s=0; /累加初值为05 for (i=0; in; i+) s=s+Ai; /先累加6 return n!=0 ? s/n : 0.0; /计算平均值
15、7 8 int main()9 10 double A3=1,2,3;11 double B5=1,2,3,4,5;12 printf(A=%lfn,average(A,3); /传递数组长度即可正确计算13 printf(B=%lfn,average(B,5); /传递数组长度即可正确计算14 return 0;15 A=2.000000B=3.000000程序运行屏幕306.3.2 数组参数的传递机制数组参数的传递机制(4)多维数组作为函数的参数,形参数组第1维可以与实参相同,也可以不相同;可以是任意长度,也可以不写长度;但其他维的长度需要相同。因为编译器是根据形参来检查实参调用的,它可以忽略第1维的长度大小,但其他维的长度由于决定了形参数组的结构而不能忽略。编译器不能对不同结构的数组类型作隐式转换。316.3.2 数组参数的传递机制数组参数的传递机制例如有函数调用:则函数定义:int a510f(a);void f(int A510); /正确void f(int A210); /正确void f(int A10); /正确void f(int A); /错误,第2维长度必须给出void f(int A55); /错误,第2维长度必须相同void f(int A50); /错误,必须是二维数组结束结束