1 / 19

上讲回顾

上讲回顾. 结构化程序设计的思想及方法; 函数的原型声明; 函数的定义; 函数的形参、实参; 函数调用;. 本讲要点. 函数的嵌套; 函数的递归调用; 局部变量、全局变量; 变量的存储类别;. 函数的嵌套. 函数的 定义 互相平行、独立。 在定义函数时,一个函数内 不能 包括另一个函数的定义。 即函数不能嵌套定义!如以下形式: … main() { …} int A(…) // 函数 A 的定义 { … int B(… ) // 函数 B 的定义 {…} }. ×.

Télécharger la présentation

上讲回顾

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 上讲回顾 • 结构化程序设计的思想及方法; • 函数的原型声明; • 函数的定义; • 函数的形参、实参; • 函数调用;

  2. 本讲要点 • 函数的嵌套; • 函数的递归调用; • 局部变量、全局变量; • 变量的存储类别;

  3. 函数的嵌套 • 函数的定义互相平行、独立。 • 在定义函数时,一个函数内不能包括另一个函数的定义。即函数不能嵌套定义!如以下形式: … main() { …} int A(…) //函数A的定义 { … int B(… ) //函数B的定义 {…} } × • 函数不可以嵌套定义,即在定义一个函数的时候,不能同时再定义另一个函数!

  4. 函数的嵌套 • 函数可以嵌套调用,即在定义一个函数时,可以在函数体中调用另外的函数;

  5. int _min(int a,int b,int c) {//求三个数的最小值 int min; min=a>b?b:a; min=min>c?c:min; return min; } //例 从键盘输入三个数,求它们中最大数和最小数的差 #include<stdio.h> void main( ) {int _max(int,int,int);//原型声明 int _min(int,int,int); //原型声明 int _dif(int,int,int); //原型声明 int x,y,z; scanf("%d,%d,%d",&x,&y,&z); printf("%d\n",_dif(x,y,z)); } int _max(int a,int b,int c) {//求三个数的最大值 int max; max=a>b?a:b; max=max>c?max:c; return max; }(接右上) int _dif(int a,int b,int c) { //求三个数最大值、最小值之差 return _max(a,b,c)-_min(a,b,c); } • 函数的嵌套调用:在自定义函数_dif()定义的过程中调用了自定义函数_max()和_min();

  6. 函数的递归调用 • 递归调用:在调用一个函数的过程中又出现了直接或者间接的调用该函数本身。 • 直接调用:在调用某一函数A时,又出现了嵌套调用该函数本身的情况;(较常见) • 间接调用:在调用某一函数A的过程中,嵌套调用了另一函数B,在函数B中,又出现了调用函数A的情况;

  7. 例:求n! • 非递归 #include<stdio.h> void main( ) { int n,i,p=1; scanf("%d",&n);//本例未对n的有效性进行判断 for(i=1;i<=n;i++) p*=i; printf("%d\n",p); }

  8. 1 n=0,1 n!= n*(n-1)! n>1 递归求解 分析: n=0 其阶乘p=0!=1; n=1 其阶乘p=1!=1; n=2 其阶乘p=2!=1!*2=2; n=3 其阶乘p=3!=2!*3=6; …

  9. 分析 • 如果自定义一个函数fac( )来求阶乘,那么fac(n)=fac(n-1)*n,在求n的阶乘时要调用自身函数,即存在递归(直接调用)。

  10. 在fac函数中出现了调用自身的情况,(直接调用)---递归调用在fac函数中出现了调用自身的情况,(直接调用)---递归调用 自定义求阶乘的函数fac( ) float fac(int n) { //自定义fac函数求n的阶乘 float f; if(n<0) printf(“Error!\n”);//x<0时,数据无效; else if(n==0||n==1) f=1; //0 or 1的阶乘为1; else f=fac(n-1)*n; //n的阶乘等于n-1的阶乘乘n; return f; //返回n的阶乘值 }

  11. float fac(int n) • { //自定义fac函数求n的阶乘 • float f; • if(n<0) • printf("Error!\n");//x<0时,数据无效; • else if(n==0||n==1) • f=1; //0 or 1的阶乘为1; • else • f=fac(n-1)*n;//n的阶乘等于n-1的阶乘乘n; • return f; //返回n的阶乘值 • } //完整的递归调用求n!源程序 #include<stdio.h> void main() { float fac(int);//原型声明 int n; float f; printf("please input the data:\n"); scanf("%d",&n); f=fac(n); printf("%f\n",f); }

  12. float fac(int n) • { //自定义fac函数求n的阶乘 • float f; • if(n<0) • printf("Error!\n");//x<0时,数据无效; • else if(n==0||n==1) • f=1; //0 or 1的阶乘为1; • else • f=fac(n-1)*n; //n的阶乘等于n-1的阶乘乘n; • return f; //返回n的阶乘值 • } 问题:两个函数中都有n, f变量, 为什么编译时没有报错,提示变量 重复定义? #include<stdio.h> void main() { float fac(int);//原型声明 int n; float f; printf("please input the data:\n"); scanf("%d",&n); f=fac(n); printf("%f\n",f); }

  13. 变量的作用域 • 变量的作用域:变量的作用范围,即变量有效的范围。 • 变量的分类 • 从作用域分,可分为局部变量,外部变量(又称为全局变量or全程变量) • 局部变量---在函数内部定义的变量;它只在本函数内有效,即只在本函数内才能使用它们;其作用域只限于从定义的位置到本函数结束。 • 外部变量---在函数之外定义的变量;它可被源程序中其他函数所共用;其作用域从变量定义的位置到源程序结束。

  14. 分析一下,在fac函数中n,f分别都是什么变量,他们的作用范围分别是什么?分析一下,在fac函数中n,f分别都是什么变量,他们的作用范围分别是什么? • float fac(int n) • { //自定义fac函数求n的阶乘 • float f; • if(n<0) • printf("Error!\n");//x<0时,数据无效; • else if(n==0||n==1) • f=1; //0 or 1的阶乘为1; • else • f=fac(n-1)*n; //n的阶乘等于n-1的阶乘乘n; • return f; //返回n的阶乘值 • } #include<stdio.h> void main() { float fac(int);//原型声明 int n; float f; printf("please input the data:\n"); scanf("%d",&n); f=fac(n); printf("%f\n",f); } n为局部变量 f为局部变量 n作用范围 f作用范围

  15. 关于全局变量说明 • 设置全局变量增加了函数间数据联系的渠道,因为全局变量可以被同一源程序中的所有函数所共用,如果在一个函数中其值发生改变,会影响到其他函数。 • 不在必要的情况下不要使用全局变量 • 全局变量在程序执行的全部过程中都占用存储单元; • 降低了函数的通用性; • 降低程序的清晰性;

  16. 关于全局变量说明(续) • 如果在同一源程序中,外部变量与局部变量同名,则在局部变量的作用域内,外部变量被“屏蔽”,即它不起作用。 例: #include<stdio.h> int a=3;//定义外部变量a void main() { int a=8;//定义局部变量a printf("%d",a); } 程序的运行结果是8而不是3,此时外部变量被“屏蔽”

  17. 例:以下程序的输出结果是? 1!=1 2!=2 3!=6 4!=24 5!=120 #include<stdio.h> void main() { int fac(int); int i; for(i=1;i<=5;i++) printf("%d!=%d\n",i,fac(i)); } int fac(int n) { static int f=1; f*=n; return f; }

  18. #include<stdio.h> void main() { int fac(int); int i; for(i=1;i<=5;i++) printf("%d!=%d\n",i,fac(i)); } int fac(int n) { static int f=1; f*=n; return f; } • static 静态变量:静态局部变量、静态外部变量 • 静态局部变量的值在函数调用结束后不消失而保留原值,其所占用的内存单元不释放,在下一次该函数被调用时,该变量的值是上一次函数调用结束时的值; • 对于静态局部变量,如果定义时不赋初值,则编译时系统自动赋初值为0; • 虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用; • 静态存储变量长期占用内存,易浪费资源,且降低了程序的可读性,若非必要,不易多用! • 说明: • 自己阅读谭版教材P188~197

  19. 作业 • 结合第7、8讲课件阅读谭浩强版教材:8.1~8.6节,教材第3章、第5章。 (重点掌握) • 阅读教材谭浩强版教材8.8~8.9节。(了解、掌握变量的作用域和存储类别)

More Related