C语言课件第八章_第1页
C语言课件第八章_第2页
C语言课件第八章_第3页
C语言课件第八章_第4页
C语言课件第八章_第5页
已阅读5页,还剩70页未读 继续免费阅读

下载本文档

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

文档简介

教学目与要求:明确C程序由一个或多个函数构成,掌握函数的定义方法,熟悉函数的传值调用,嵌套调用,递归调用的执行过程;掌握变量的类型,作用域,生存期等概念,正确使用动态变量,静态变量。教学内容:概述;函数定义的一般形式;函数的参数和函数的值;函数的调用;函数的嵌套调用;函数的递归调用;数组作为函数参数;局部变量和全局变量;变量的存储类别;内部函数和外部函数;如何运行一个多文件的程序。教学重点与难点:重点是函数的定义和调用,变量的作用域和生存期难点是函数的嵌套调用与递归调用。,Ch8函数,特点:各模块相对独立、功能单一、结构清晰、接口简单控制了程序设计的复杂性缩短开发周期避免程序开发的重复劳动易于维护和功能扩充,8.1概述,C是模块化程序设计语言基本思想:将一个大的程序按功能分割成一些小模块,开发方法:自上向下,逐步细化,一个C程序由一个或多个程序模块组成,每个程序模块作为一个源程序文件C是函数式语言,一个源程序文件由一个或多个函数以及其他有关内容组成.一个C程序必须有且只能有一个名为main的主函数C程序的执行总是从main函数开始,main函数结束时结束函数不能嵌套定义,可以嵌套调用,但不能调用main函数.所有子函数都是平行的,任何函数都不属于其他函数,C是模块化程序设计语言,C程序结构,函数分类从用户角度标准函数(库函数):由系统提供用户自定义函数从函数形式无参函数有参函数,使用库函数应注意:1、函数功能2、函数参数的数目和顺序,及各参数意义和类型3、函数返回值意义和类型4、需要使用的包含文件,8.2函数定义的一般格式,合法标识符,函数返回值类型缺省int型无返回值void,函数体,类型标识符函数名()说明部分语句部分,例无参函数printstar()printf(“*n”);或printstar(void)printf(“*n”);,8.2.1无参函数定义的一般格式,8.2.2有参函数定义的一般格式,合法标识符,函数返回值类型缺省int型无返回值void,函数体,类型标识符函数名(形参类型说明表)说明部分语句部分,例有参函数intmax(intx,inty)intz;z=xy?x:y;return(z);,例有参函数(传统风格)intmax(x,y)intx,y;intz;z=xy?x:y;return(z);,8.2.3空函数,void函数名(),作用:在程序设计中往往根据需要确定若干模块,分别由一些函数实现,而在第一阶段中设计最基本的模块,其他一些次要功能或锦上添花的功能则在以后需要时陆续补上,在编写程序的开始阶段,可以在将来要扩充的地方写一个空函数.,8.3.1形参与实参形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数时函数名后面括号中的参数,例比较两个数并输出大者,max(intx,inty)intz;z=xy?x:y;return(z);main()inta,b,c;scanf(%d,%d,8.3函数参数和函数的值,说明:形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放实参可为常量,变量或表达式,但必须有确定的值,调用时实参的值传给形参.形参必须指定类型形参与实参类型一致,个数相同若形参与实参类型不一致,自动按形参类型转换函数调用转换实参到形参是单向的值传递反过来不行.,例计算x的立方,#includefloatcube(floatx)return(x*x*x);main()floata,product;printf(Pleaseinputvalueofa:);scanf(%f,x,1.2,1.2,1.728,返回语句形式:return(表达式);或return表达式;或return;功能:使程序控制从被调用函数返回到调用函数中,同时把返回值带给调用函数说明:函数中可有多个return语句若无return语句,遇时,自动返回调用函数,返回的是一个不确定的值若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换void型函数没有返回值,例无返回值函数voidswap(intx,inty)inttemp;temp=x;x=y;y=temp;,8.3.2函数的返回值,printstar()printf(*);main()inta;a=printstar();printf(%d,a);,例:下列函数的不同。,voidprintstar()printf(*);main()inta;a=printstar();printf(%d,a);,*10,编译错误notanallowedtype,例:函数返回值类型转换,max(floatx,floaty)floatz;z=xy?x:y;return(z);main()floata,b;intc;scanf(%f%f,教学目与要求:熟悉函数的传值调用嵌套调用递归调用的执行过程;教学内容:函数的嵌套调用;函数的递归调用;数组作为函数参数;教学重点与难点:函数的嵌套调用与递归调用。,Ch8函数(2),8.4函数的调用8.4.1调用的一般形式函数名(实参表列);说明:实参与形参个数相等,类型一致,按顺序一一对应实参表求值顺序,因系统而定(TurboC自右向左),8.4.2调用方式函数语句:例printstar();printf(“Hello,World!n”);函数表达式:例m=max(a,b)*2;函数参数:例printf(“%d”,max(a,b);m=max(a,max(b,c);,intf(inta,intb)intc;if(ab)c=1;elseif(a=b)c=0;elsec=-1;return(c);voidmain()inti=2,p;p=f(i,+i);printf(%d,p);,例参数求值顺序,intf(inta,intb)intc;if(ab)c=1;elseif(a=b)c=0;elsec=-1;return(c);voidmain()inti=2,p;p=f(i,i+);printf(%d,p);,运行结果:0,TC运行结果:1VC:0,对被调用函数要求:必须是已存在的函数库函数应该使用#include用户自定义函数或者在调用前面,或者先有函数类型说明告诉编译系统函数类型、参数个数及类型,以便检验函数定义与函数声明不同函数定义是指函数功能的确立,包括函数名、值、形参以及函数体,是一个完整的、独立的函数单位。函数声明告诉编译系统函数类型、参数个数及类型,以便检验,8.4.3对被调用函数的声明和函数原型,例函数声明举例,/*ch8-4.c*/voidmain()floatadd(floatx,floaty);floata,b,c;scanf(%f,%f,8.4.3对被调用函数的声明和函数原型函数的声明简称函数原型.一般情况下,函数的声明与函数定义的第一行(函数首部)基本相同,但差一个分号,因此,可以简单地照写已经定义的函数的首部,再加一个分号,就成了声明。函数原型的形式(1)函数类型函数名(形参类型1,形参类型2,.形参类型n);(2)函数类型函数名(形参类型1参数名1,形参类型2参数名2,.,形参类型n参数名n);编译系统不检查参数名,参数名是什么无所谓函数说明位置:程序的数据说明部分(函数内或外)下列情况下,可不作函数说明被调用函数定义出现在主调函数之前如果已经在头文件的开头(在所有函数之前)已经对本文件中所调用的函数进行了声明,则在各函数中不必再说明。若函数返值是char或int型,系统自动按int型处理,intsum(inta,intb)a=a+b;b=a+b;return(a);voidmain()inta=1,b=3,c;c=sum(a,b);printf(%d,%d,%d,a,b,c);,例读程序写出程序结果。,1,3,4,voidmain()floatadd(floata,floatb);floata,b,c;scanf(%f,%f,8.5函数的嵌套调用,嵌套调用C规定:函数定义不可嵌套,但可以嵌套调用函数,即在调用一个函数的过程中又调用另一个函数。,例求三个数中最大数和最小数的差值,#includeintdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);voidmain()inta,b,c,d;scanf(%d%d%d,intdif(intx,inty,intz)returnmax(x,y,z)-min(x,y,z);intmax(intx,inty,intz)intr;r=xy?x:y;return(rz?r:z);intmin(intx,inty,intz)intr;r=xy?x:y;return(rz?r:z);,floatfac(intk)floatt=1;inti;for(i=2;i=k;i+)t*=i;returnt;voidmain()floatc;intm,n;scanf(“%d,%d”,例求,分析:重复三次求阶乘运算,只是每次的值不同。将求阶乘的过程编成一个函数,以不同的参数值来调用函数。,说明:C编译系统对递归函数的自调用次数没有限制每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,8.6函数的递归调用定义:函数直接或间接的调用自身叫函数的递归调用,intf(intx)inty,z;z=f(y);.return(2*z);,此两种递归都无法结束,应有某种条件控制递归调用结束。,例8.8,intage(intn)intc;if(n=1)c=10;elsec=age(n-1)+2;return(c);voidmain()printf(“%dn”,age(5);,例8.8求n的阶乘,/*ch8_8.c*/#includefloatfac(intn)floatf;if(n0)printf(ny?x:y);voidmain()inta10,i,m;for(i=0;i10;i+)scanf(“%d”,若函数的形参是数组,对应的实参必须是数组名或指针变量。,intmax(intx10)inti,m=x0;for(i=1;i10;i+)if(mxi)m=xi;returnm;voidmain()inta10,i;for(i=0;i10;i+)scanf(“%d”,说明:应该在主调函数和被调函数中分别定义数组,不能只在一方定义.实参数组与形参数组的类型必须一致用数组名做参数时,传递的是数组的首地址,形参数组的大小不起作用.形参数组可以不指定大小,只用一个方括号,可另设一参数,传递数组元素的个数数组做函数参数时,形参数组和实参数组共享同一内存单位,例求10个任意整数中的最大值,8.7.2数组名作函数参数地址传递,intmax(intx,intn)inti,m=x0;for(i=1;in;i+)if(mxi)m=xi;returnm;voidmain()inta10,i;for(i=0;i10;i+)scanf(“%d”,例求学生的平均成绩,#includefloataverage(intstu10,intn);voidmain()intscore10,i;floatav;printf(Input10scores:n);for(i=0;i10;i+)scanf(%d,floataverage(intstu10,intn)inti;floatav,total=0;for(i=0;in;i+)total+=stui;av=total/n;returnav;,实参用数组名,形参用数组定义,intstu,数组排序-简单选择排序,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;if(k!=i)t=arrayi;arrayi=arrayk;arrayk=t;,voidmain()voidsort(intarray,intn);inta10,i;for(i=0;i10;i+)scanf(%d,9,49,i=0,例数组排序-简单选择排序,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;if(k!=i)t=arrayi;arrayi=arrayk;arrayk=t;,main()voidsort(intarray,intn);inta10,i;for(i=0;i10;i+)scanf(%d,13,68,i=1,例数组元素与数组名作函数参数比较,#includevoidswap2(intx,inty)intz;z=x;x=y;y=z;main()inta2=1,2;swap2(a0,a1);printf(a0=%dna1=%dn,a0,a1);,值传递,#includevoidswap2(intx)intz;z=x0;x0=x1;x1=z;main()inta2=1,2;swap2(a);printf(a0=%dna1=%dn,a0,a1);,地址传递,例数组元素与数组名作函数参数比较,8.7.1数组元素作函数实参值传递,8.7数组作为函数参数,8.7.2一维数组作函数参数地址传递,intmax(intx4)inti,j,m=x00;for(i=0;i3;i+)for(j=0;j4;j+)if(mxij)m=xij;returnm;voidmain()inta34=1,3,5,7,9,2,4,6,8,10,15,13,17,5;printf(“max=%d”,max(a);,1.多数数组元素可以作为函数的参数2.如果形参是多维数组,可以省略第一维的大小,但不能省略其他维的大小。,8.7.3多维数组与函数参数,intmax(intx34)intmax(intx4)intmax(intx3)()intmax(intx)(),例:有一个34的矩阵,求最大元素的值。,例求二维数组中各行元素之和,get_sum_row(intx3,intresult,introw,intcol)inti,j;for(i=0;irow;i+)resulti=0;for(j=0;jcol;j+)resulti+=xij;main()inta23=3,6,9,1,4,7;intsum_row2,row=2,col=3,i;get_sum_row(a,sum_row,row,col);for(i=0;irow;i+)printf(Thesumofrow%d=%dn,i+1,sum_rowi);,18,12,8.8.1局部变量-内部变量定义:在函数内定义,只在本函数内有效说明:main中定义的变量只在main中有效不同函数中同名变量,占不同内存单元形参属于局部变量在一个函数内,可定义在复合语句中有效的变量局部变量可用存储类型:autoregisterstatic(默认为auto),运行结果:54321,例:复合语句中的变量#defineN5main()inti;intaN=1,2,3,4,5;for(i=0;iN/2;i+)inttemp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;iN;i+)printf(%d,ai);,例不同函数中同名变量main()inta,b;a=3;b=4;printf(main:a=%d,b=%dn,a,b);sub();printf(main:a=%d,b=%dn,a,b);sub()inta,b;a=6;b=7;printf(sub:a=%d,b=%dn,a,b);,运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4,8.8局部变量和全局变量,8.8.2全局变量-外部变量定义:在函数外定义,可为本文件所有函数共用有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件,应尽量少使用全局变量,因为:全局变量在程序全部执行过程中占用存储单元降低了函数的通用性、可靠性,可移植性降低程序清晰性,容易出错,定义说明次数:只能1次可说明多次位置:所有函数之外函数内或函数外分配内存:分配内存,可初始化不分配内存,不可初始化,外部变量说明:extern数据类型变量表;,外部变量定义与外部变量说明不同,若外部变量与局部变量同名,则外部变量被屏蔽,外部变量可用存储类型:缺省或static,全局变量增加了函数间数据联系的渠道,通过函数调用可得到一个以上的值,一般将全局变量名的第一个字母大写;,#includefloatMax,Min;floataverage(floatarray,intn)inti;floatsum=Max=Min=array0;for(i=1;imax)Max=arrayi;elseif(arrayib?a:b;return(c);,形参a,b作用范围,8.9变量的存储类别,编译或函数调用时为其分配内存单元,10,程序中使用变量名对内存操作,概述变量是对程序中数据的存储空间的抽象。,变量的属性数据类型:变量所持有的数据的性质(操作属性)存储属性存储器类型:寄存器、静态存储区、动态存储区作用域:变量在程序中的作用范围-局部变量与全局变量生存期:变量占用内存单元的时间-静态存储与动态存储,8.9.1动态变量与静态变量存储方式静态存储:编译时为其分配的,程序运行期间占有该固定存储空间,直到程序运行结束。动态存储:程序运行期间根据需要动态分配存储空间。内存用户区,生存期静态变量:从程序开始执行到程序结束动态变量:从包含该变量定义的函数开始执行至函数执行结束,8.9变量的存储类别,8.9.2auto-自动型函数中的局部变量(如不专门声明为static存储类别)、函数中的形参和在函数中定义的变量,在调用函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。这类局部变量称为自动变量。用关键字auto作存储类别的声明,可省略。,intf(inta)autointb,c=3;.,8.9变量的存储类别,8.9.3static-静态型有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即占有存储单元不释放,在下一次该函数调用时,该变量已有值,是上一次函数调用结束时的值。这时就应该指定局部变量为“静态局部变量”,用关键字static进行声明。,#includevoidmain()intf(int);inta=2,i;for(i=0;i3;i+)printf(%d,f(a);intf(inta)autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);,8.9变量的存储类别,789,8.9.3static-静态型的说明属于静态存储类别静态局部变量在编译时赋初值,即只赋初值一次不赋初值的话,则对静态局部变量来说,编译时自动赋初值0或空字符在函数调用结束后仍然存在,但其他函数不能引用它,#includevoidmain()inti;intfac(intn);for(i=1;i=5;i+)printf(%d!=%dn,i,fac(i);intfac(intn)staticintf=1;f=f*n;return(f);,8.9变量的存储类别,8.9.4register-存器变量为了提高效率,C语言允许将局部变量得值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register作声明。只有局部自动变量和形式参数可以作为寄存器变量;不能定义任意多个寄存器变量;局部静态变量不能定义为寄存器变量。,#includeintfac(intn)registerinti,f=1;for(i=1;ib?a:b;return(z);main()printf(max=%d,max();inta=13,b=-8;,/*ch8_17.c*/inta=3,b=5;max(inta,intb)intc;c=ab?a:b;return(c);main()inta=8;printf(max=%d,max(a,b);,例外部变量与局部变量,运行结果:max=8,inti;main()voidprt();for(i=0;i5;i+)prt();voidprt()for(i=0;i5;i+)printf(“%c”,*);printf(“n”);,例外部变量副作用,运行结果:*,例auto变量的作用域,main()intx=1;voidprt(void);intx=3;prt();printf(“2ndx=%dn”,x);printf(“1stx=%dn”,x);voidprt(void)intx=5;printf(“3thx=%dn”,x);,运行结果:3thx=52ndx=31stx=1,main()voidincrement(void);increment();increment();increment();voidincrement(void)intx=0;x+;printf(“%dn”,x);,例局部静态变量值具有可继承性,运行结果:111,main()voidincrement(void);increment();increment();increment();voidincrement(void)staticintx=0;x+;printf(“%dn”,x);,运行结果:123,例变量的寿命与可见性,inti=1;main()staticinta;registerintb=-10;intc=0;printf(-MAIN-n);printf(i:%da:%db:%dc:%dn,i,a,b,c);c=c+8;other();printf(-MAIN-n);printf(i:%da:%db:%dc:%dn,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:%db:%dc:%dn,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,8,4,33,15,4,43,6,75,15,6,main()voidgx(),gy();externintx,y;printf(“1:x=%dty=%dn”,x,y);y=246;gx();gy();voidgx()externintx,y;x=135;printf(“2:x=%dty=%dn”,x,y);intx,y;voidgy()printf(“3:x=%dty=%dn”,x,y);,例用extern扩展外部变量作用域,运行结果:1:x=0y=02:x=135y=2463:x=135y=246,例引用其它文件中的外部变量,例引用其它文件中的变量,输出ab和a的m次方,inti=1;main()/*lec9-7*/inti,j;i=reset();for(j=1;j=3;j+)printf(i=%d,j=%dn,i,j);printf(next(i)=%dn,next(i);printf(last(i)=%dn,last(i);printf(ne

温馨提示

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

评论

0/150

提交评论