C语言函数与宏定义课件.ppt

上传人:wuy****n92 文档编号:70101469 上传时间:2023-01-16 格式:PPT 页数:54 大小:886.50KB
返回 下载 相关 举报
C语言函数与宏定义课件.ppt_第1页
第1页 / 共54页
C语言函数与宏定义课件.ppt_第2页
第2页 / 共54页
点击查看更多>>
资源描述

《C语言函数与宏定义课件.ppt》由会员分享,可在线阅读,更多相关《C语言函数与宏定义课件.ppt(54页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*1/49第第1章章函数与宏定义函数与宏定义1.1函数概念函数概念 1.2变量作用域和存储类型变量作用域和存储类型1.3内部函数与外部函数内部函数与外部函数1.4递归函数的设计和调用递归函数的设计和调用1.5预处理预处理1.6综合范例综合范例C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*2/491.1函数概念函数概念 C语言中,函数可分为两类语言中,函数可分为两类:一类是由系统定义的一类是由系统定义的标准函数标准函数,又称为,又称为库函数库函数,其函数,其函数声明一般是放在系统的声明一般

2、是放在系统的include目录下以目录下以.h为后缀的头文为后缀的头文件中,如在程序中要用到某个库函数,必须在调用该函件中,如在程序中要用到某个库函数,必须在调用该函数之前用数之前用#include命令将库函数信息包含到命令将库函数信息包含到本程序中。本程序中。另一类函数是另一类函数是自定义函数自定义函数C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*3/491.1.1函数定义函数定义存储类型符存储类型符返回值类型符返回值类型符函数名函数名(形参说明表形参说明表)函数语句体函数语句体C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*4/

3、49说明:说明:1存储类型符存储类型符指的是函数的作用范围,它只有两种指的是函数的作用范围,它只有两种形式:形式:static和和extern。static说明函数只能作用于其所在的源文件,用说明函数只能作用于其所在的源文件,用static说说明的函数又称为明的函数又称为内部函数内部函数。extern说明函数可被其它源文件中的函数调用,用说明函数可被其它源文件中的函数调用,用extern说明的函数,又称为说明的函数,又称为外部函数外部函数。缺省缺省情况为情况为extern。2返返回回值值类类型型符符指指的的是是函函数数体体语语句句执执行行完完成成后后,函函数数返返回回的的值值的的类类型型,如如

4、int,float,char等等等等,若若函函数数无返回值,则用无返回值,则用空类型空类型void来定义函数的返回值。来定义函数的返回值。缺省缺省情况为情况为int型。型。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*5/493函数名函数名由任何合法的标识符构成。建议将函数名由任何合法的标识符构成。建议将函数名的命名与函数内容有一定关系。的命名与函数内容有一定关系。4形形参参说说明明表表是是一一系系列列用用逗逗号号分分开开的的每每个个形形参参变变量量说明。说明。如:如:intx,inty,intz这表示形参变量有三个:这表示形参变量有三个:x,y,z。它们的类型

5、都是。它们的类型都是int型。型。5函数语句体函数语句体是放在一对花括号是放在一对花括号中,由局部数据类中,由局部数据类型描述和功能实现两部分组成。型描述和功能实现两部分组成。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*6/496函数返回语句函数返回语句的形式有以下两种:的形式有以下两种:函数无返回值的情况:函数无返回值的情况:return;或者什么也不写;或者什么也不写函数有返回值的情况:函数有返回值的情况:return(表达式的值表达式的值);在在第第种种情情况况下下要要注注意意“表表达达式式的的值值”的的类类型型必必须须与与函数返回值的类型相一致。函数返

6、回值的类型相一致。例例如如:求求两两个个任任意意整整数数的的绝绝对对值值的的和和,用用函函数数abs_sum()实现。实现。/*直接调用库函数来计算直接调用库函数来计算m和和n的绝对值的绝对值*/intabs_sum(intm,intn)return(abs(m)+abs(n);/*函数函数abs()是在头文件是在头文件math.h中声明的中声明的*/C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*7/49函数定义如下:函数定义如下:intabs_sum(intm,intn)if(m0)m=-m;if(n0)n=-n;return(m+n);1.1.2函数声明和调

7、用函数声明和调用1函数的声明函数的声明函数声明的一般形式:函数声明的一般形式:存储类型符存储类型符返回值类型符返回值类型符函数名函数名(形参说明表形参说明表);如:如:intabs_sun(intm,intn);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*8/492函数调用函数调用函数调用是通过函数调用语句来实现的,分两种形式:函数调用是通过函数调用语句来实现的,分两种形式:无返回值的情况:无返回值的情况:函数名函数名(实参表实参表);有返回值的情况:有返回值的情况:变量名函数名变量名函数名(实参表实参表);该变量名的类型必须与函数的返回值类型相同。该变量名的

8、类型必须与函数的返回值类型相同。函函数数调调用用时时都都会会去去执执行行函函数数语语句句中中的的内内容容,函函数数执执行行完完毕后,回到函数的调用处,继续执行下面的语句。毕后,回到函数的调用处,继续执行下面的语句。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*9/491.1.3函数的传值方式函数的传值方式函数的传值方式函数的传值方式:采用实参表将每一个实参的值相应地传递给每一个形采用实参表将每一个实参的值相应地传递给每一个形参变量,形参变量在接收到实参表传过来的值时,会在内参变量,形参变量在接收到实参表传过来的值时,会在内存存临时开辟新的空间临时开辟新的空间,以

9、保留形参变量的值,当函数执行,以保留形参变量的值,当函数执行完毕时,这些完毕时,这些临时开辟的内存空间会被释放临时开辟的内存空间会被释放,并且形参的,并且形参的值在函数中不论是否发生变化,值在函数中不论是否发生变化,都不会影响到实参变量的都不会影响到实参变量的值的变化值的变化,这就是函数的传值方式。,这就是函数的传值方式。自定义函数在程序中的使用顺序有两种形式:自定义函数在程序中的使用顺序有两种形式:先进行函数声明,再进行函数调用,先进行函数声明,再进行函数调用,函数定义放在函数定义放在函数调用之后。函数调用之后。函数声明在函数调用之前。函数声明在函数调用之前。函数定义放在函数调用之前。函数定

10、义放在函数调用之前。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*10/49【例例1-1】编编程程序序,通通过过调调用用函函数数abs_sum(),求求任任意意两个整数的绝对值的和。两个整数的绝对值的和。/*exam1_1.c调用函数求两整数绝对值的和调用函数求两整数绝对值的和*/#includeintabs_sum(intm,intn);main()intx,y,z;scanf(%d%d,&x,&y);z=abs_sum(x,y);printf(sumis%d,z);intabs_sum(intm,intn)if(m0)m=-m;if(n0)n=-n;retu

11、rnm+n;程序运行结果程序运行结果程序运行结果程序运行结果:712712 sumis19sumis19C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*11/49用传值方式调用函数时,实参也可以是函数调用语句用传值方式调用函数时,实参也可以是函数调用语句【例例1-2】求任意三个数的绝对值的和。求任意三个数的绝对值的和。/*exam1_2.c调用函数求三个整数绝对值的和调用函数求三个整数绝对值的和*/#includeintabs_sum(intm,intn);main()intx,y,z,sum;scanf(%d%d%d,&x,&y,&z);sum=abs_sum(

12、abs_sum(x,y),z);printf(sumis%d,sum);intabs_sum(intm,intn)if(m0)m=-m;if(n0)n=-n;returnm+n;程序运行结果程序运行结果:7125 sumis24C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*12/49注意:注意:对于有返回值的函数,调用时若没有把它赋给某个变量,对于有返回值的函数,调用时若没有把它赋给某个变量,仍然是可以的,只是函数的返回值有可能会被丢失。仍然是可以的,只是函数的返回值有可能会被丢失。【例例1-3】求任意两数的乘积。求任意两数的乘积。自定义一个函数自定义一个函数m

13、ul(),用于求两数的乘积,程序:,用于求两数的乘积,程序:/*exam1_3.c求两个数的乘积求两个数的乘积*/#includefloatmul(floata,floatb);main()floatx,y,z;scanf(%f%f,&x,&y);z=mul(x,y);/*/x=x+10;y=y-10;mul(x,y);/*/C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*13/49x=x*2;y=y*2;printf(z=%f,mul(%f,%f)=%fn,z,x,y,mul(x,y);/*/floatmul(floata,floatb)returna*b;程序

14、运行结果程序运行结果:56 z=30.000000,mul(30.000000,-8.000000)=-240.000000C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*14/49程序说明程序说明:注释注释处调用函数后的返回值赋给变量处调用函数后的返回值赋给变量z。注释注释处调用函数后的返回值没有赋给任何变量,处调用函数后的返回值没有赋给任何变量,函数的返回值被丢失。函数的返回值被丢失。注释注释处调用函数后的返回值成为了处调用函数后的返回值成为了printf()函数的函数的参数。参数。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*

15、15/491.2变量作用域和存储类型变量作用域和存储类型1变量的作用域变量的作用域变量的作用域:指的是变量的作用域:指的是变量的有效范围变量的有效范围,针对变量不同,针对变量不同的作用域,可把变量分为局部变量和全局变量。的作用域,可把变量分为局部变量和全局变量。局部变量局部变量:在函数内部或某个控制块的内部定义的变量:在函数内部或某个控制块的内部定义的变量为局部变量,局部变量的有效范围只限于为局部变量,局部变量的有效范围只限于本函数内部本函数内部,退出函数,该变量自动失效。退出函数,该变量自动失效。全局变量全局变量:在函数外面定义的变量称为全局变量,全局变:在函数外面定义的变量称为全局变量,全

16、局变量的作用域是从该变量定义的位置开始,直到源文件结束。量的作用域是从该变量定义的位置开始,直到源文件结束。在在同一文件同一文件中的所有函数都可以引用全局变量。中的所有函数都可以引用全局变量。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*16/49局部变量和全局变量的局部变量和全局变量的作用域作用域如图所示:如图所示:C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*17/49【例例1-4】变量作用域应用举例,阅读下面的程序,变量作用域应用举例,阅读下面的程序,注意区分局部变量和全局变量的作用域。注意区分局部变量和全局变量的作用域。/

17、*exam9_4.c变量作用域举例变量作用域举例*/#includevoida(void);voidb(void);voidc(void);intx=1;main()intx=5;printf(localxinouterscopeofmainis%dn,x);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*18/49intx=7;printf(localxininnerscopeofmainis%dn,x);printf(localxinouterscopeofmainis%dn,x);a();b();c();a();b();c();前三次输出前三次输出结果结果:

18、localxinouterscopeofmainis5localxininnerscopeofmainis7localxinouterscopeofmainis5C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*19/49printf(localxinmainis%dn,x);getchar();return0;voida(void)intx=25;printf(nlocalxinais%dafterenteringan,x);+x;printf(localxinais%dbeforeexitingan,x);C C 程序设计基础教程程序设计基础教程第九章第九章函数

19、与宏定义函数与宏定义*20/49voidb(void)staticintx=50;printf(nlocalstaticxis%donenteringbn,x);+x;printf(localstaticxis%donexitingbn,x);voidc(void)printf(nglobalxis%donenteringcn,x);x*=10;printf(globalxis%donexitingcn,x);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*21/49程序运行结果程序运行结果:后后6次函数调用次函数调用localxinais25afterenter

20、ingalocalxinais26beforeexitingalocalstaticxis50onenteringblocalstaticxis51onexitingbglobalxis1onenteringcglobalxis10onexitingclocalxinais25afterenteringalocalxinais26beforeexitingalocalstaticxis51onenteringblocalstaticxis52onexitingbglobalxis10onenteringcglobalxis100onexitingc最后一次输出:最后一次输出:localxinm

21、ainis5C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*22/492变量的存储类型变量的存储类型变量的存储类型:指的是变量的变量的存储类型:指的是变量的存储属性存储属性,它说明,它说明变量变量占用存储空间的区域。占用存储空间的区域。在内存中,供用户使用的存储区由在内存中,供用户使用的存储区由程序区程序区、静态存储区静态存储区和和动态存储区动态存储区三部分组成。三部分组成。变量的存储类型有四种:变量的存储类型有四种:auto型、型、register型、型、static型和型和extern型。型。auto型型变量存储在内存的变量存储在内存的动态存储区动态存储区。r

22、egister型变量保存在型变量保存在寄存器寄存器中。中。static型变量和型变量和extern型变量型变量存储在存储在静态存储器静态存储器。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*23/49局部变量局部变量的存储类型缺省值为的存储类型缺省值为auto型型。全局变量全局变量的存储类型缺省值为的存储类型缺省值为extern型型。auto型变量和型变量和register型变量只用于定义局部变量。型变量只用于定义局部变量。static型变量即可定义成局部变量,又可定义成全局变量。型变量即可定义成局部变量,又可定义成全局变量。【例例1-5】设计一个函数:设计一个

23、函数:longfac(intn),可用来计算,可用来计算15的阶乘。的阶乘。分析:可在函数中定义一个分析:可在函数中定义一个static型变量,用来保存型变量,用来保存上次的计算结果。上次的计算结果。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*24/49/*exam1_5.c用用static型型变变量量保保留留上上次次阶阶乘乘的的值值*/#includelongfac(intn)staticintf=1;f=f*n;returnf;main()inti;for(i=1;i=5;i+)printf(%d!=%ldn,i,fac(i);程序运行结果程序运行结果:1

24、!=12!=23!=64!=245!=120局部变量局部变量局部变量局部变量f f被定义成被定义成被定义成被定义成staticstatic型的,因型的,因型的,因型的,因此,它只在该函数第此,它只在该函数第此,它只在该函数第此,它只在该函数第1 1次被调用的次被调用的次被调用的次被调用的时候初始化其值为时候初始化其值为时候初始化其值为时候初始化其值为1 1,以后再调用,以后再调用,以后再调用,以后再调用该函数时,不再进行初始化,而该函数时,不再进行初始化,而该函数时,不再进行初始化,而该函数时,不再进行初始化,而是使用上一次调用的值。是使用上一次调用的值。是使用上一次调用的值。是使用上一次调用

25、的值。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*25/491.3内部函数与外部函数内部函数与外部函数1内部函数内部函数若函数的存储类型为若函数的存储类型为static型,则称其为型,则称其为内部函数内部函数或称或称静态静态函数函数,它表示在同一个程序中(由多个源文件组成),该,它表示在同一个程序中(由多个源文件组成),该函数只能在一个文件中存在,在其它文件中不可使用。函数只能在一个文件中存在,在其它文件中不可使用。如:如:staticintfun-name();内部函数只能被其所在的源文件调用。内部函数只能被其所在的源文件调用。2外部函数外部函数若函数的存储

26、类型定义为若函数的存储类型定义为extern型,则称其为型,则称其为外部函数外部函数,它表示该函数能被其它源文件调用。函数的缺省存储类它表示该函数能被其它源文件调用。函数的缺省存储类型为型为extern型。型。注意:注意:在需要用到外部函数的文件中,其函数声明必须在需要用到外部函数的文件中,其函数声明必须用用extern进行说明。进行说明。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*26/49例如:有两个源文件例如:有两个源文件file1.c和和file2.c如下所示:如下所示:/*file1.c调用外部函数调用外部函数*/#includeintmod(int

27、a,intb);externintadd(intm,intn);/*外部函数声明外部函数声明*main()intx,y,result;scanf(“%d%d”,&x,&y);result=add(x,y);/*调用外部函数调用外部函数*/if(result0)result=result-mod(x,y);printf(“result=%dn”,result);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*27/49intmod(inta,intb)return(a%d);/*file2.c外部函数外部函数*/externintadd(intm,intn)retu

28、rn(m+n);说明:说明:1在文件在文件1(file1.c)中的函数声明:中的函数声明:intmod(inta,intb);实际上相当于:实际上相当于:externintmod(inta,intb);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*28/492在文件在文件2(file2.c)中的函数定义:中的函数定义:externintadd(intm,intn)return(m+n);实际上相当于:实际上相当于:intadd(intm,intn)return(m+n);3由多个源文件组成一个程序时,由多个源文件组成一个程序时,main()函数只能函数只能出现在

29、一个源文件中。出现在一个源文件中。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*29/494多个源文件的连接方式有三种:多个源文件的连接方式有三种:将各源文件分别编译成目标文件,得到多个目标文件将各源文件分别编译成目标文件,得到多个目标文件(.obj后缀),然后用连接命令(后缀),然后用连接命令(tlink)把多个)把多个.obj文件文件连接起来,在连接起来,在Turboc上用如下命令:上用如下命令:tlinkfile1.obj+file2.obj+filen.obj生成一个生成一个file1.exe的可执行文件。的可执行文件。建立项目文件(建立项目文件(.pr

30、j后缀),具体操作可参阅各种后缀),具体操作可参阅各种C编译手册。编译手册。使用文件包含命令。使用文件包含命令。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*30/491.4递归函数设计和调用递归函数设计和调用C语言中一个函数中的语句可以是对另一个函数的调用。语言中一个函数中的语句可以是对另一个函数的调用。函数嵌套调用函数嵌套调用图例:图例:调用过程按图中箭头所示的方向和顺序进行,属于一种调用过程按图中箭头所示的方向和顺序进行,属于一种线性调用关系线性调用关系,每次调用后,最终返回到原调用点,继,每次调用后,最终返回到原调用点,继续执行以下语句。续执行以下语句。

31、C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*31/49C语言中还允许在函数中语言中还允许在函数中调用自身调用自身,或函数之间相,或函数之间相互调用,这种调用方式称之为互调用,这种调用方式称之为递归递归。递归又分为。递归又分为直直接递归调用接递归调用和和间接递归调用间接递归调用。直接递归调用;函数直接调用自身。直接递归调用;函数直接调用自身。间接递归调用:函数互相调用对方。间接递归调用:函数互相调用对方。直接递归:直接递归:inttemp(intx)inty,z;z=temp(y);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*3

32、2/49间接递归:间接递归:显然,递归有可能陷入无限递归状态,最终导致错误发显然,递归有可能陷入无限递归状态,最终导致错误发生。因此,生。因此,设计一个递归问题必须具备两个条件设计一个递归问题必须具备两个条件:1后一部分与原始问题类似。后一部分与原始问题类似。2后一问题是原始问题的简化。后一问题是原始问题的简化。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*33/49【例例1-6】编程,从键盘输入一个正整数编程,从键盘输入一个正整数n,求,求n!。n!的数字表达式为:的数字表达式为:n!=定义一个求定义一个求n!的函数:的函数:longfac(intn)long

33、fac(intn)longresult;if(n=0|n=1)result=1;elseresult=n*fac(n-1);return(result);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*34/49完整程序如下:完整程序如下:/*exam1_6.c用递归法求用递归法求n!*/#includelongfac(intn)longresult;if(n=0|n=1)result=1;elseresult=n*fac(n-1);returnresult;main()intx;longf;C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏

34、定义*35/49scanf(%d,&x);if(x1)设计一个函数:设计一个函数:longfibonacci(intn)用于计算数列用于计算数列中第中第n项的值,项的值,C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*37/49程序如下所示:程序如下所示:/*exam1_7.c求第求第n项项Fibonacci数列的值数列的值*/#includelongfibonacci(intn);main()intx=0;longresult;doresult=fibonacci(x);printf(fibonacci(%d)=%ldn,x,result);scanf(%d,&

35、x);while(x!=-1);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*38/49longfibonacci(intn)if(n=0|n=1)returnn;elsereturnfibonacci(n-1)+fibonacci(n-2);程序运行结果程序运行结果程序运行结果程序运行结果:fibonacci(0)=0fibonacci(0)=03 3 fibonacci(3)=2fibonacci(3)=24 4 fibonacci(4)=3fibonacci(4)=36 6 C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*39

36、/49以以x=4为例,下图说明了为例,下图说明了fibonacci函数是怎样计算函数是怎样计算fibonacci(4)的。图中把的。图中把fibonacci简写成简写成f。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义“编编译译预预处处理理”是是C与与其其它它高高级级语语言言的的一一个个重要区别。它们主要是:重要区别。它们主要是:宏定义宏定义 文件包含文件包含 条件编译条件编译1.5 预处理预处理C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义1)不带参数的宏定义不带参数的宏定义用指定的标识符用指定的标识符(宏名宏名)代表一串字符。代表

37、一串字符。#define 宏名宏名 字符串字符串1.5.1 宏定义宏定义例例 求正圆锥体的底周长、底面积和它的体积。求正圆锥体的底周长、底面积和它的体积。#definePI3.1415926/*宏名宏名PI用大写,行末无分号用大写,行末无分号*/main()floatl,s,r,v;scanf(%f,&r);l=2.0*PI*r;s=PI*r*r;v=4.0/3*PI*r*r*r;printf(l=%10.4fns=%10.4fnv=%10.4fn,l,s,v);getch();C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 进行宏定义时,可以引用已定义的宏名,层

38、层置换。进行宏定义时,可以引用已定义的宏名,层层置换。对程序中用双引号括起来的字符串,即使与宏名相同,对程序中用双引号括起来的字符串,即使与宏名相同,也不会被置换。也不会被置换。宏名的有效范围为该宏定义命令之后至本源文件结束。宏名的有效范围为该宏定义命令之后至本源文件结束。通常,宏定义命令一般写在文件开头或函数之前作为该通常,宏定义命令一般写在文件开头或函数之前作为该文件的一部分。文件的一部分。可以用可以用#undef 命令终止宏定义的作用域。如:命令终止宏定义的作用域。如:#define G 9.8main()#undef Gfloat f()G 的作用范围的作用范围C C 程序设计基础教程

39、程序设计基础教程第九章第九章函数与宏定义函数与宏定义2带参数的宏定义带参数的宏定义语句形式:语句形式:#define 宏名宏名(形参表形参表)字符串字符串注意:字符串应包含形参表中的参数注意:字符串应包含形参表中的参数例例#definePI3.1415926#defineS(r)PI*r*rmain()floata,area;a=3.6;area=S(a);/*area=3.1415926*a*a,但不会置换,但不会置换a为为3.6*/printf(r=%fnarea=%fn,a,area);getch();C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 若将若将

40、area=S(a)改写成改写成 area=S(a+2),将置换为:,将置换为:area=PI a+2 a+2,而不是,而不是:area=PI (a+2)(a+2)。若要达到后者,则应将宏定义命令改写为:若要达到后者,则应将宏定义命令改写为:#define S(r)PI (r)(r)宏宏名名与与括括号号之之间间不不得得有有空空格格,因因为为宏宏名名与与表表达达式式之之间间的的分分隔隔符符为为空空格格。如如果果用用#define S (r)PI r r 的的话话,则被置换为则被置换为 area=(r)PI r r (a)宏宏展展开开并并不不进进行行值值的的传传递递,即即不不求求表表达达式式的的值值

41、,也也没没有有“返回值返回值”的概念。的概念。宏宏不不存存在在类类型型问问题题,宏宏名名无无类类型型,参参数数也也无无类类型型,表表达式可以是任何类型。达式可以是任何类型。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义注注:这里的:这里的 t 展开后为展开后为 t=(a+b)(c+d)?(a+b):(c+d)如如果果第第一一行行写写成成:#define MAX(x,y)xy?x:y 则则这里的这里的 t 展开后为展开后为 t=a+bc+d?a+b:c+d 因为因为置换展开是用置换展开是用“表达式表达式”对等对等的置换的置换“形参表形参表”中的参数中的参数。定义带参

42、数的宏,可以实现一些简单的函数功能。定义带参数的宏,可以实现一些简单的函数功能。如:如:#define MAX(x,y)(x)(y)?(x):(y)main()int a,b,c,t;t=MAX(a+b,c+d);C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义1.5.2 “文件包含文件包含”用用#include 命令实现一个文件包含另一个文件。命令实现一个文件包含另一个文件。语句形式:语句形式:#include“文件名文件名”例例#includestdio.h#defineN2#defineMN+1#defineNUM(M+1)*M/2main()inti,n=0

43、;for(i=1;i=NUM;i+)n+;printf(%2d,n);getch();输出结果:输出结果:1 2 3 4 5 6 7 8C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 一一个个include命命令令只只能能指指定定一一个个被被包包含含文文件件,如果要包含如果要包含n个文件,则要用个文件,则要用n个个include命令。命令。NUM被代换展开后为:被代换展开后为:(2+1+1)2+1/2#include命令中,文件名既可用双引命令中,文件名既可用双引“”号号(推荐),推荐),也可用尖括号也可用尖括号括起来。括起来。表示被包含在标准目录表示被包含在标准

44、目录中中(include).“”表示被包含文件在指定目录中,若只表示被包含文件在指定目录中,若只有文件名不带路径,则在当前目录中,若找不到,有文件名不带路径,则在当前目录中,若找不到,再到标准目录中找。再到标准目录中找。包含文件名可以是包含文件名可以是.c源文件或源文件或.头文件,如头文件,如#include#include“myhead.h”#include“D:myexammyfile.c”C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 条件编译条件编译语句形式:语句形式:1#ifdef 宏名宏名程序段程序段1#else程序段程序段2#endif 作用:如果宏

45、名已定义,则编译作用:如果宏名已定义,则编译“程序段程序段1”,否则编,否则编译译“程序段程序段2”。所所谓谓“宏宏名名已已定定义义”是是无无论论“宏宏名名”定定义义为为什什么么内内容。容。条条件件编编译译的的作作用用:缩缩短短编编译译时时间间,减减少少目目标标程程序序的的长长度。度。C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 作用:如果宏名未定义,则编译作用:如果宏名未定义,则编译“程序段程序段1”,否则,否则编译编译“程序段程序段2”。3#if 表达式表达式程序段程序段1#else程序段程序段2#endif 作用:当作用:当“表达式表达式”值为非值为非0,

46、则编译,则编译“程序段程序段1”,否则编译,否则编译“程序段程序段2”。2#ifndef 宏名宏名 程序段程序段1#else 程序段程序段2#endifC C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义 4#if 表达式表达式1 程序段程序段1#elif 表达式表达式2 程序段程序段2#else 程序段程序段3#endif 作用:当作用:当“表达式表达式1”值为非值为非0,则编译,则编译“程序段程序段1”,否则判断否则判断”表达式表达式2”;当当“表达式表达式2”的值为真,则编译的值为真,则编译“程序段程序段2”,否则编译否则编译”程序段程序段3”。C C 程序设计基

47、础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义例例#defineTED10main()#ifdefTEDprintf(Hi,Tedn);#elseprintf(HI,Anyonen);#endif#ifndefPALPHprintf(RAPLHnotdefinedn);#endifgetch();C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义例例main()#ifMAX99printf(compileforarraygreaterthan99);#elseprintf(compileforsmallarray);#endifgetch();C C 程序

48、设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义例例#defineN2#defineMN+1#defineNUM2*M+1main()inti;for(i=1;i(y)?(x):(y)main()inta=5,b=2,c=3,d=3,t;t=MAX(a+b,c+d)*10;printf(%dn,t);/*t的值是多少?的值是多少?*/getch();C C 程序设计基础教程程序设计基础教程第九章第九章函数与宏定义函数与宏定义*54/49小小结:介绍了函数的定义和传值调用函数的使用方法介绍了函数的定义和传值调用函数的使用方法。注意:若用全局变量作为函数的参数,则在函数中可注意:若

49、用全局变量作为函数的参数,则在函数中可以使得该全局变量的值发生变化。以使得该全局变量的值发生变化。对于递归函数的设计一定要有可使递归结束的条件,对于递归函数的设计一定要有可使递归结束的条件,否则会使程序产生无限递归。否则会使程序产生无限递归。使用预处理命令时,要注意以下几点:使用预处理命令时,要注意以下几点:1宏替换定义的末尾不能使用分号宏替换定义的末尾不能使用分号“;”。2在有参数的宏定义中,参数加括号和不加括号有时在有参数的宏定义中,参数加括号和不加括号有时会有区别。会有区别。3使用文件包含时,要避免出现变量和函数发生重定使用文件包含时,要避免出现变量和函数发生重定义的现象。义的现象。4要区分条件编译与条件语句的作用。要区分条件编译与条件语句的作用。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁