第六章 函数2.ppt
6.3 6.3 函数的嵌套与递归调用函数的嵌套与递归调用6.3.1 6.3.1 嵌套调用嵌套调用C C规定:函数不可嵌套定义,但可以嵌套调用规定:函数不可嵌套定义,但可以嵌套调用main()调用函数调用函数a结束结束a函数函数b函数函数调用函数调用函数b6.3 嵌套调用和递归调用 6.3.2 6.3.2 函数的函数的递归调用递归调用 递归调用递归调用递归调用递归调用 在调用一个函数过程中又出现直接或间接地在调用一个函数过程中又出现直接或间接地调用该函数本身,前者称之为直接递归调用,后调用该函数本身,前者称之为直接递归调用,后者称之为间接递归调用。者称之为间接递归调用。func()调调func调调func2调调func1func1()func2()float func(int n)int m;float f;f=func(m);.funcl(int n)int m;func2(m);.func2(int x)int y;funcl(y);.直接递归调用直接递归调用直接递归调用直接递归调用 间接递归调用间接递归调用间接递归调用间接递归调用 long int fact(int n)long int f;if(n=0)f=1;else f=n*fact(n-1);return(f);#include stdio.h void main()int n;long int result;long int fact(int n);while(1)printf(”Input a number:”);scanf(”%d”,&n);if(n=0)break;result=fact(n);printf(”Result=%ld”,result);【例例6_166_16】从键盘输入一非负整数从键盘输入一非负整数n n,并求出,并求出n!n!的值。的值。n!=n*(n-1)!结果分析:结果分析:n=4 f(4)=4*fact(4-1)=3 f(3)=3*fact(3-1)=2 f(2)=2*fact(2-1)=1 f(1)=1*fact(1-1)=0 f(0)=1回推回推递推递推运行情况:运行情况:Input a number:4 Result=24递归调用递归调用嵌套调用嵌套调用if(n=0)/*递归终止条件递归终止条件*/f=1;递归过程的两个阶段:递归过程的两个阶段:fact(4)是主函数调用的。在一次调用是主函数调用的。在一次调用fact函数时函数时并不是立即得到并不是立即得到fact(4)的值,而是一次又一次地的值,而是一次又一次地进行递归调用进行递归调用(回推回推),直到,直到fact(1)时才有确定的值。时才有确定的值。之后,再递推出之后,再递推出fact(2)、fact(3)、fact(4)的值。的值。double xpower(float x,int n)if(n=0)return(1);else return(x*xpower(x,n-1);#include stdio.h void main()double xpower(float x,int n);float x;int n;double r scanf(”%f%d”,&x,&n);r=xpower(x,n);printf(”Result=%f”,r);【例例6_17】编一程序,利用函数的递归调用求编一程序,利用函数的递归调用求x的的n次方的值,次方的值,其中其中n为正整数。为正整数。运行情况:运行情况:2,3 Result=8 小结:小结:任何有意义的递归调用总是由两部分组成:任何有意义的递归调用总是由两部分组成:即即递归方式递归方式与与递归终止条件递归终止条件。if(n=0)/*递归终止条件递归终止条件*/return(1);6.4 6.4 作用域和存储类型作用域和存储类型概述概述变量是对程序中数据的存储空间的抽象变量是对程序中数据的存储空间的抽象内存内存.void main()int a;a=10;printf(“%d”,a);编译或函数调用时为其分配内存单元编译或函数调用时为其分配内存单元102000程序中使用变量名对内存操作程序中使用变量名对内存操作变量的属性变量的属性数据类型:变量所持有的数据的性质(数据类型:变量所持有的数据的性质(操作属性操作属性)存储属性存储属性存储方式存储方式:静态存储与动态存储:静态存储与动态存储-静态变量静态变量与动态变量与动态变量生存期生存期:变量在某一时段存在:变量在某一时段存在作用域作用域:变量在某区域内有效:变量在某区域内有效-局部变量与局部变量与全局变量全局变量可见性可见性:可以对变量进行操作为可见:可以对变量进行操作为可见变量的存储类型变量的存储类型auto -自动型自动型register-寄存器型寄存器型static -静态型静态型extern -外部型外部型变量定义格式变量定义格式:存储类型存储类型 数据类型数据类型 变量表变量表;如如:int sum;auto int a,b,c;register int i;static float x,y;局部变量与全局变量局部变量与全局变量局部变量局部变量-内部变量内部变量定义:在定义:在函数内定义函数内定义,只在本函数内有效只在本函数内有效说明:说明:mainmain中定义的变量只在中定义的变量只在mainmain中有效中有效不同函数中同名变量,占不同内存单元不同函数中同名变量,占不同内存单元形参属于局部变量形参属于局部变量可定义在复合语句中有效的变量可定义在复合语句中有效的变量局部变量可用存储类型局部变量可用存储类型:auto auto register static register static (默认为默认为autoauto)例例 不同函数中同名变量不同函数中同名变量void sub()int a,b;a=6;b=7;printf(sub:a=%d,b=%dn,a,b);void main()int a,b;a=3;b=4;printf(main:a=%d,b=%dn,a,b);sub();printf(main:a=%d,b=%dn,a,b);运行结果:运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4运行结果:运行结果:5 4 3 2 1例例 复合语句中变量复合语句中变量#define N 5void main()int i;int aN=1,2,3,4,5;for(i=0;iN/2;i+)int temp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;ib?a:b;return(c);void main()int a=8;printf(max=%d,max(a,b);例例 外部变量与局部变量外部变量与局部变量运行结果:运行结果:max=8int i;void main()void prt();for(i=0;i5;i+)prt();void prt()for(i=0;i5;i+)printf(“%c”,*);printf(“n”);例例 外部变量副作用外部变量副作用运行结果:运行结果:*例例 auto 变量的作用域变量的作用域void main()int x=1;void prt(void);int x=3;prt();printf(“2nd x=%dn”,x);printf(“1st x=%dn”,x);void prt(void)int x=5;printf(“3th x=%dn”,x);结果:结果:3th x=52nd x=31st x=1 x=1作用域作用域 x=1作用域作用域 x=3作用域作用域 x=5作用域作用域void main()void increment(void);increment();increment();increment();void increment(void)int x=0;x+;printf(“%dn”,x);例例 局部静态变量值具有可继承性局部静态变量值具有可继承性运行结果:运行结果:1 1 1void main()void increment(void);increment();increment();increment();void increment(void)static int x=0;x+;printf(“%dn”,x);运行结果:运行结果:1 2 3变量存储类型变量存储类型静态静态动态动态存储方式存储方式程序整个运行期间程序整个运行期间函数调用开始至结束函数调用开始至结束生存期生存期编译时赋初值,编译时赋初值,只赋一次只赋一次每次函数调用时每次函数调用时赋初值赋初值自动赋初值自动赋初值0 0或空字符或空字符不确定不确定未赋初值未赋初值静态存储区静态存储区动态区动态区存储区存储区寄存器寄存器局部变量局部变量全局全局变量变量作用域作用域定义变量的函数或复合语句内定义变量的函数或复合语句内本文件本文件 本程序本程序u局部变量默认为局部变量默认为autoauto型型uregisterregister型变量个数受限型变量个数受限,且不能为且不能为long,double,floatlong,double,float型型u局部局部staticstatic变量具有变量具有全局寿命全局寿命和和局部可见性局部可见性u局部局部staticstatic变量具有变量具有可继承性可继承性uexternextern不是变量定义不是变量定义,可扩展外部可扩展外部变量作用域变量作用域 register register 局部局部staticstaticautoauto外部外部staticstatic外部外部存储类别存储类别例例 文件文件file1.cppint a;void main().f2;.f1;.void f1()auto int b;f2;.void f2()static int c;C作用域作用域 b作用域作用域 a作用域作用域mainf2f1mainf1f2main a:b:c:生存期生存期mainf2f1mainf1f2main a:b:可见性可见性 c:例例 引用其它文件中的外部变量引用其它文件中的外部变量int global;extern float x;void main()int local;.extern int global;static int number;void func2().float x;static int number;void func3()extern int global;.file1.cppfile2.cppfile3.cpp外部函数和静态函数外部函数和静态函数一一个个函函数数要要被被另另外外的的函函数数调调用用,根根据据函函数数能能否否被被其其他他的的源源文文件件所所调调用用,可可将将函函数数分分为为外外部部(extern)型型和和静静态态(static)型型,这这是是在在函函数数定定义义时时由由存存储储类类说说明明来来指指定定。若若定定义义为为extern型型时时,则则在在整整个个源源程程序序的的所所有有源源文文件件内内都都可可以以调调用它。用它。关键字关键字extern不写不写.例如:例如:extern 函数名函数名(形参表形参表).(1)函数多为外部型,会产生不同源文件中同名函数)函数多为外部型,会产生不同源文件中同名函数的冲突。的冲突。(2)若函数定义为静态型,则只能被该函数所在源文)若函数定义为静态型,则只能被该函数所在源文件的其他函数所调用,但不能被其他源文件的函数件的其他函数所调用,但不能被其他源文件的函数所调用。所调用。static 函数名函数名(形参表形参表).