用函数实现模块化程序设计PPT课件_第1页
用函数实现模块化程序设计PPT课件_第2页
用函数实现模块化程序设计PPT课件_第3页
用函数实现模块化程序设计PPT课件_第4页
用函数实现模块化程序设计PPT课件_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章函数,函数定义的一般形式函数参数和函数的值函数的调用函数的嵌套调用函数的递归调用数组作为函数参数局部变量和全局变量变量的存储类别内部函数和外部函数,.,2,概述,函数是源程序的基本模块,通过对函数模块的调用实现特定的功能。一个C程序可由一个主函数和若干函数构成,由主函数调用其他函数,其他函数也可以互相调用。从用户使用的角度看,函数可分为库函数和用户定义函数。库函数:由系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。如前面反复用到的printf、scanf、getchar、putchar、gets、puts、strcat等函数均属此类。用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。,.,3,由于采用了函数模块式的结构,语言易于实现结构化程序设计。使程序的层次结构清晰,便于程序的编写、阅读、调试。,#includeintmain()/*主函数*/intmax(intx,inty);/*函数原型声明*/inta,b,c;scanf(“%d,%d”,/*将z的值返回*/,用户定义函数-举例,在程序中,一个函数的定义可以放在任意位置,既可放在主函数main之前,也可放在main之后。,.,4,概述,从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。#includeintmain()voidprintstar();/*函数原型声明*/voidprint_message();/*函数原型声明*/printstar();/*函数调用*/print_message();/*函数调用*/printstar();/*函数调用*/return0;voidprintstar()/*函数定义*/printf(*n);voidprint_message()/*函数定义*/printf(Howdoyoudo!n);,.,5,函数定义的一般形式,类型标识符函数名(形式参数表列)声明部分语句有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔。在进行函数调用时,主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明。例:intmax(intx,inty,intz)intt;t=xy?x:y;t=zt?z:t;returnt;,.,6,形式参数和实际参数,函数的参数分为形参和实参两种。形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用。形参和实参的功能是作数据传送。发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。,#includeintmain()intmax(intx,inty);inta,b,c;scanf(“%d,%d”,.,7,形式参数和实际参数,函数的形参和实参具有以下特点:1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。3.实参和形参在数量上,类型上,顺序上应严格一致,否则会发生“类型不匹配”的错误。4.函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。,.,8,例:用函数交换两个变量的值。#includeintmain()voidswap(intx,inty);inta,b;a=5;b=10;/*说明两个变量并赋初值*/printf(beforeswapa=%d,b=%dn,a,b);swap(a,b);/*用变量a和b作为实际参数调用函数*/printf(afterswapa=%d,b=%dn,a,b);return0;voidswap(intx,inty)/*借助临时变量交换两个形参变量的值*/inttemp;temp=x;x=y;y=temp;printf(inswapx=%d,y=%dn,x,y);,函数间参数传递,输出:beforeswapa=5,b=10inswapx=10,y=5afterswapa=5,b=10,.,9,函数的返回值,函数的值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。函数的值只能通过return语句返回主调函数。return语句的一般形式为:return表达式;或者为:return(表达式);该语句的功能是计算表达式的值,并返回给主调函数。在函数中允许有多个return语句,但每次调用只能有一个return语句被执行,因此只能返回一个函数值。例如,定义一个函数,用于求两个数中的大数,可写为:intmax(inta,intb)if(ab)returna;elsereturnb;,.,10,函数的返回值,如函数值为整型,在函数定义时可以省去类型说明符int。不返回函数值的函数,可以明确定义为“空类型”,类型说明符为“void”。一旦函数被定义为空类型后,就不能在主调函数中使用被调函数的函数值了。例:voidprintstar()printf(“*”);如果在主调函数中写下述语句n=printstar();就是错误的。而只能写成:printstar();为了使程序有良好的可读性并减少出错,凡不要求返回值的函数都应定义为空类型。,.,11,函数调用,语言中,函数调用的一般形式为:函数名(实际参数表)在语言中,可以用以下几种方式调用函数:1、函数语句把函数调用作为一个语句,例如:printstar();这时不要求函数带回值,只要求函数完成一定的操作。2、函数表达式函数出现在一个表达式中,例如:c+2*max(a,b);这时要求函数带回一个确定的值以参加表达式的运算。3、函数参数函数调用作为一个函数的参数,实质上也是函数表达式调用,例如:m=max(a,max(b,c),.,12,例:用函数fact计算m阶乘。#includeintmain()intm,n;intfact(intx);scanf(%d,函数执行过程,main()n=fact(m);,fact(x)return(y);,调用,返回,函数举例,.,13,例:计算:C(m,n)=m!/(n!*(m-n)!)#includeintmain()intcmn,m,n;intfact(int);/说明函数fact的类型scanf(%d%d,函数举例,.,14,函数举例,例:编写一个求幂的函数power(m,n),用于计算整数m的n次幂,其中n是正整数。#includeintmain()intpower(int,int);/*函数原型声明*/inti;for(i=0;i1时intmain()intfact(intn);intn,p;scanf(%d,函数的递归调用,在一个程序中,若存在函数自己调用自己的现象就是构成了递归。,.,19,例:求菲波那奇序列:1,1,2,3,5,8,13,21,建立问题的递归定义:f(n)=1当n=1或n=2时f(n)=f(n-1)+f(n-2)当n2时程序:#includeintmain()inti,f(int);for(i=1;i1)个圆盘的汉诺塔,将N个圆盘分为两部分:上面的N-1个圆盘和最下面的N号圆盘。将“上面的N-1个圆盘”看成一个整体。第三步,为解决N个圆盘的汉诺塔,可按如下方式进行操作:,将A杆上面的N-1个盘子,借助C杆,移到B杆上;将A杆上剩下的第N号盘子移到C杆上;将B杆上的N-1个盘子,借助A杆,移到C杆上。,函数的递归调用,.,24,voidmove(charx,chary)printf(“%c%cn”,x,y);voidhanoi(intn,charone,chartwo,charthree)/*将n个盘从one杆借助two杆,移到three杆*/if(n=1)move(one,three);elsehanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three);intmain()intm;printf(“inputthenumber:”);scanf(“%d”,函数的递归调用,.,25,例:将一个一维数组中的素数输出。#include#includevoidmain()intsushu(intn);inti,a10=11,22,67,35,89,17,43,48,99,76;for(i=0;i10;i+)if(sushu(ai)printf(“%disasushu!n”,ai);intsushu(intn)intflag=1,i;for(i=2;i=(int)sqrt(n);i+)if(n%i=0)flag=0;break;return(flag);,数组作函数参数数组元素,实现单向的值传递,.,26,例:求给定一维数组a中各元素的平均值。intmain()floataverage(float,int);floata10=1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9;printf(Theaveragearrayis%fn,average(a,10);return0;floataverage(floatx,intn)/*n为a中元素的个数*/inti;floatsum=0;for(i=0;in;i+)/*求数组a中n个元素的累加和*/sum+=xi;return(sum/n);/*返回平均值*/,在被调用函数中可以通过下标正常使用数组,数组名作函数参数-一维数组,实现双向的地址传递,.,27,例:编写一个函数,用选择法对数组中10个整数按由小到大排序。voidsort(intarray,intn)inti,j,k,t;for(i=0;in-1;i+)/*选择排序法*/k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;t=arrayk;arrayk=arrayi;arrayi=t;voidmain()inta10,i;printf(“enterthearrayn”);for(i=0;iy?x:y;return(z);intmain()externA,B;/*声明外部变量*/printf(“%d”,max(A,B);return0;intA=13,B=-8;/*定义外部变量*/,外部变量的声明,.,36,2.在不同的文件中使用外部变量和函数当外部变量的定义与使用在不同的文件中,若一个文件要使用在另一个文件中定义的外部变量,就必须在使用该外部变量之前,使用“extern”存储类型说明符进行变量“外部”说明。extern仅仅是说明变量是“外部的”,以及它的类型,并不真正分配存储空间。在将若干个文件连接生成一个完整的可执行程序时,系统会将不同文件中使用的同一外部变量连在一起,使用同一个系统分配的存储单元。当被调用的函数在另一个文件中时,在调用该函数时,无论被调用的函数是什么类型,都必须用extern说明符说明被调用函数是“外部函数”。,外部变量的声明,.,37,例:下列程序由两个文件组成,请分析运行结果。/*文件一*/intx=10;inty=10;/*定义外部变量x和y*/voidadd()y=10+x;x*=2;voidmain()externvoidsub();/*说明sub是void型的外部函数*/x+=5;add();sub();/*分别调用函数*/printf(x=%d;y=%dn,x,y);/*文件二*/voidsub()/*函数sub定义在另一个文件中*/externintx;/*说明在另一个文件中的外部变量x*/x-=5;,外部变量的声明,.,38,intf(inta)autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);intmain()inta=2,i;for(i=0;i3;i+)printf(%d,f(a);return0;,例:观察静态局部变量与自动变量的值。,静态变量静态局部变量、静态外部变量,intfac(intn)staticintf=1;f=f*n;return(f);intmain()inti;for(i=1;i=5;i+)printf(%d!=%dn,i,fac(i);return0;,.,39,对静态局部变量的说明:静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储空间,函数调用结束后即释放。静态局部变量在编译时赋初值,即只赋初值一次;而对自动变量赋初值是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论