谭浩强C语言教程 函数课件_第1页
谭浩强C语言教程 函数课件_第2页
谭浩强C语言教程 函数课件_第3页
谭浩强C语言教程 函数课件_第4页
谭浩强C语言教程 函数课件_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

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

文档简介

第五章函数本章目标1.进一步理解多个函数构成一个C程序2.进一步了解和熟悉库函数3.学会编写自已的函数4.理解函数的调用关系5.理解函数中参数的传递机制一、C程序模块一个C程序可由一个main()函数和多个其它函数构成。§5.1C程序模块其它函数指的是:系统函数由系统提供,放在头文件中自编函数由程序设计人员编写所有的函数都具有两种特征:返回值参数(返回值和参数都是可缺省的)§5.2库函数一、库函数简介系统自带的标标准库函数根据不同的功能作用放在不同的头文件中。如:stdio.h用于标准输入/输出math.h用于数学计算ctype.h用于字符处理string.h用于字串处理time.h用于时间/日期的处理dir.h用于控制目录和路径graphics.h用于图形操作dos.hbios.h用于接口处理二、库函数的作用使程序更具有“独立性”和“可移植”性。使用时只需在程序的开头加上一条语句:#include<.h>“”根据使用的函数来确定使程序具有“模块化”。例:函数的结构main(){printstar();print_message();printstar();}printstar(){printf(“********************************”);}print_message(){printf(“howdoyoudo!\n”);}§5.3自定义函数一、自定义函数的作用使程序具有“积木”功能。(模块化)使程序具有“重构”功能。1、函数的返回值是通过函数中的return语句来完成的,return语句一次只能返回一个值;2、由return语句返回的数据类型应与函数定义时的类型一致。例:3、当在函数的定义时,未指出函数的类型,c语言默认的类型为整型.4、函数没有return语句并不表明函数没有返回值,只是这个返回值对于调用者来说可能是没有用的,这个返回值随函数的不同它的值也不尽相同.5、如果我们明确表示函数不能返回值,在函数的定义时用“void”加以说明,这样可以确保函数不带回返回值.returnz等价return(z)return(x>y?x:y);6、例:函数的返回值例:对函数返回值的理解:main(){inta,b,c;a=printstar();b=print_message();c=printstar();printf(“%d,%d,%d\n”,a,b,c);}若不需要函数带回任何值,可使用:voidprintstar(){…}voidprint_message(){…}例:函数返回值的类型与其定义的类型不符时:main(){floata,b;intc;scanf(“%f,%f”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}max(floatx,floaty)输入:1.5,2.5{floatz;输出:maxis2z=x>y?x:y;return(z);}/*return(x>y?x:y)等价*/函数的一般调用1、函数调用的一般形式:函数名(实参表列);如:add(intx,inty)的调用为add(2,3)2、函数调用的规则:实参与形参在个数与类型上必须保持一致。当函数无参数时,实参表列就为空,但括号不能少。实参表列中的各个参数之间用逗号隔开。实参与形参是一一对应的关系(函数调用的过程)。对于实参表的求值顺序各个系统是不一致的。1.函数语句:功能:将函数调用作为一个语句。如:printf(“book”);要点:不要求函数带回值,只要求完成一定的操作。2.函数表达式:功能:将函数作为表达式的一部分。如:c=2*max(a,b);要点:要求函数带回一个确定的值,以参加表达式的运算。3.一个函数作为另一个函数的参数:功能:将函数的调用作为一个函数的实参。如:m=max(a,max(b,c));要点:其实质也是函数表达式的调用。函数调用的方式例1:求二个数中的最大值

intmax(x,y)intx,y;{intz;

z=x>y?x:y;return(z);}用return语句,返回函数的值。或:intmax(intx,inty)

{intz;

z=x>y?x:y;return(z);}四、举例通过函数调用求二个数中的最大值:#include<stdio.h>intmax(int,int);/*函数原型*/main(){inta,b,t;scanf("%d%d",&a,&b);t=max(a,b);/*函数调用*/printf("valueofmaximizeis:t=%d",t);}intmax(intx,inty)/*函数定义*/{intz;z=x>y?x:y;return(z);}#include<stdio.h>

floatadd(floatx,floaty);/*函数定义*/

{floatz;

z=x+y;

returnz;

}

main()

{ floata,b,c;

scanf(“%f,%f”,&a,&b);

c=add(a,b);/*函数调用*/

printf("sum=%f";c);}求二实数之和(将例1程序改写如下:)第五章函数1.形参与实参调用时:实参值单向传递形参。

函数被调用时,临时分配单元给形参,调用完毕,这些单元被释放。实参:

出现在调用函数中,形参:出现被调用函数中。五、自定义函数中的几个重要特征2.函数返回或return变量的值;通过return语句将流程返回主调函数。return;函数无返回值return表达式的值;3.函数名要选择一个简洁的有意义的名字作为函数名。从函数名可以反映出函数的功能。六、传值调用和传引用(传址)调用1.传值调用方式:函数的实参和形参的类型均为简单变量。当实参传递形参时系统会建立一份实参的拷贝给形参。当函数调用完毕,这份实参的拷贝消失。特点:传值调用不会影响实参的值。2.传引用(传址)调用把实参形参后传递形参变量和实参变量共同内存地址。地址传递:数组名和指针(共用内存单元)特点:形参变量的值的变化会影响实参的值的改变。§5.4函数的存储类型一、标识符的属性一个标识符的属性除了前面已讲过的基本属性外,还具有一些其它的属性:存储类别存储期函数中的变量1、按作用域分局部变量:在本函数内部有效

全局变量:从定义位置到源程序结束均有效2、按存储类型分静态存储变量:程序运行时有固定的存储空间,结束时释放内存单元动态存储变量:根据需要动态分配和释放内存单元举例说明二、存储类别1.存储类型和存储期自动型(auto)寄存器型(register)外部型(extern)静态型(static)自动存储期静态存储期2.存储期的性质自动存储:只有变量才具有自动存储期如函数中的变量说明:[auto]floatx,y;[auto]intm,n;作用:进入到函数块中,该变量存在,退出函数块后该变量消失。程序中大部分变量都具有自动存储期。静态存储:可用于变量和函数如:staticint;作用:从程序开始执行起就一直存在,始终占据内存单元,直到程序结束运行。对静态存储变量,若定义时赋初值,则程序运行中仅在第一次调用时赋初值,下一次调用不再赋初值,而是使用上一次调用的值。特别提醒:对静态存储变量,若定义时不赋初值,则系统置初值0,而动态变量不赋初值则值不确定。#include<stdio.h>

intfac(n)/*函数定义*/

intn;

{staticintf=1;

f=fn;

return(f);

}

main()

{inti;

for(i=1;i<=5;i++)

printf("%d!=%d\n",i,fac(i));

}例:求n!第五章函数1!=12!=23!=64!=245!=120每一次调用fac(i),打印一个i!,同时保留这个i!的值以便下次再乘(i+1)。运行结果为:§5.5标识符的作用域标识符可以具有四种作用域。函数作用域文件作用域块作用域函数原型作用域(作用域:有效范围)可根据标识符的作用域区分局部变量和全局变量。一、局部变量凡在函数(含main函数)内部定义的变量称为局部变量。局部性:局部变量仅在函数内部有效。2.形参为局部变量。3.在复合语句中可定义仅在复合语句中有效的临时变量。1.不同的函数可有同名同类型的变量,它们占不同的内存单元,互不影响。二、全局变量一个源文件中,在所有函数之外定义的变量为全局变量。有效性:自定义位置开始至文件结尾全部有效。例:intp=1,q=5;floatf1(a)inta;{intb,c;

}

charc1,c2;p,q的作用范围c1,c2的作用范围charf2(x,y);intx,y;{inti,j;

}

main(){

}第五章函数1.全局变量所作用到的函数,相当于这些函数的公共变量。当一个函数对其值进行改变后,另一个函数使用该变量的值亦相应改变。好处:函数之间值传递。2.不要随意使用全局变量。一是始终占据内存单元;二是由于函数依赖于外部定义的变量,减少了通用性。注意3.

不在作用域内函数。若使用全局(外部)变量,需在函数体内加上extern保留字。4.

全局和局部变量同名时,局部变量有效。

局部变量1、含义:在一个函数内部定义的变量,其作用范围为函数体内部。2、应用3、使用要点:(1)主函数中定义的变量也只在主函数中有效;(2)不同的函数中可以使用相同的函数名,它们代表不同的含义;(3)形参也是局部变量;(4)在一个函数内部可以使用复合语句来定义变量,这样的变量只在本复合语句中有效.intmax(inta,intb){intt;…..}fun(){inti;..}main(){intm,n;…}m,n有效a,b,t有效i有效局部变量---内部变量定义:在函数内定义,只在本函数内有效说明:main中定义的变量只在main中有效不同函数中同名变量,占不同内存单元形参属于局部变量可定义在复合语句中有效的变量局部变量可用存储类型:autoregisterstatic

(默认为auto)floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效例不同函数中同名变量main(){inta,b;a=3;b=4;printf("main:a=%d,b=%d\n",a,b);sub();printf("main:a=%d,b=%d\n",a,b);}sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}例不同函数中同名变量main(){inta,b;a=3;b=4;printf("main:a=%d,b=%d\n",a,b);sub();printf("main:a=%d,b=%d\n",a,b);}sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4局部变量与全局变量

/*ch7_17.c*/inta=3,b=5;max(inta,intb){intc;c=a>b?a:b;return(c);}main(){inta=8;printf("max=%d",max(a,b));}运行结果:max=8例外部变量与局部变量全局变量1、含义:在所有的函数之外定义的变量称为外部变量(或叫做全局变量).其作用范围是从变量定义的位置开始,直到本源文件的结束。如:2、要点:3、举例:intp=1,q=1;/*定义全局变量p,q*/floatf1(a)/*定义函数f1*/inta;{intb,c;…}charc1,c2;/*定义外部变量c1,c2*/charf2(intx,inty)/*定义函数f2*/{inti,j;…}main()

{intm,n;…}全局变量p,q的有效范围全局变量c1,c2的有效范围(1)一个源文件可以包含一个或几个函数.(2)全局变量可以被本源文件的所有函数共享.(3)全局变量的设置增强了函数间数据的联系.一个函数对全局变量的值的改变将会影响到其他的函数中.例:(用于返回多个函数值)(4)建议在只有必要时才设置全局变量.(5)全局变量在文件的开头定义,则它的有效范围是整个源文件,但如果全局变量不是在开头定义的,则它有效范围是从定义点到源文件的结束.如果想在全局变量的定义点之前引用时,需要用关键字“extern”作提前引用说明.(6)当全局变量名与局部变量名相同时,则在局部变量的有效范围内全局变量不起作用.例:写一个函数,找出100-200之间的全部素数。#include“stdio.h”#include“math.h”intisprime(intd);{inti,s;s=sqrt(d);for(i=2;i<=s;i++)if(d%i==0)return0;return1;}main(){intm,n=0;for(m=100;m<=200;m++){if(isprime(m)){if(n%10==0)printf(“\n”);n++;printf(“%d”,m);}}}例:有一个一维数组,内放10个学生成绩,写一个函数,求出平均分、最高分和最低分。略floatmax=0,min=0;main()floataverage(array,n){floatave,score[10];floatarray[];intn;inti;{inti;for(i=0;i<10;i++)floataver,sum=array[0];scanf(“%f”,&score[i]);max=min=array[0];ave=average(score,10);for(i=0;i<n;i++)printf(“%6.2f,%6.2f,%6.2f\n”,{if(array[i]>max)max=array[i];max,min,ave);}elseif(array[i]<min)min=array[i];sum=sum+array[i];}aver=sum/n;return(aver);}例:分析下面的程序写出结果.plus(intx,inty){intz;z=x+y++;returnz;}mian()

{externinta,b;intz;z=plus(a,b);printf(“%d\n”,z);}inta=13,b=-8,z=10;运行结果;5例:分析下面的程序写出结果f1(intx,inty){intz;returnz=x>y?x:y;returnz;}f2(intx,inty){intz;z=x>y?++x:++y;returnz;}main()

{externinta,b;printf(“%d,%d,%d\n”,a,b,f1(a,b));printf(“%d,%d,%d\n”,a,b,f2(a,b));}inta=20,b=-15;20,-15,20//20,-15,21

例输入长方体的长(l)、宽(w)、高(h),求长方体体积及正、侧、顶三个面的面积。/*功能:利用全局变量计算长方体的体积及三个面的面积*/ints1,s2,s3;intvs(inta,intb,intc){intv; v=a*b*c;s1=a*b;s2=b*c;s3=a*c; returnv;}main(){intv,l,w,h;clrscr();printf("\ninputlength,widthandheight:");scanf("%d%d%d",&l,&w,&h);v=vs(l,w,h);printf("v=%ds1=%ds2=%ds3=%d\n",v,s1,s2,s3);getch();} [程序演示]#include<stdio.h>inti=1;main(){staticinta;

registerintb=-10;

intc=0;printf("-----MAIN------\n");printf("i:%da:%d\b:%dc:%d\n",i,a,b,c);c=c+8;other();printf("-----MAIN------\n");printf("i:%da:%d\b:%dc:%d\n",i,a,b,c);i=i+10;

other();}other(){staticinta=2;staticintb;

intc=10;a=a+2;i=i+32;c=c+5;printf("-----OTHER------\n");printf("i:%da:%d\b:%dc:%d\n",i,a,b,c);b=a;}-------Main------i:1a:0b:-10c:0------Other------i:33a:4b:0c:15-------Main-----i:33a:0b:-10c:8-------Other-------i:75a:6b:4c:15全局i1main:a0b:-10registermain:c0静态存储区动态存储区other:a2other:b0other:c10843315443other:c10675156例变量的寿命与可见性

例:f(a)inta;{autointb=0;staticintc=3;b+=1;c+=1;return(a+b+c);}main(){inta=2,i;for(i=0;i<3;i++)printf(“%3d”,f(a));}运行结果:7 8 9例:intfac(intn){registerinti,f=1;for(i=1;i<=n;i++)f=f*i;returnf;}main(){inti;for(i=1;i<=5;i++)printf(“%d!=%d\n”,i,fac(i));}结果:1!=12!=23!=64!=245!=1201、含义:所谓函数的嵌套调用是指一个函数在被调用时其本身又调用了其他函数.2、嵌套调用的过程:main()a函数b函数调用a函数调用b函数结束3、举例:函数的嵌套调用例7:函数的嵌套调用swap(inta,intb){intt;t=a,a=b,b=t;

printf(“%d,%d”,a,b);}//嵌套调用main(){inta=3,b=5;swap(a,b);//调用printf(“%d,%d”,a,b);}#include<stdio.h>

intdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);

d=dif(a,b,c);printf("Max-Min=%d\n",d);}intdif(intx,inty,intz){returnmax(x,y,z)-min(x,y,z);}intmax(intx,inty,intz){intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz){intr;r=x<y?x:y;return(r<z?r:z);}main()调用函数dif输出结束dif函数max函数调用函数max调用函数minmin函数例求三个数中最大数和最小数的差值§5.6递归调用一、递归的特点一个问题能够成为递归必须具备的条件是:后一部分与原始问题类似后一部分是原始问题的简化1.直接递归调用:函数直接调用本身二、程序中的递归方式2.间接递归调用:函数间接调用本身直接调用:intf(x)intx;{inty,z;

:

z=f(z);:}间接调用:intf1(x)intx;{inty,z;

:z=f2(y);:}intf2(t)intt;{inta,b;

:a=f1(b);:}以下表示了递归的概念.显然:上述例子会无限递归(无限执行)。所以,在递归调用时都必须有条件限制。n!=1(n=0,1)n(n–1)!(n>1)当条件成立,调用递归,否则结束。例:求n!1.从数学上定义#include<stdio.h>

longfac(intn)/*函数定义,计算n!*/

{longf;

if(n<0)

printf("inputerror!\n");

else

if(n==0¦¦n==1)

f=1;

elsef=nfac(n–1);

return(f);

}2.程序:第五章函数main(){intn;longy;printf("inputainteger!")scanf("%d",&n);y=fac(n);/*函数调用,计算n!*/

printf("%d!=%7d",n,y);}第五章函数3.执行过程:设:

输入5(n=5)第1次调用:y=fac(5)——返回:y=5fac(4)第2次调用:y=5*4fac(3)第3次调用:y=5*4*3fac(2)第4次调用:y=5*4*3*2fac(1)第5次调用:y=5*4*3*2*1*fac(0)例:有五个人坐在一起,问第五个人有多少岁?他说比第四个人大两岁.问第四个人的岁数,他说比第三个人大两岁,问第三个人的岁数,他说比第二个人大两岁,….当问到第一个人时,他说自己10岁,请问第五个人的岁数?age(5)=age(4)+2age(4)=age(3)+2age(3)=age(3)+2age(2)=age(1)+2age(1)=10 10 (n=1) age(n-1)+2 (n>1)age(n)=递归调用的过程age(5)=age(4)+2age(4)=age(3)+2

温馨提示

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

评论

0/150

提交评论