资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,Chap_9,函数,函数的组织,递归函数,变量与函数,宏定义,一个例子,#include,double fact(,int,n);,void main(),int,i,m;double s=0;,while(,scanf(%d,for(i=1;i=m;i+)s+=1.0/fact(i);,printf(“s,=%,dn,s);,本程序中出现了哪些函数?,double,fact(int,n),int,i;double f=1;,for(i,=1;i=n;i+),f*=i;,return f;,函数类型,_1,从用户角度:,库函数,:,scanf,(),printf,(),getchar,(),putchar,(),puts(),gets(),fabs,(),sqrt,(),exp(),strcpy,(),strcat,(),strcmp,(),strlen,(),isdigit,(),isalphar,(),isupper,(),islower,(),toupper,(),自定义函数,:,主函数,main(),其他函数,fact(),#include,函数类型,_2,从函数的参数:,无参函数,如,void main,(),有参函数,如,double fact,(,int,n),从函数的返回值:,无返回值函数,如,void,main(),有返回值函数,如,double,fact(,int,n),函数体中带,return,语句,【09,春试题,】,函数的定义与调用,定义函数,fact(n,),,计算,n!,,形参,n,的类型是,int,,函数类型是,double,。,定义函数,cal(x,e,),,计算多项式,s,,直到最后一项绝对值小于,e,,,形参,x,和,e,的类型都是,double,,函数类型是,double,,要求调用,fact(n,),函数,调用库函数,pow(x,n,),来计算,x,n,。,定义函数,main(),,输入两个浮点数,x,和,e,,计算多项式的值,直到最后一项的绝对值小于精度,e,。要求调用,cal(x,e,),【,函数功能分析,】,主函数,main(),:,输入,x,和,e,;调用函数,cal(x,e,),;输出结果,自定义函数,cal(x,e),:,累加求和;调用函数,fact(i,),求,i,!,调用库函数,pow(x,i,),求,x,i,;向主调函数,main(),返回,s,自定义函数,fact(n,),:,求,n!,;向主调函数,cal(),返回,n!,函数调用关系,void main(),double cal(),double fact(),double,pow,(),x,e,i,x,i,i,!,x,i,s,函数的嵌套调用,定义函数,fact(),/*,定义函数,fact(n,),,计算,n!,,形参,n,的类型是,int,,函数类型是,double*/,double fact(,int,n,),int,i;,double f=1;,for(i=1;i=,n,;i+),f*=i;,return,f,;,定义函数,cal(),/*,定义函数,cal(x,e,),,计算多项式,s,的值,直到最后一项绝对值小于,e,,形参,x,和,e,的类型是,double,,函数类型是,double*/,#include,/,库函数,pow,(),,,fabs,(),double,cal(double,x,double,e,),double item,s=0;,int,i=1;,do item=,fact(i)/pow(,x,i,);,s+=item;,i+;,while(,fabs(item,)=,e,),return,s,;,定义主函数,main(),/*,定义函数,main(),,输入两个浮点数,x,和,e,,计算多项式,s,的值,(,最后一项绝对值小于,e)*/,#include,void main(),double,x,e,;,printf(Input,x,e:);,scanf(“%lf%lf,”,&,x,&e,);,printf(s,=%f n,cal,(,x,e,);,当函数定义在前,无需函数声明,9.2,递归函数,求阶乘!,解法一,:递推定义,n!=1*2*3*n,for(f=1,i=1;i1,9.2,递归函数,-,求,!,#include,void main(),int,n;,double fact();,scanf(%d,&n,);,printf(%fn,fact(n),);,不可写成,fact(n,)=n*fact(n-1),;,递归式子,递归出口,double,fact(int,n),double r;,if(,n=1,),r=1;,else,r=n*,fact(n-1),;,return r;,递归函数,fact(n),的实现过程,fact(3)=3*fact(2),2*fact(1),fact(1)1,2*1=2,3*2=6,递归函数,递归函数,:函数体中直接或间接地调用该函数本身。,哪些问题可以用递归函数实现?,问题可逐步简化成自身较简单的形式,即,递归式子,,如:!()!,2.,有递归的最终结束条件,即,递归出口,如:,if(n=1)r=1;,两个条件缺一不可!,Fibonacci,数列,1 n=1,2,fib(n,),fib(n-1)+fib(n-2)n2,int,fib,(,int,n),int,r,;,if,(,n,=,1|n=2,),r=,1;,else,r=,fib,(n-1)+,fib,(n-2),;,return,r,;,递归出口,递归式子,用递归函数求,1+2+n,1 n=1,sigma(n,),sigma(n-1)+n n1,int,sigma,(,int,n),int,i,s,=0;,for(i,=1;i1,):,先将上面的,n-1,个盘子搬到辅助塔,b,;,再将,第,n,个,盘子从源塔搬,a,到目标塔,c;,最后将放在辅助塔,b,上的,n-1,个盘子搬到目标塔,c,Hanoi,塔,A B C,A B C,n,n-1,n-1,n-1,hanoi(n,a,c,b,),hanoi(n-1,a,b,c),hanoi(n-1,b,c,a),Hanoi,塔的递归函数,void,hanoi,(,int,n,char,a,char,c,char,b,),if(,n=1,),printf,(“%,c,%cn,”,a,c,);,else,hanio,(,n-1,a,b,c,);,printf,(“%,c,%cn,”,a,c,);,hanio,(,n-1,b,c,a,);,直接搬,1,个盘子,a,c,相关主函数,#include,void,hanoi,(,int,n,char,a,char,c,char,b,),;,void main(),int,n;,printf(“Input,n:”);,scanf(“%d”,&n,);,hanoi,(n,A,C,B);,9.3,变量与函数,在函数内,定义的变量(包括形参),局部变量,作用范围:本函数内部,在复合语句内,定义的变量,作用范围:复合语句内部,全局变量:,在函数以外,定义的变量,不,属,于,任一函数,作用范围:,整个程序有效(包括各函数),全局,or,局部?,-,在何处定义,局部变量,&,全局变量,#include,int,x,=1;,void main(),int,a,=2;,.,int,b,=3;.,f();.,int,y,=4;,void f(),int,x,=5,b,=6;,.,int,a,=7;,x=?a=?y=?,b=?,x=?a=?y=?,如果函数中的局部变量与全局变量重名,则以,局,部变量起作用。,int,x,=1;,int,f(int,x,),return(,x,+);,void main(),int,y,;,y,=f(2);,x,=,f(,x,);,printf(%d,%d,y,x,);,输出,x=1 a=2 y=4,b,未定义,x=5 a=7 y=4,x=1,2 1,如果某函数的局部变量与全局变量重名,则,局,部变量,起作用。,不要滥用全,局,变量,它会产生副作用,局部变量,&,全局变量,9.3.2,变量生命周期和静态局部变量,自动变量(,auto,),普通的局部变量,。,int,x,y;,auto,int,x,y;,特点,:执行到定义语句,系统动态产生存储单元;一旦函数结束,系统自动回收存储单元。,int,f(,int,y),int,x=1;,return y+x+;,void main(),f(,f(,f(1),),),;,x=1,2,y=1,返回,2,x=1,2,y=2,返回,3,x=1,2,y=3,返回,4,静态变量,(,static,),静态局部变量,静态全局变量,特点:不随函数的结束而自动回收存储单元。同一函数的两次调用,所用的存储单元为同一个单元,保存原来的值。,x=1,2,y=1,返回,2,x=2,3,y=2,返回,4,x=3,4,y=4,返回,7,int,f(,int,y),static,int,x=1;,return y+x+;,void main(),f(,f(,f(1),),),;,静态变量(,static,)的,说明:,静态变量若不赋初值,自动取或,0,。,局部静态变量在函数调用结束后,只要主函数未结束,它仍保留原值,当再次进入函数时才能使用。,函数中的静态变量,仅在第一次调用时才赋初值。,【,例,9-9】,写出下列程序的输出结果。,void,fun(int,k),;,void main(),int,k;,for(k=1;k=3;k+),fun(k,);,void,fun(int,k),static,int,a;/a,初值,=0,printf(”%d,”,a);,a+=k;/,静态变量,a,保留上一次调用产生的值,运行结果:,0,,,1,,,3,、外部变量(,extern,),在一个文件中要使用在另一文件中定义的全局变量,应使用外部变量:,extern,x;,、寄存器变量,(,register,),定义:,register,int,x;,register char c;,使用寄存器变量比普通变量运行速度更快,9.4,宏定义,格式,:,#define,宏名 宏定义字符串,作用,:,编译,时,把程序中所有与宏名相同的字符串,替换成 宏定义字符串,#define PI 3.14,#define,arr,_,size,4,说明,:,宏名一般用,大写,字母,以与变量名区别,宏定义不是语句,后面不得跟分号,宏定义可以嵌套使用,#define PI 3.14,#define AA 2*PI*,PI,4,宏名,中间不能有空格,ARR_SIZE,#define AA for(i=0;i10;i+),空格,不可:,#define A A for(i=0;i10;i+),宏定义的作用,1,、保持符号常量,精度,的一致性及,可读性,,如,PI,2,、,数组,大小的定义,#,define N 6,main(),int,aN;,for(i=0;iN;i+),scanf(“%d”,&ai,);,3,、,可以实现一些简单的函数,4,、对程序的一些固定的书写可以偷一下懒,但不得降低程序的可读性。,带参数的,宏定义,#define f(a)a*a*a,void main()/*,水仙花数 *,/,int,i,x,y,z;,for(i=1;i1000;i+),x=i%10;y=i/10%10;z=i/100;,if(x,*x*,x+y,*y*,y+z,*z*z=i),printf(“%dn,”,i);,F(x+y,),(,x+y),3,#,define,F(a,),(,a,),*,(,a,),*,(,a,),水仙花数:,1,3,+5,3,+3,3,=153,i,f,(,F(x,),+,F(y,),+,F(z,),=i),=,x+y,*,x+y,*,x+y,带参数的宏定义实现简单的函数功能,例:用宏实现两个变量值的交换,#define,F(a,b,c,)c=a;a=b;b=c;,main(),int,x,y,temp,;,scanf(“%d%d,”,F(x,y,temp,),printf(“%d,%,dn,”,x,y);,temp=x;x=y;y=temp;,编译时被替换,注意,:,(1),带参数的宏定义不是函数,宏与函数是两种不同的概念。,(2),宏可以实现简单的函数功能,【,例,9-12】,程序输出结果,?,#define,F(x,)x,-,2,#define,Q(x,)x*,F(x,),void main(),printf(%d,%d,Q(3),Q(Q(3);,分析:,先替换所有宏,再统一代入计算,不可一边代入一边计算,Q(3),=x*,F(x,),=x*,x-2,=3*3-2=7,Q(Q(3),=,Q(x,*x-2),=x*x-2*,F,(x,*x-2),=x*x-2*x*x-2-2,=3*3-2*3*3-2-2=-13,运行结果:,7 -13,#define,F(x,)x-2,#define,Q(x,)x*,F(x,),代入,x=3,代入,x=3,小结与作业,小结:,函数的嵌套调用,递归函数,局部,/,全局变量,静态变量,宏,作业:,1,,,2,,,3,6,,,8,,,9,上机实验题,12,
展开阅读全文