C语言函数公开课一等奖省优质课大赛获奖课件_第1页
C语言函数公开课一等奖省优质课大赛获奖课件_第2页
C语言函数公开课一等奖省优质课大赛获奖课件_第3页
C语言函数公开课一等奖省优质课大赛获奖课件_第4页
C语言函数公开课一等奖省优质课大赛获奖课件_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

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

文档简介

模块化程序设计——函数孙小松10/10/11§6.1函数概念C程序结构●C程序结构如图所表示1.一个C程序能够分为若干个函数2.每个程序有且只有一个主函数(main),其它都是子函数3.子函数能够相互调用,但主函数不能被调用4.一个C源程序由一个或多个文件组成,每个文件就是一个编译单位2●说明:1.一个C程序执行从主函数(main)开始,调用其它函数后仍回到main主函数结束.2.每个子函数都是平行,任何子函数都不隶属于其它函数3.从用户角度,函数能够分为:

☆标准函数,即库函数

☆用户自定义函数4.从函数形式能够分为:☆无参函数:printstar()☆有参函数:printf(“hello”)#include<stdio.h>voidprintStar(){printf(“*******************\n”);}voidprintMessage(){printf(“Hello,world.\n”);printStar();}voidmain(){printStar();printMessage();}3函数定义普通形式●函数定义普通形式:类型说明函数名([形式参数说明]){函数体}形式参数说明方法:

数据类型变量名[,类型变量名]●无参数函数定义形式:

类型说明函数名(){函数体}voidprintHello(){printf(“hello!\n”);}●有参数函数定义形式:

类型说明函数名(形式参数说明){函数体}intsum(intx,inty){intz;z=x+y;return(z);}4●函数体普通情况下,函数体有两部分组成:

{[局部变量说明]语句;}局部变量说明:函数体内变量.其有效范围仅在本函数体内起作用,离开本函数无意义.intsum(intx,inty){intz;//局部变量定义z=x+y;return(z);}5函数参数和函数值●一个程序由若干个函数组成,各函数调用时经常要传递一些数据,即调用函数把数据传递给被调用函数,经过被调用函数处理后,得到一个确定结果,在返回调用函数时,将结果带回调用函数.#include<stdio.h>intmax(intx,inty){intz;z=(x>y)?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}主函数子函数..

c=max(a,b);..intmax(intx,inty)...return(z);a,bz各函数之间数据往来经过参数传递和返回语句实现6函数参数:用于函数间数据传递形式参数:定义函数时给出参数实际参数:调用函数时给出参数#include<stdio.h>intmax(int

x,int

y){intz;z=(x>y)?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}对于函数max有两个形式参数x,y形式参数x和y只在max函数中使用a,b是主函数中定义变量,当main函数调用max函数时.a,b成为max实际参数调用时,实际参数值赋给形参进行处理例:max接收到两个值:89max返回89一、形式参数和实际参数7#include<stdio.h>intmax(int

x,int

y){intz;z=(x>y)?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}说明:1.定义函数时,必须说明形参类型,形参只能是变量(包含数组).不能是常量或表示式2.函数被调用之前,形参和子函数中变量不占内存,调用结束返回,形参所占内存被收回.3.实参能够是常量、变量或表示式.因为传递过来是详细数值.4.实参和形参类型必须一致(或能够安全转换).5.C语言中,实参和形参传递是”按值传递”,即单向传递,只与参数相对位置相关,而与变量名无关intb,intaintc;c=(a>b)?a:b;return(c);1320main-amain-bmax-amax-b13208#include<stdio.h>intsum(inta,intb){a=a+b;b=a+b;return(a);}voidmain(){inta=1,b=3,c;c=sum(a,b);printf(“sumof%d,%dis%d\n”,a,b,c);}阅读下面程序,写出运行结果函数被调用之前,形参和子函数中变量不占内存,调用结束返回,形参所占内存被收回.实参和形参传递是”值传递”,即单向传递,只与参数相对位置相关,而与变量名无关sumof1,3is49二、函数返回值#include<stdio.h>intmax(int

x,int

y){intz;z=(x>y)?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}函数值也就是函数返回值,是一个详细确定值.①函数使用return语句返回值。②一个函数内能够有多个return语句,执行到任何return语句,函数都将马上返回到调用函数if(x>y)return(x);elsereturn(y);③return后面()能够省略,能够返回一个表示式,先求解表示式值,再返回.intmax(intx,inty){returnx>y?x:y;}1.返回函数值方法10#include<stdio.h>intmax(int

x,int

y){intz;z=(x>y)?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“maxis%d\n”,c);}2.函数值类型

①函数类型即函数值类型.比如,函数max是int型,函数返回值也是int型.②省略了类型说明函数就是int型.③return中表示式值普通和函数类型相同.④假如不一致,则需要进行类型转换.以函数类型为准.113.不需要返回函数①假如函数中没有return,认为是一个过程,能够使用类型void.②假如一个函数被申明void类型,就不允许再引用它返回值。只能单纯调用它。#include<stdio.h>voidprintStar(){printf(“*******************\n”);}voidprintMessage(){printf(“Hello,world.\n”);printStar();}voidmain(){printStar();printMessage();}12函数调用一、函数调用普通形式普通形式:

函数名(实参列表)说明:①假如调用无参函数,实参表列能够忽略,但括号不能省.②实参个数和形参个数相同.③实参和形参类型一一对应,必要时会进行类型转换.注意:不一样系统中,实参计算次序不一样.普通认为从右到左计算和赋值.普通在调用函数前计算出实参值例1读程序,写出结果#include<stdio.h>intf(inta,intb){intc;if(a>b)c=1;elseif(a==b)c=0;elsec=-1;returnc;}voidmain(){inti=2,p;p=f(i,++i);printf(“%d”,p);}13二、函数调用方式1、函数语句

形式为:函数(实参表列);比如:printMessage();printf(“%d”,p);说明:这种方式不要求函数带返回值,函数只执行一定操作.2、函数表示式

函数返回值参加运算比如:m=max(a,b);m=3*max(a,b);printf(“%d”,max(a,b));说明:这种方式函数不能用于void类型14三、函数调用执行过程①从右到左次序,计算实参中各表示式值.②按照位置,将实参值一一传递给形参.③执行被调用函数.④当碰到return(表示式)语句时,计算表示式值并返回主调函数.例2读程序,写出结果#include<stdio.h>intiabs(floatx){return(x>0?x:-x);}voidmain(){floatx=-0.6,y;y=iabs(2*x);printf(“x=%f,iabs(x)=%f\n”,x,y);}1234X=-0.600000,iabs(x)=1.00000015四、函数原形在程序中调用函数需满足以下条件:①被调用函数必须存在,且必须遵照“先定义后使用”标准②假如被调用函数定义在主调函数之后,能够在调用之前给出原形说明.原形说明:类型说明函数名(参数类型,参数类型…)16函数嵌套调用嵌套调用是指在一个函数函数体中又调用了其它函数.程序执行过程:第一层第二层第三层

main()printStar(){{printStar();……}printfMessage()printMessage();{……printStar();printStar();{……}}}结束#include<stdio.h>voidprintStar(){printf(“*******************\n”);}voidprintMessage(){printf(“Hello,world.\n”);printStar();}voidmain(){printStar();printMessage();}17例3编程求分析:重复三次不一样阶乘运算,只是每次值不一样.将求阶乘过程编程一个函数fac,以不一样参数值来调用facfackk!#include<stdio.h>#include<math.h>floatfac(intk);{floatt=1.0;inti;for(i=2;i<=k;i++)t*=i;returnt;}voidmain(){floatc;intm,n;printf(“inputm,n:”);scanf(“%d%d”,&m,&n);c=fac(n)/(fac(m)*fac(n-m));printf(“%.0f\n”,c);}18许多数学函数都是使用递归调用形式定义:函数递归调用当n=1时当n>1时当n=0时当n!=1时19函数递归调用是指在调用一个函数时又直接或间接调用函数本身.直接调用间接调用递归调用必须引入一个循环条件控制递归结束,不然进入死循环.20例4有5个人坐在一起,问第5个人多少岁?答:比第4个人大2岁;第4个人说他比第三个人大2岁;第3个人比第2个人大2岁,第2个人比第1个人大2岁.而第1个人有10岁.问第5个人多少岁?计算公式:(n=1)(n>1)回推阶段递推阶段21函数调用过程#include<stdio.h>intage(intn){intc;if(n==1)c=10;elsec=age(n-1)+2;returnc;}voidmain(){printf(“%d“,age(5));}22例5用递归调用求n!阶乘(n>=0)使用循环做:floatfac(intn){floatf=1;if(n>=0)for(i=2;i<=n;i++)f*=i;elsef=-1;returnf;}#include<stdio.h>floatfac(intn){floatf;if(n>1)f=fac(n-1)*n;elseif(n==0||n==1)f=1;elsef=-1;returnf;}voidmain(){intn;floaty;printf(“inputaintegernumber:”);scanf(“%d”,&n);y=fac(n);if(y<0)printf(“error:%d\n”,n);elseprintf(“%d!=%.0f\n”,n,y);}递归公式:(n=0,1)(n>1)23依据变量作用域不一样,可分为局部变量和全局变量两种。1.变量作用域变量作用域:变量起作用范围。①局部变量:在函数内部或某个控制块内部定义变量。局部变量作用域:函数内部。作用:增强了函数模块独立性。②全局变量:在函数外面定义变量称为全局变量。全局变量作用域:从该变量定义位置开始,直到源文件结束。作用:在同一文件中,全部函数都能够引用全局变量。增强了各函数间数据联络。§6.2变量作用域24局部变量和全局变量作用域如图所表示:25阅读程序【例6-4】程序,了解变量作用域。请注意区分局部变量和全局变量作用域。程序:example6_4.c26变量存放类别一、变量动态存放和静态存放全局变量和局部变量

变量作用域静态存放和动态存放

变量存放类别:生存期内存中供用户使用空间有:①代码区②静态存放区:编译时分配空间③动态存放区:执行时分配空间变量或函数属性:数据类型存放类型自动型auto静态型static存放器register外部型extern27二、局部变量存放类别1、自动类别存放在动态存放区,用auto说明如:intfunc1(inta){

autointb,c=3;……}形参a,变量b,c都是自动变量,调用函数时,系统给它们分配存储空间,函数调用结束时,自动释放空间.通常auto能够省略282、局部静态变量占用静态存放,用static说明说明:①局部静态变量,属于静态存放类别,在程序执行整个过程中,都不释放存放空间.②局部静态变量在编译时赋值,仅赋值一次.③假如定义局部静态变量没有赋初值,系统会自动赋初值.④局部静态变量,只有在定义它函数内被引用(它存在,但不被其它函数引用)假如f不定义成static是什么结果?f=1;j=1;fac(1):f=f*n=1*1=1;输出1!=1;j=2;fac(2):f=f*n=1*2=2;输出2!=2;j=3;fac(3):f=f*n=2*3=6;输出3!=6;j=4;fac(4):f=f*n=6*4=24;输出4!=24;293、存放器变量存放在存放器中,用register说明说明:①计算机存放器个数有限.②存放器变量对存放器占有是动态③有系统对存放器变量转化为自动变量处理,而有系统会自动设置存放器变量.30三、全局变量存放类别全局变量都存放在静态存放区。用static关键字申明全局变量,只能在本文件内使用。没有用static关键字全局变量能够在别文件中使用extern关键字申明为外部变量,并在该文件中作为全局变量使用。尽可能少使用全局变量/*a.c*/intmax;voidcalcMax(inta[],intn){......}/*main.c*/externintmax;voidmain(){...printf(“%d”,max);...}/*a.c*/staticintmax;voidcalcMax(inta[],intn){......}/*main.c*/externintmax;voidmain(){...printf(“%d”,max);...}错!max未定义错!不能引用max31四、存放类别小结1、变量定义方法[存放类别]数据类型变量名……2、变量划分按作用域划分:按生存期局部变量全局变量自动变量静态变量存放器变量形式参数变量动态存放静态存放自动变量形式参数存放器变量静态局部变量全局变量按变量存放位置动态存放区静态存放区自动变量形式参数静态局部变量全局变量存放器存放器变量32自定义函数有两种:内部函数和外部函数。1.内部函数若函数存放类型为static型,则称其为内部函数(内部函数又称为静态函数),它表示在由多个源文件组成同一个程序中,该函数只能在其所在文件中使用,在其它文件中不可使用。内部函数申明形式:

static<返回值类型><函数名>(<参数>);比如:

staticintStatistic();2.外部函数若函数存放类型定义为extern型,则称其为外部函数,它表示该函数能被其它源文件调用。函数默认存放类型为extern型。§6.3内部函数与外部函数33

外部函数应用示例。下面程序由3个文件组成:file1.c、file2.c、example6_6.c。在file1.c、file2.c中分别定义了两个外部函数;在example6_6.c中能够分别调用这两个函数。1.file1.c/*file1.c外部函数定义*/externintadd(intm,intn){return(m+n);}2.file2.c/*file2.c外部函数定义*/externintmod(inta,intb){return(a%b);}343.example6_6.c#include<stdio.h>externintmod(inta,intb); /*外部函数申明*/externintadd(intm,intn); /*外部函数申明*/main(){intx,y,result1,result2,result;printf("Pleaseenterxandy:\n");scanf("%d%d",&x,&y);result1=add(x,y); /*调用file1中外部函数*/printf("x+y=%d\n",result1);if(result1>0)

result2=mod(x,y); /*调用file2中外部函数*/result=result1-result2;printf("mod(x,y)=%d\n",result2);printf("(x+y)-mod(x,y)=%d\n",result);}35关于程序几点说明(1)在程序file1.c、file2.c中函数定义能够不需要extern加以说明,默认为外部函数。(2)在example6_6.c中对外部函数申明也能够不用extern加以说明,默认为外部函数。(3)由多个源文件组成一个程序时,main()函数只能出现在一个源文件中。(4)由多个源文件组成一个程序时,有3种连接方式:①将各源文件分别编译成目标文件,得到多个目标文件(.obj后缀),然后用连接命令把多个.obj文件连接起来。

36②建立项目文件(.prj后缀或.dsw后缀),详细操作可参阅各种C语言集成开发环境说明。③使用文件包含命令。请参阅本章6.6节。(5)假如将file1.c或file2.c中extern改成static,则主程序在编译时无法经过。(6)在程序file1.c或file2.c中,也能够相互调用其外部函数。Turboc连接接命令为tlink

比如:tlinkexample6_6.obj+file1.obj+file2.obj

结果:生成一个example6_6.exe文件。37

§6.4编译预处理作用:在对源程序编译之前做一些处理,生成扩展C源程序种类宏定义

#define文件包含

#include条件编译

#if--#else--#endif等格式:“#”开头占单独书写行语句尾不加分号38如#defineYES1#defineNO0if(x==YES)printf(“correct!\n”);elseif(x==NO)printf(“error!\n”);展开后:if(x==1)printf(“correct!\n”);elseif(x==0)printf(“error!\n”);1

宏定义不带参数宏定义普通形式#define宏名(标识符)[宏体](字符串)功效:用指定标识符(宏名)代替字符序列(宏体)宏展开:预编译时,用宏体来替换宏名---不作语法检验如#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);说明:1.定义位置:任意(普通在函数外面)2.作用域:从定义命令到文件结束3.#undef可终止宏名作用域格式:#undef宏名例#defineYES1main(){……..}#undefYES#defineYES0max(){……..}YES原作用域YES新作用域5.宏定义可嵌套,不能递归例#defineMAXMAX+10()4.引号中内容与宏名相同也不置换例#definePI3.14159printf(“2*PI=%f\n”,PI*2);宏展开:printf(“2*PI=%f\n”,3.14159*2);6.宏定义中使用必要括号()例#defineWIDTH80#defineLENGTH

WIDTH+40var=LENGTH*2;宏展开:var=80+40*2;()()例#defineWIDTH80#defineLENGTH

WIDTH+40var=LENGTH*2;宏展开:var=WIDTH+40*2var=80+40*27.只是简单替换,标识符不占内存空间8.普通宏名使用大写字母形式.39带参数宏定义普通形式:#define宏名(参数表)宏体例#defineS(r)PI*r*r相当于定义了不带参宏S,代表字符串“(r)PI*r*r”说明:1.宏展开:不但宏体替换,还要进行形参替换2.宏体及各形参外普通应加括号()3.宏名与参数之间不能有空格例#defineS(a,b)a*b………..area=S(3,2);宏展开:area=3*2;不能加空格例#definePOWER(x)x*xx=4;y=6;z=POWER(x+y);宏展开:z=x+y*x+y;普通写成:#definePOWER(x)((x)*(x))宏展开:z=((x+y)*(x+y));①②③40#defineMAX(x,y)(x)>(y)?(x):(y)…….main(){inta,b,c,d,t;…….t=MAX(a+b,c+d);……}宏展开:t=(a+b)>(c+d)?(a+b):(c+d);intmax(intx,inty){return(x>y?x:y);}main(){inta,b,c,d,t;…….t=max(a+b,c+d);………}4.用宏定义能够实现和函数一样功效<>415.带参宏与函数区分带参宏函数处理过程不分配内存简单字符置换分配内存先求实参值,再代入形参处理时间编译前程序运行时参数类型无类型问题定义实参,形参类型程序长度变长不变运行速度不占运行时间调用和返回占时间422文件包含功效:一个源文件可将另一个源文件内容全部包含进来普通形式:#include“文件名”或#include<文件名>#include“file2.c”file1.cfile2.cfile1.cBABA处理过程:预编译时,用被包含文件内容取代该预处理命令,再对“包含”后文件作一个源文件编译<>直接按标准目录搜索(存放C库函数头文件)“”先在当前目录搜索,再搜索标准目录

可指定路径43被包含文件内容源文件(*.c)头文件(*.h)宏定义数据结构定义函数说明等文件包含可嵌套#include“file2.c”file1.cAfile3.cC#include“file3.c”file2.cBfile1.cAfile3.cfile2.c44例文件包含举例/*powers.h*/#definesqr(x)((x)*(x))#definecube(x)((x)*(x)*(x))#definequad(x)((x)*(x)*(x)*(x))#include<stdio.h>#include“c:\powers.h"#defineMAX_POWER10voidmain(){intn;printf("numberexp1\texp2\texp3\texp4\n");printf("----\t----\t-----\t------\n");for(n=1;n<=MAX_POWER;n++)printf("%2d\t%3d\t%4d\t%5d\n",n,sqr(n),cube(n),quad(n));}453条件编译概念:在某个条件成立情况下才对某一部分进行编译。三种格式:格式二形式:作用:假如标识符没有被#define命令定义过,则对程序段1进行编译,不然对程序段2进行编译格式三形式:作用:假如指定常量表示式1值为真(非零),则对程序段1进行编译,不然假如指定常量表示式2值为真(非零),则对

温馨提示

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

评论

0/150

提交评论