1、第17讲,调用函数和被调用函数间的数据传递 函数的递归调用、程序举例,形参与实参的概念 形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式,7.5 调用函数和被调用函数之间的数据传递,形参:x,y 形参必须指定类型;,实参:a,b 实参: a+5,100,(1) 实参表达式也可以是变量或常量,但必须有确定的值; (2) 要求形参与实参类型一致,个数相同(多:略/少:随机值); (4) 形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放; (5) C语言的参数传递方式值传递方式:函数调用时,系统临时为被调函数的形参分配存贮单元,并将实
2、参的值复制到形参中;当被调函数结束时,形参单元被释放,实参单元仍保留并维持原值。 特点:单向的值传递(数值或地址值)。,有关参数传递的几点说明,x,1.2,1.2,1.728,1.变量作为参数(单向的数值传递),Cube kju:b n.立方体, 立方,main() void swap(int , int);int x=10,y=20;printf(“(1)x=%d y=%dn”,x,y);swap(x,y);printf(“(4)x=%d y=%dn”,x,y); void swap(int a, int b) int t;printf(“(2)a=%d b=%dn”,a,b);t=a; a
3、=b; b=t;printf(“(3)a=%d b=%dn”,a,b); ,例7.1 函数参数之间的单向传递,程序运行结果为: (1)x=10 y=20 (2)a=10 b=20 (3)a=20 b=10 (4)x=10 y=20,main( ) void ex(int z,int y,int x); int x=10,y=20,z=30;printf(“(1)x=%d y=%d z=%dn”,x,y,z);ex(y,z,x); void ex(int x,int y,int z) printf(“(2)x=%d y=%d z=%dn”,x,y,z); ,例7.2 实参向形参按位置传递数据,程
4、序运行结果为: (1)x=10 y=20 z=30 (2)x=20 y=30 z=10,函数说明语句 形参名是一种虚设,函数调用语句确定实参顺序,函数定义 确定形参顺序,实参向形参按位置传递数据,补充例题,当数组名作为函数参数时,要求实参和形参都用数组名(或指针变量,第十章作介绍)。由于数组名的值就是数组在内存中分配的存储空间的首地址,这种方法称之为“传址调用”方式。当把实参数组名的值(首地址)传给形参数组名后,由于形参数组名也代表首地址,这样实参数组和形参数组的首地址相同,即实参数组和形参数组占用相同的存储空间。在被调函数中,形参数组中各元素的值如果发生变化,就会使实参数组元素的值同时也发生
5、变化。在函数调用结束后,虽然形参数组已不复存在,但实参数组元素的值已发生变化,可以在主调函数中进行使用。,2.数组名作为参数,(单向的地址值传递),例7.3 选择法排序,对N个数排序的算法步骤如下:(1)在N个数中寻找最小值,然后把这个最小值与最前面的那个数交换位置。,(2)排除最前面的那个数(i=i+1),在余下的N-1个数中寻找最小值,然后把这个最小值与最前面的那个数交换位置。如此循环,直到最后只剩一个数(i=N-1)时结束。,对10个数排序的算法步骤演示如下:,下标: 0 1 2 3 4 5 6 7 8 9,对10个数排序的算法步骤演示如下:,下标: 0 1 2 3 4 5 6 7 8
6、9,总结:10个数排序,需要进行九次的上述操作。 若有N个数需要排序,则需要进行N-1次的上述操作。,10个数排序的完整程序如下:,void sort(int a10) int i,j,k,t;for(i=0;i9;i+)k=i;for(j=i+1;j10;j+)if(ajak)k=j;t=ak;ak=ai;ai=t;,main() int i,x10=5,7,4,2,8,6,1,9,0,3;printf(“the original array:n“);for(i=0;i10;i+)printf(“%d“,ai);printf(“n“);sort(x);printf(“the sorted a
7、rray:n“);for(i=0;i10;i+)printf(“%d“,ai);printf(“n“);,程序运行结果为: the original array: 5 7 4 2 8 6 1 9 0 3 the sorted array: 0 1 2 3 4 5 6 7 8 9,例7.4 将一个数组中的n个数据按颠倒的顺序重新存放,解题思路为:借助于一个临时变量,将a0与an-1对换,再将a1与an-2对换,直到将a(n-1)/2-1与an-int(n-1)/2)-1对换。 程序采用循环来实现,设二个“位置指针变量”i和j,i的初值为0,j的初值为n-1,将ai与aj交换,然后使i的值加1,j
8、的值减1,再将ai与aj交换,直到i=m为止。m=(n-1)/2为“中间位置”。见图7.2所示。,i=0,j=n-1,i=1,j=n-2,m=(n-1)/2,数组逆序程序,void inv(int x ,int n) int t,i,j,m=(n-1)/2;for(i=0;i=m;i+) j=n-1-i;t=xi;xi=xj; xj=t; ,main() int i,a10=10,20,90,100;printf(“The original array:n“);for(i=0;i10;i+)printf(“%d “,ai);printf(“n“);inv(a,10);printf(“The a
9、rray has been inverted:n“);for(i=0;i10;i+)printf(“%d “,ai);printf(“n “);,程序运行结果为: The original array: 10 20 30 40 50 60 70 80 90 100 The array has been inverted: 100 90 80 70 60 50 40 30 20 10,void inv(int x ,int n) int t,i,j=n-1;for(i=0;ij;i+,j-)t=xi;xi=xj; xj=t;,例7.5 求二维数组每行元素的平均值,void lineave(int
10、 x 4,float y ,int n) int i,j,s;for(i=0;in;i+) s=0; for(j=0;j4;j+)s=s+xij;yi=s/4.0;/*书印错: bi=s/4.0*/,main() int a34=1,2,3,4,5,6,7,8,9,10,11,12;int i,j;float b3;lineave(a,b,3);for(i=0;i3;i+) for(j=0;j4;j+)printf(“%4d”,aij);printf(“ ave:%6.2dn”,bi);,程序运行结果为:1 2 3 4 ave: 2.505 6 7 8 ave: 6.509 10 11 12
11、ave: 10.50,1. 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数,7.6 函数的嵌套与递归调用,#include int dif(int x,int y,int z);int max(int x,int y,int z);int min(int x,int y,int z); void main()int a,b,c,d;scanf(“%d%d%d“,int dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r;r=xy?x:y;return(rz?r:z);
12、 int min(int x,int y,int z) int r;r=xy?x:y;return(rz?r:z);,例 求三个数中最大数和最小数的差值,例 用弦截法求方程根,运行情况: Input x1,x2: 2,6 A root of equation is 5.0000,函数的嵌套举例,2.递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,说明 C编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,int f(int x) int y,z;z=f(y);.return(2*z); ,#
13、include int fac(int n) int f;if(n=0|n=1) f=1;else f= fac(n-1)*n;return(f ); main() int n, y;printf(“Input a integer number:“);scanf(“%d“, ,int fac(int n) /*更完善的阶乘函数*/ int f;if(n0) printf(“n0,data error!“);return(-1);if(n=0|n=1) f=1;else f= fac(n-1)*n;return(f ); ,递归方法的要点: 1. 递推公式f n = f n-1*n 2. 结束条
14、件。n=0|n=1,例7.6用递归的方法求n的阶乘,#include int fib(int n) int f;if(n=1|n=2) f=1;else f= fib(n-2)+fib(n-1);return(f ); main() int n, s;printf(“Input a integer number:“);scanf(“%d“, ,递归方法的要点: 1. 递推公式f n = f n-2+ f n-1 2. 结束条件。n=1|n=2,例7.7 用递归实现斐波那契数列,#include “math.h“ int isprime(int); main() int x;scanf(“%d“
15、, ,编写函数isprime(int n)用来判断自变量n是否为素数,若是,函数返回1,否则返回0。,isprime(int n) int i, flag=1;for(i=2;i=sqrt(n);i+)if(n%i=0)flag=0;break; return (flag); ,isprime(int n) int i, flag=1;for(i=2;i=sqrt(n) ,7.7 函数程序举例例7.8,#include “math.h“ int isprime(int); void even(int); main() int a;printf(“Enter a even number:“);s
16、canf(“%d“, isprime(int n) ,例7.9 编写函数,验证任意偶数为两个素数之和并输出这两个素数。,程序运行结果为: Enter a even number:10 10=3+7,例7.10 利用梯形法求定积分,利用梯形法求定积分,double integ(double a,double b) double s,x,h,f(double);int n=100,i;h=fabs(b-a)/n; s=(f(a)+f(b)/2.0;for(i=1;i=n-1;i+)x=a+i*h;s=s+f(x);ruturn s; double f(double x) return sin(x)
17、; ,#include “math.h“ double integ(double a,double b); main() double s;s=integ(0.0,10.0);printf(“s=%fn“,s); ,程序运行结果为: s=1.837539,例7.11 编写函数统计输入的一行字符中出现的每个小写字母的个数。,#include “stdio.h“ #include “string.h“ void countch(char c,int b); void main() char c,ch81; int b26=0;gets(ch);countch(ch,b);for(c=a;c=z;c
18、+)printf(“%c:%d“,c,bc-97);if(c-97+1)%10=0)printf(“n“);,void countch(char c,int b) int k,l;l=strlen(c);for(k=0;k=a ,程序运行结果为: this is a statistics program! a:3 b:0 c:1 d:0 e:0 f:0 g:1 h:1 i:4 j:0 k:0 l:0 m:1 n:0 o:0 p:1 q:0 r:2 s:5 t:4 u:0 v:0 w:0 x:0 y:0 z:0,例7.12 求某班每门课程的平均成绩和每个学生的平均成绩,#define M 3 #
19、define N 4 void courave(int a,int b,float scoreN) int course,stud;float total1,aver1;for(course=0;courseb;course+)total1=0;for(stud=0;studa;stud+)total1=total1+scorestudcourse;aver1=total1/a;printf(“average of course %d is:%6.2fn“,course+1,aver1); ,求某班的课程平均成绩和学生的平均成绩,void studave(int a,int b,float s
20、core N) int course,stud;float total2,aver2;for(stud=0;studa;stud+)total2=0;for(course=0;courseb;course+)total2=total2+scorestudcourse;aver2=total2/b;printf(“average of student %d is:%6.2fn“,stud+1,aver2); main() float scoreMN=89,78,56,88,99,100,72,80,61,60,70,75;courseave(M,N,scoreMN);studave(M,N,sc
21、oreMN); ,程序运行结果为: average of course 1 is: 77.25 average of course 2 is: 81.75 average of course 3 is: 73.00 average of student 1 is: 76.33 average of student 2 is: 95.33 average of student 3 is: 71.00 average of student 4 is: 68.33,courave(M,N,score); studave(M,N,score);,教材P112 习题七 第一大题:112小题; 第二大题:1、2、7、8小题; 第三大题:1、2、3、6小题。,第七章 作业,