第7章编译预处理.ppt
《第7章编译预处理.ppt》由会员分享,可在线阅读,更多相关《第7章编译预处理.ppt(51页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第7 7章章编译预处理C C/C C+语言程序设计案例教程语言程序设计案例教程7.1 宏定义7.2 文件包含7.3 条件编译3/2/2023预处理不是预处理不是C语言本身的组成部分,不能直语言本身的组成部分,不能直接进行编译。在对源程序编译之前,系统接进行编译。在对源程序编译之前,系统先将这部分命令进行先将这部分命令进行“预处理预处理”,处理后,处理后源程序将不再包括预处理命令,随后系统源程序将不再包括预处理命令,随后系统完成编译,链接生成目标程序。完成编译,链接生成目标程序。C语言提供语言提供3种预处理功能:宏定义;文件种预处理功能:宏定义;文件包含;条件编译。包含;条件编译。3/2/20
2、232案例一案例一 宏的使用宏的使用 1.1.问题描述问题描述计算物体在水中的浮力以及在不同液体和不同物计算物体在水中的浮力以及在不同液体和不同物计算物体在水中的浮力以及在不同液体和不同物计算物体在水中的浮力以及在不同液体和不同物体体积下受到的浮力体体积下受到的浮力体体积下受到的浮力体体积下受到的浮力(假设物体全部沉入水中假设物体全部沉入水中假设物体全部沉入水中假设物体全部沉入水中)。2.2.问题分析问题分析浮力浮力浮力浮力=pgvpgv。在水中,物体受到的浮力与体积有关,在水中,物体受到的浮力与体积有关,在水中,物体受到的浮力与体积有关,在水中,物体受到的浮力与体积有关,g g 是常数,是常
3、数,是常数,是常数,将将将将g g定义为宏定义为宏定义为宏定义为宏(无参宏无参宏无参宏无参宏)。在液体中,不同物体在不同液体中受到的浮力与在液体中,不同物体在不同液体中受到的浮力与在液体中,不同物体在不同液体中受到的浮力与在液体中,不同物体在不同液体中受到的浮力与物体体积和液体的密度有关,将计算公式也定义物体体积和液体的密度有关,将计算公式也定义物体体积和液体的密度有关,将计算公式也定义物体体积和液体的密度有关,将计算公式也定义为宏为宏为宏为宏(有参宏有参宏有参宏有参宏)。3/2/202333.C3.C语言代码语言代码#include#include stdio.hstdio.h /*/*预处
4、理指令是以预处理指令是以预处理指令是以预处理指令是以#号为开头的代码行,号为开头的代码行,号为开头的代码行,号为开头的代码行,#include#include是一个文件包含预处理是一个文件包含预处理是一个文件包含预处理是一个文件包含预处理*/#define g 9.8 /*g#define g 9.8 /*g定义为无参宏定义为无参宏定义为无参宏定义为无参宏*/#define#define F(pF(p,v)(p*9.8*v)/*,v)(p*9.8*v)/*将浮力计算公式定义为有参宏,物体体积将浮力计算公式定义为有参宏,物体体积将浮力计算公式定义为有参宏,物体体积将浮力计算公式定义为有参宏,物体
5、体积v v和液体密度和液体密度和液体密度和液体密度p p为参数,也可将为参数,也可将为参数,也可将为参数,也可将 F(pF(p,v),v)定义为定义为定义为定义为(p*g*v)(p*g*v),即有参宏的嵌套定义,即有参宏的嵌套定义,即有参宏的嵌套定义,即有参宏的嵌套定义*/void main()void main()float F1,F2;float F1,F2;float p,v;float p,v;/*/*以下部分计算物体在水中的浮力以下部分计算物体在水中的浮力以下部分计算物体在水中的浮力以下部分计算物体在水中的浮力F1*/F1*/printfprintf(请输入在水中物体的体积请输入在水
6、中物体的体积请输入在水中物体的体积请输入在水中物体的体积vnvn););scanf(%fscanf(%f,&v);,&v);F1=1000*g*v;/*F1=1000*g*v;/*替换无参宏名替换无参宏名替换无参宏名替换无参宏名g g,将,将,将,将g g替换成数值替换成数值替换成数值替换成数值9.8*/9.8*/printfprintf(物体在水中的浮力是物体在水中的浮力是物体在水中的浮力是物体在水中的浮力是F1=%F1=%fnfn,F1);,F1);/*/*以下部分计算不同物体在不同液体中的浮力以下部分计算不同物体在不同液体中的浮力以下部分计算不同物体在不同液体中的浮力以下部分计算不同物体
7、在不同液体中的浮力F2*/F2*/printfprintf(请输入在某液体中液体的密度请输入在某液体中液体的密度请输入在某液体中液体的密度请输入在某液体中液体的密度p p和物体的体积和物体的体积和物体的体积和物体的体积vnvn););scanf(%fscanf(%f,%f,&p,&v);,%f,&p,&v);F2=F2=F(pF(p,v);,v);/*/*替换有参宏替换有参宏替换有参宏替换有参宏F(pF(p,v),v),将,将,将,将F(pF(p,v),v)替换为表达式替换为表达式替换为表达式替换为表达式p*9.8*v*/p*9.8*v*/*/*如果采用宏的嵌套定义,如果采用宏的嵌套定义,如果
8、采用宏的嵌套定义,如果采用宏的嵌套定义,F(pF(p,v),v)首先替换为表达式首先替换为表达式首先替换为表达式首先替换为表达式p*g*vp*g*v,再替换为,再替换为,再替换为,再替换为p*9.8*v*/p*9.8*v*/printfprintf(物体在液体中的浮力物体在液体中的浮力物体在液体中的浮力物体在液体中的浮力F2=%F2=%fnfn,F2);,F2);#undefundef g;g;/*/*取消取消取消取消g g宏定义宏定义宏定义宏定义*/#undefundef F(pF(p,v);,v);/*/*取消宏取消宏取消宏取消宏F(pF(p,v),v)定义定义定义定义*/3/2/2023
9、44.程序运行结果请输入在水中物体的体积请输入在水中物体的体积v12.2物体在水中的浮力是物体在水中的浮力是F1=119560请输入在某液体中液体的密度请输入在某液体中液体的密度p和物体的体和物体的体积积v700,24物体在液体中的浮力物体在液体中的浮力F2=1646403/2/202357.1 宏 定 义宏定义是预处理命令中的一种,它提供了一宏定义是预处理命令中的一种,它提供了一种可以替换源代码中字符串的机制。根据种可以替换源代码中字符串的机制。根据宏中是否有参数,可以将宏定义分为不带宏中是否有参数,可以将宏定义分为不带参数的宏定义和带参数的宏定义。参数的宏定义和带参数的宏定义。3/2/20
10、236宏定义是预处理命令中的一种,它提供了一宏定义是预处理命令中的一种,它提供了一种可以替换源代码中字符串的机制。根据种可以替换源代码中字符串的机制。根据宏中是否有参数,可以将宏定义分为不带宏中是否有参数,可以将宏定义分为不带参数的宏定义和带参数的宏定义。参数的宏定义和带参数的宏定义。3/2/202377.1.1 不带参数的宏定义不带参数的宏定义格式如下:不带参数的宏定义格式如下:#define 标识符标识符 字符串字符串宏定义格式中宏定义格式中“标识符标识符”为用户定义标识符,为用户定义标识符,称为宏名,也叫符号常量,一般用大写字称为宏名,也叫符号常量,一般用大写字母表示。母表示。字符串可以
11、是常量、表达式、格式串等。字符串可以是常量、表达式、格式串等。注意:宏定义不是注意:宏定义不是C语言的语句,宏定义结语言的语句,宏定义结尾没有分号。尾没有分号。3/2/20238说明:说明:说明:说明:(1)(1)预处理中,源程序在宏定义之后出现的所有与宏名一预处理中,源程序在宏定义之后出现的所有与宏名一预处理中,源程序在宏定义之后出现的所有与宏名一预处理中,源程序在宏定义之后出现的所有与宏名一样的标识符都替换成宏定义中的字符串,不做语法检查。样的标识符都替换成宏定义中的字符串,不做语法检查。样的标识符都替换成宏定义中的字符串,不做语法检查。样的标识符都替换成宏定义中的字符串,不做语法检查。例
12、如:将例如:将例如:将例如:将#define g 9.8#define g 9.8错误地写成错误地写成错误地写成错误地写成#define g 98#define g 98,则在编译预处理中将则在编译预处理中将则在编译预处理中将则在编译预处理中将g g替换为替换为替换为替换为9898进行编译。进行编译。进行编译。进行编译。(2)(2)源程序中宏可以嵌套定义。例如,计算圆柱体体积:源程序中宏可以嵌套定义。例如,计算圆柱体体积:源程序中宏可以嵌套定义。例如,计算圆柱体体积:源程序中宏可以嵌套定义。例如,计算圆柱体体积:#define R 6.3#define R 6.3#define HIGHT 1
13、2.5#define HIGHT 12.5#define VOLUME (3.14*R*R*HIGHT)/*#define VOLUME (3.14*R*R*HIGHT)/*宏的嵌套定义宏的嵌套定义宏的嵌套定义宏的嵌套定义*/在在在在#define VOLUME (3.14*R*R*HIGHT)#define VOLUME (3.14*R*R*HIGHT)中中中中HIGHTHIGHT和和和和R R宏宏宏宏定义定义定义定义VOLUMEVOLUME在之前,即为宏嵌套定义。在之前,即为宏嵌套定义。在之前,即为宏嵌套定义。在之前,即为宏嵌套定义。3/2/20239嵌套定义的替换过程为由外到内,例如:嵌
14、套定义的替换过程为由外到内,例如:嵌套定义的替换过程为由外到内,例如:嵌套定义的替换过程为由外到内,例如:将宏名将宏名将宏名将宏名R R进行替换,替换结果为进行替换,替换结果为进行替换,替换结果为进行替换,替换结果为#define VOLUME (3.14*6.3*#define VOLUME (3.14*6.3*6.36.3*HIGHT)*HIGHT)将宏名将宏名将宏名将宏名HIGHTHIGHT进行替换,替换结果为进行替换,替换结果为进行替换,替换结果为进行替换,替换结果为#define VILUME (3.14*6.3*#define VILUME (3.14*6.3*6.36.3*12.
15、5)*12.5)案例一中:案例一中:案例一中:案例一中:#define g 9.8#define g 9.8/*g/*g定义为无参宏定义为无参宏定义为无参宏定义为无参宏*/#define#define F(pF(p,v)(p*g*v),v)(p*g*v)/*g/*g宏定义在宏定义在宏定义在宏定义在F F之前,也是宏的嵌套定义之前,也是宏的嵌套定义之前,也是宏的嵌套定义之前,也是宏的嵌套定义*/(3)(3)宏定义的作用域。一个宏名与变量一样也有它的作用域,宏名的作用范围从该宏名的宏定义处宏定义的作用域。一个宏名与变量一样也有它的作用域,宏名的作用范围从该宏名的宏定义处宏定义的作用域。一个宏名与变
16、量一样也有它的作用域,宏名的作用范围从该宏名的宏定义处宏定义的作用域。一个宏名与变量一样也有它的作用域,宏名的作用范围从该宏名的宏定义处开始到所在文件的结尾,或用开始到所在文件的结尾,或用开始到所在文件的结尾,或用开始到所在文件的结尾,或用#undefundef命令取消该宏定义为止。例如,在如下程序段计算物体在水命令取消该宏定义为止。例如,在如下程序段计算物体在水命令取消该宏定义为止。例如,在如下程序段计算物体在水命令取消该宏定义为止。例如,在如下程序段计算物体在水中的浮力,中的浮力,中的浮力,中的浮力,#include#include stdio.hstdio.h#define g 9.8#
17、define g 9.8 /*/*宏名宏名宏名宏名g g定义开始定义开始定义开始定义开始*/void main()void main()float F1;float F1;float p,v;float p,v;.printf(F1=%printf(F1=%fnfn,F1);,F1);undefundef g;g;/*/*undefundef 使得使得使得使得g g的宏定义的作用范围到此处为止的宏定义的作用范围到此处为止的宏定义的作用范围到此处为止的宏定义的作用范围到此处为止*/#define g 9.78#define g 9.78 /*/*宏名宏名宏名宏名g g重新定义新的精度重新定义新的
18、精度重新定义新的精度重新定义新的精度*/3/2/2023107.1.2 带参数的宏定义带参数的宏定义格式如下:带参数的宏定义格式如下:带参数的宏定义格式如下:带参数的宏定义格式如下:#define#define 宏名宏名宏名宏名(参数表参数表参数表参数表)字符串字符串字符串字符串宏名一般为大写,参数表可以有一个或多个参数组成,参数之间用逗宏名一般为大写,参数表可以有一个或多个参数组成,参数之间用逗宏名一般为大写,参数表可以有一个或多个参数组成,参数之间用逗宏名一般为大写,参数表可以有一个或多个参数组成,参数之间用逗号分隔。例如案例一中,号分隔。例如案例一中,号分隔。例如案例一中,号分隔。例如案
19、例一中,#define#define F(pF(p,v)(p*9.8*v),v)(p*9.8*v),p p和和和和v v为参数。为参数。为参数。为参数。带参数宏的调用格式如下:带参数宏的调用格式如下:带参数宏的调用格式如下:带参数宏的调用格式如下:宏名宏名宏名宏名(实参表实参表实参表实参表)即将实参替换形参,其他部分不变。即将实参替换形参,其他部分不变。即将实参替换形参,其他部分不变。即将实参替换形参,其他部分不变。例如,假设有例如,假设有例如,假设有例如,假设有#define#define SW(xSW(x)(x)*(x)(x)*(x)如果程序中有语句如果程序中有语句如果程序中有语句如果程序
20、中有语句x=SW(5);x=SW(5);,那么编译系统会将,那么编译系统会将,那么编译系统会将,那么编译系统会将SW(5)SW(5)替换为替换为替换为替换为5*55*5。但。但。但。但输出语句双引号中的宏定义不做替换。例如:输出语句双引号中的宏定义不做替换。例如:输出语句双引号中的宏定义不做替换。例如:输出语句双引号中的宏定义不做替换。例如:#define XYZ this is a test#define XYZ this is a test printf(XYZprintf(XYZ););输出输出输出输出XYZXYZ,而不是,而不是,而不是,而不是this is a testthis is
21、 a test。3/2/202311说明:说明:说明:说明:(1)(1)定义时参数和字符串部分要分别用括号括起来,宏名与参数表的定义时参数和字符串部分要分别用括号括起来,宏名与参数表的定义时参数和字符串部分要分别用括号括起来,宏名与参数表的定义时参数和字符串部分要分别用括号括起来,宏名与参数表的括号之间不要加空格,否则就成为不带参数的宏定义语句了。括号之间不要加空格,否则就成为不带参数的宏定义语句了。括号之间不要加空格,否则就成为不带参数的宏定义语句了。括号之间不要加空格,否则就成为不带参数的宏定义语句了。(2)(2)为了保证在宏展开后,字符串中各个参数的计算顺序正确,应当为了保证在宏展开后,
22、字符串中各个参数的计算顺序正确,应当为了保证在宏展开后,字符串中各个参数的计算顺序正确,应当为了保证在宏展开后,字符串中各个参数的计算顺序正确,应当在宏定义中的字符串最外面以及其中的各个参数外面加上圆括号。在宏定义中的字符串最外面以及其中的各个参数外面加上圆括号。在宏定义中的字符串最外面以及其中的各个参数外面加上圆括号。在宏定义中的字符串最外面以及其中的各个参数外面加上圆括号。例如,比较以下两个例子。例如,比较以下两个例子。例如,比较以下两个例子。例如,比较以下两个例子。#define#define sqr(xsqr(x)(x*x)(x*x)#define sqr(x)(x)*(x)#defi
23、ne sqr(x)(x)*(x)如果在后续程序中有如果在后续程序中有如果在后续程序中有如果在后续程序中有s=s=sqr(a+bsqr(a+b),程序在预处理时会产生不同的结果:,程序在预处理时会产生不同的结果:,程序在预处理时会产生不同的结果:,程序在预处理时会产生不同的结果:sqr(xsqr(x)替换为替换为替换为替换为(a+ba+b*a+ba+b);sqr(xsqr(x)替换为替换为替换为替换为(a+ba+b)*()*(a+ba+b)。(3)(3)在带参宏定义时,也有宏嵌套定义。在带参宏定义时,也有宏嵌套定义。在带参宏定义时,也有宏嵌套定义。在带参宏定义时,也有宏嵌套定义。(4)(4)带参
24、数的宏和函数存在相似之处。例如它们的表示形式都是由一带参数的宏和函数存在相似之处。例如它们的表示形式都是由一带参数的宏和函数存在相似之处。例如它们的表示形式都是由一带参数的宏和函数存在相似之处。例如它们的表示形式都是由一个名字加上几个参数,引用方式也相同,实参和形参的个数都要求个名字加上几个参数,引用方式也相同,实参和形参的个数都要求个名字加上几个参数,引用方式也相同,实参和形参的个数都要求个名字加上几个参数,引用方式也相同,实参和形参的个数都要求相同,但是要注意它们之间的区别。比较以下有参宏和函数的定义:相同,但是要注意它们之间的区别。比较以下有参宏和函数的定义:相同,但是要注意它们之间的区
25、别。比较以下有参宏和函数的定义:相同,但是要注意它们之间的区别。比较以下有参宏和函数的定义:3/2/202312例例例例7.1 7.1 将一表达式分别定义为宏和函数。将一表达式分别定义为宏和函数。将一表达式分别定义为宏和函数。将一表达式分别定义为宏和函数。#include#include#define#define SQR(xSQR(x)(x)*(x)/*)(x)*(x)/*宏定义以宏定义以宏定义以宏定义以#define#define开头,不需要对形参进行数据类型声明,不需对开头,不需要对形参进行数据类型声明,不需对开头,不需要对形参进行数据类型声明,不需对开头,不需要对形参进行数据类型声明,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 预处理
限制150内