




已阅读5页,还剩47页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七讲函数(2),2,上讲内容回顾,一、模块化程序设计(7.1)二、函数的定义(7.2)三、函数的调用(7.3),3,本讲主要内容,7.3.4函数的嵌套调用和递归函数7.4变量的作用域(Scope)与生存期(Lifetime),4,7.3.4函数的嵌套调用和递归函数,一、函数的嵌套调用二、函数的递归调用,5,#includestdio.hvoidf2()printf(*n);voidf1(intn)inti;for(i=1;i0;i-)a+=sub2(i);returna;,sub2(intn)returnn+1;,程序输出结果:9,嵌套调用举例:,8,【例】利用函数嵌套,编写程序,求出所有的两位绝对素数。,分析:(1)问题描述:绝对素数是指本身是素数,其逆序数也是素数的数。例如:10321与12301是绝对素数。两位绝对素数是将一个素数的个位和十位交换位置后仍为素数。例如:11是两位绝对素数。(2)需求分析和处理流程:用枚举法逐个判断所有两位数是否为绝对素数,输出绝对素数。,9,三要素:i=11;i=99;i+循环体:判断1个数是否为两位绝对素数。判断1个数是否为素数个位和十位交换再次判断交换后的数是否为素数设计自定义函数:判断1个数是否为两位绝对素数intabsoluteprime(intn);判断1个数是否为素数intprime(intn);将这个数的个位和十位交换intinvert(intn);,10,#include#includeintprime(intn)/*判断素数函数的定义*/intj,flag=1;for(j=2;j=sqrt(n);j+)if(n%j=0)flag=0;break;returnflag;,intinvert(inta)/*调换位置函数的定义*/intm,n;m=a/10;n=a%10;return(n*10+m);,11,voidmain()intn;for(n=11;n=99;n+)if(absoluteprime(n)printf(%dt,n);,/*判断一个数是否为绝对素数*/intabsoluteprime(intn)/*函数定义*/if(prime(n)=0)return0;elseif(prime(invert(n)=1)return1;elsereturn0;,12,数学中的递归定义。例如,求n的阶乘:要计算f(n)的值,就必须先算出f(n-1);要计算f(n-1)就必须先求出f(n-2);这样回推下去直到计算出f(0)时为止。由于f(0)已知,依此向回递归,计算出f(n)。,二、函数的递归调用,13,一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。递归调用有两种:直接递归:函数直接调用函数自身间接递归:函数调用其它函数,而其它函数又调用该函数自身。,(1)直接递归,voidfun(),.,fun();,.,(2)间接递归,voidfun1(),.,fun2();,.,voidfun2(),.,fun1();,.,二、函数的递归调用,14,无论是直接还是间接递归,两者都是无终止的调用自身。要避免这种情况的发生,使用递归解决的问题应满足两个基本条件:,(1)问题的转化。有些问题不能直接求解或难以求解,但它可以转化为一个新问题,这个新问题相对较原问题简单或更接近解决方法。这个新问题的解决与原问题一样,可以转化为下一个新问题,。,(2)转化的终止条件。原问题到新问题的转化是有条件的、次数是有限的,不能无限次数地转化下去。确定递归算法的结束条件(或边界条件),这是决定递归程序能否正常结束的关键。,二、函数的递归调用,15,【例】用递归法设计求n!的函数。,分析:(1)用递归法计算n!,可用下述公式表示:,(2)用递归函数可将n!表示为:,16,#includedoublef(intn)doubler;if(n0)printf(n0,inputerror);elseif(n=0|n=1)r=1;elser=n*f(n-1);returnr;voidmain()intn;doubley;printf(ninputainteagernumber:n);scanf(%d,程序如下:,/*函数调用*/,/*递归终止条件*/,/*递归调用*/,17,voidmain()y=f(4);,递归调用执行情况如下:,doublef(4)doubler;r=4*f(3);returnr;,doublef(3)doubler;r=3*f(2);returnr;,doublef(2)doubler;r=2*f(1);returnr;,doublef(1)doubler;return1;,doublef(intn)doubler;if(n=0|n=1)r=1;elser=n*f(n-1);returnr;,18,斐波那契数列的递归方法实现。计算并输出斐波那契数列的前7个数据。,intfib(intn)if(n=0|n=1)return1;elsereturnfib(n-1)+fib(n-2);,二、函数的递归调用,19,#includeintfib(intn)if(n=0|n=1)return1;elsereturnfib(n-1)+fib(n-2);voidmain()intf,i;for(i=0;i7;i+)f=fib(i);printf(%dt,f);,程序如下:,/*函数调用*/,/*递归终止条件*/,/*递归调用*/,20,7.4变量的作用域(Scope)与生存期(Lifetime),二、变量的作用域局部变量和全局变量,三、存储类型动态存储与静态存储,一、变量的存储空间分配概念,21,思考:1.何时为变量分配内存单元?2.将变量分配在内存的什么区域?3.变量占据内存的时间(生存期)?4.变量起作用的代码范围?,变量类型决定了变量在内存中所占的字节数及数据的表示形式,并且决定了变量起作用的代码范围,也决定了系统在什么时间、什么空间为变量分配或释放内存单元。这是变量的生存期和作用域。,一、变量的存储空间分配概念,22,一、变量的存储空间分配概念,变量定义位置变量的作用域空间(变量的使用范围)变量的存储类别变量的生存期时间(变量的建立到消亡),23,作用域:指能正确访问该变量的有效程序范围。,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),24,main()inti=1,j=3;printf(”%dn”,i+);inti=0;i+=j*2;printf(”%d,%dn”,i,j);printf(”%d,%d”,i,j);,程序输出结果为:16,32,3,例,函数体内定义的局部变量,复合语句内定义的局部变量,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),25,intm=13;intfun2(intx,inty)intm=3;return(x*y-m);main()inta=7,b=5;printf(”%d”,fun2(a,b)/m);,程序输出结果为:2,全局变量,例,局部变量,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),26,#includeintcalculator(void);voidmain(void)charop;inta,b,result;scanf(%d%c%d,【例】有实现简单四则算术运算器的程序如下,分析程序出错的原因。,intcalculator(void)switch(op)case+:result=a+b;break;case-:result=a-b;break;case*:result=a*b;break;case/:if(b!=0)result=a/b;elseprintf(error!);return(result);,变量op、a、b、result的作用域,变量op、a、b、result未定义,不起作用,intcalculator(charop,inta,intb)intresult;,局部变量,27,voidswap()intt,x,y;t=x;x=y;y=t;main()intx=3,y=5;printf(x=%d,y=%dn,x,y);swap();printf(x=%d,y=%dn,x,y);,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),例,28,例用全局变量实现两个数据的交换voidswap(intx,inty)intt;t=x;x=y;y=t;main()intx=3,y=5;printf(x=%d,y=%dn,x,y);swap(x,y);printf(x=%d,y=%dn,x,y);,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),29,例用全局变量实现两个数据的交换intx,y;voidswap()intt;t=x;x=y;y=t;main()x=3,y=5;printf(x=%d,y=%dn,x,y);swap();printf(x=%d,y=%dn,x,y);,各个函数都可以对全局变量的值进行修改,使程序难控制,尽量少使用全局变量。,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),30,例用全局变量实现两个数据的交换intx,y;voidswap(intx,inty)intt;t=x;x=y;y=t;main()x=3,y=5;printf(x=%d,y=%dn,x,y);swap(x,y);printf(x=%d,y=%dn,x,y);,结论:全局变量与局部变量同名时,局部变量的作用域屏蔽全局变量,可以实现吗?,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),31,局部变量同名不同函数中定义的局部变量(包括形参)可以同名,由于其作用域不同,因此互不影响。同一函数中不能定义两个同名的局部变量(包括形参)全局变量与局部变量同名当全局变量与某个函数中的局部变量同名时,在该函数内部局部变量的作用域将“覆盖”同名全局变量的作用域,关于变量同名,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),32,#includefloatmax,min,ave;voidcount()inti;floatsc;scanf(%d,【例】编写函数,统计10个成绩的最高分、最低分和平均分。(要求在main函数中输出结果),33,从程序设计的观点看,使用全局变量:,优点增加了函数间的数据传递联系同一文件中的若干函数引用全局变量,可以在多个函数间传递变量值的变化。函数通过全局变量可以得到多个返回值,缺点全局变量在程序的全部执行过程中都占用存储单元。使用全局变量过多,会降低程序的可读性和可维护性。所以要慎用、少用全局变量。某函数对全局变量的引用出错,导致系统难以维护。,二、变量的作用域局部变量(localvariable)与全局变量(globalvariable),34,三、存储类别动态存储与静态存储,变量的存储类别变量的存储类别反映了数据在内存中的存储方式。变量按作用域可分为局部变量和全局变量;按其存在的时间(生存期)分为静态存储变量和动态存储变量。,动态存储变量:程序运行期间根据需要临时分配存储空间的变量。特点:函数开始调用时为变量分配存储空间,函数结束时释放这些变量空间。静态存储变量程序运行期间“永久”占用固定内存的变量。特点:在静态存储区为变量分配存储单元,整个程序运行期间都不释放。,35,C语言变量存储分类符auto自动存储类型static静态存储类型extern外部存储类型register寄存器存储类型,如:autointa;staticintb;registerintd;,定义变量的一般形式:存储分类说明类型说明变量名;,三、存储类别动态存储与静态存储,36,1.auto(自动)存储类别变量,只能说明局部变量,函数内凡未加存储类型说明的变量均视为自动变量,自动变量说明必须在一个函数体内或复合语句中。随函数的调用而存在,随函数的返回而消失,它们在一次调用结束到下一次调用开始之间不再占有存储空间。,例:intkv(inta)autointx,y;/*auto可省*/autocharc;/*c的作用域*/*a,x,y的作用域*/,37,局部静态变量,全局静态变量,函数内部定义,作用域在函数内部,当所在的函数执行结束后,静态变量所占内存单元并不释放,其值仍然保留,直到整个程序结束。,函数外部定义,作用域仅限所在的源程序文件(.c),是指在编译时分配存储空间的变量,整个程序运行期间静态变量所占的存储单元不释放,其值不会丢失。对不赋初值的静态变量,初值自动为0。可以说明全局变量,也可以说明局部变量。,2、static(静态)存储类别变量,38,fun()inta=0;a+=2;printf(“%d”,a);main()intcc;for(cc=1;cc=4;cc+)fun();,结果是:2222,结果是:2468,例,局部静态变量,2、static(静态)存储类别变量,39,【例】在函数中使用static存储类别实现输出九九乘法表。,40,voidMul(void)staticinta=1;inti;for(i=1;i=a;i+)printf(%d*%d=%2d,a,i,a*i);printf(n);a+;voidmain(void)intb;for(b=1;b=9;b+)Mul();,41,intx,y;voidnum()inta=15,b=10;x=a-b;y=a+b;main()inta=7,b=5;x=a+b;y=a-b;num();printf(“%d,%dn”,x,y);,例,3.extern(外部)存储类别变量,说明:全局变量的定义省略存储类说明时,默认为extern。,42,voidnum()inta=15,b=10;x=a-b;y=a+b;intx,y;main()inta=7,b=5;x=a+b;y=a-b;num();printf(“%d,%dn”,x,y);,例,可以吗?,3.extern(外部)存储类别变量,43,全局变量的作用域是从定义点到本文件结束。如果定义点之前的函数需要引用这些全局变量时,需要在函数内对被引用的全局变量进行说明。其一般形式为:extern类型说明符变量名,变量名.其中方括号内的extern定义时可以省去不写,声明变量时不能省。,3.extern(外部)存储类别变量,44,voidnum()externintx,y;/*外部变量说明*/inta=15,b=10;x=a-b;y=a+b;intx,y;main()inta=7,b=5;x=a+b;y=a-b;num();printf(“%d,%dn”,x,y);,例,3.extern(外部)存储类别变量,45,变量,(按使用的存储媒介),内存变量,寄存器变量,使用CPU中的寄存器来存取变量的值,前面所介绍的变量都为内存变量,由编译程序在内存中分配存储单元,变量的存取在内存储器中完成,寄存器处在CPU的内部,可避免CPU频繁访问存储器,从而提高程序的执行速度,4.register(寄存器)变量,46,寄
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论