kj-第8章预处理命令课件.ppt
《kj-第8章预处理命令课件.ppt》由会员分享,可在线阅读,更多相关《kj-第8章预处理命令课件.ppt(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第8章章 预处理命令预处理命令l本章概述 l本章的学习目标l主要内容l本章概述l本章介绍宏定义的两种形式,介本章介绍宏定义的两种形式,介绍文件包含的使用方法绍文件包含的使用方法,介绍条件介绍条件编译的概念。编译的概念。第第8章章 预处理命令预处理命令本章的学习目标本章的学习目标: 本章教学目的:本章教学目的: 掌握宏定义的两种形式,掌握文掌握宏定义的两种形式,掌握文件包含的使用方法了解条件编译的概念。件包含的使用方法了解条件编译的概念。 本章教学重点:本章教学重点: 宏定义的两种形式,文件包含的宏定义的两种形式,文件包含的使用方法。使用方法。 本章教学难点:本章教学难点: 带参数的宏定义。带
2、参数的宏定义。第第8章章 预处理命令预处理命令第第8章章 预处理命令预处理命令l8.1 宏定义宏定义 l8.2 “文件包含文件包含”处理处理 l8.3 条件编译条件编译 l8.4 本章小结本章小结主要内容主要内容: 编译预处理是指一些行首以编译预处理是指一些行首以# #开头的特殊语句,必须在对开头的特殊语句,必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理预处理”,即根据预处理命令对程序作相应的处理(例如,即根据预处理命令对程序作相应的处理(例如,若程序中用若程序中用# define# define命令定义了一个符号常量命
3、令定义了一个符号常量A A,则在预处理,则在预处理时将程序中所有的时将程序中所有的A A都置换为指定的字符串)。经过预处理后都置换为指定的字符串)。经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。的源程序进行通常的编译处理,得到可供执行的目标代码。C C语言与其它高级语言的一个重要区别是可以使用预处理命令语言与其它高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。和具有预处理的功能。第8章 预处理命令C提供的预处理功能主要有以下三种:提供的预处理功能主要有以下三种
4、: 宏定义、文件包含和条件编译宏定义、文件包含和条件编译它们分别用宏定义命令、文件包含命令和条件编译命令来实现。为了与一般C语句相区别,这些命令以符号“”开头。 8.1 宏定义 宏定义指的是用宏定义指的是用#define定义的命令行,有不带定义的命令行,有不带参数和带参数两种形式。参数和带参数两种形式。 8.1.1 不带参数的宏定义不带参数的宏定义不带参数的宏定义的一般形式为:不带参数的宏定义的一般形式为: # define # define 标识符标识符 字符串字符串含义是用指定的宏名(即标识符)来代表其后字符串。含义是用指定的宏名(即标识符)来代表其后字符串。 例如例如: #define
5、SIZE 10000#define SIZE 10000 #define PI 3.1415926 #define PI 3.1415926 #define FORMAT “%d#define FORMAT “%d,%d%d,%dn”%dn”作用是指用标识符作用是指用标识符SIZESIZE来代替字符串来代替字符串“1000010000”,用标识符用标识符PIPI来代替字符串来代替字符串“3.14159263.1415926”,用标识符用标识符FORMATFORMAT来代替字符串来代替字符串“ “%d “%d,%d%d,%dn” %dn” ”, 在编译预处理时,将程序中在该命令以后出现的所有的在
6、编译预处理时,将程序中在该命令以后出现的所有的SIZESIZE用用1000010000代替、代替、PIPI用用3.14159263.1415926代替、代替、FORMATFORMAT用用“%d“%d,%d%d,%dn”%dn”代代替。这种方法使用户能以一个简单的名字代替一个长的字符串,可替。这种方法使用户能以一个简单的名字代替一个长的字符串,可以减小重复编程工作量,而且不容易出错。以减小重复编程工作量,而且不容易出错。 把定义时所用的标识符称为把定义时所用的标识符称为“宏名宏名”,即,即SIZESIZE、PIPI和和FORMATFORMAT都是都是宏名。在预编译时将宏名替换成字符串的过程称为宏
7、名。在预编译时将宏名替换成字符串的过程称为“宏展开宏展开”。注意:宏名习惯用大写字母表示。定义宏与定义变量含义不同,宏定注意:宏名习惯用大写字母表示。定义宏与定义变量含义不同,宏定义只是作字符替换,并不给宏名分配内存空间。义只是作字符替换,并不给宏名分配内存空间。 例例8.1 # include #define SIZE 5int main() int i,sum=0; int dataSIZE; for(i=0;iSIZE;i+) scanf(“%d”,&datai); sum=sum+datai; printf(“sum=%dn”,sum); return 0; 运行此程序可计算运行此程序
8、可计算5个数组元素值的总和。个数组元素值的总和。对宏定义的说明:对宏定义的说明: (1)(1)定义宏的目的是提高程序的可读性和通用性,便于程序的修定义宏的目的是提高程序的可读性和通用性,便于程序的修改。例如若要把例改。例如若要把例8.18.1中数组中数组datadata的元素个数改变为的元素个数改变为1010,则只要将,则只要将“#define SIZE 5#define SIZE 5”改为改为“#define SIZE 10#define SIZE 10”即可,程序中的其它语即可,程序中的其它语句均不用修改。句均不用修改。 (2) (2)不要在宏定义的行末加分号,因为宏定义不是不要在宏定义的
9、行末加分号,因为宏定义不是C C语句,加分号语句,加分号后,会将分号也作为字符串的组成部分,宏展开后可能出现错误。后,会将分号也作为字符串的组成部分,宏展开后可能出现错误。 (3) (3)宏定义可以出现在程序的任何位置,一般位于文件开头,写在宏定义可以出现在程序的任何位置,一般位于文件开头,写在函数的外面。宏名的有效范围是从定义处到本源文件结束。可以用函数的外面。宏名的有效范围是从定义处到本源文件结束。可以用#undef#undef命令终止宏定义的作用域。例如:命令终止宏定义的作用域。例如: #define PI 3.1415926#define PI 3.1415926 int main()
10、int main() #undef PI#undef PI 由于由于#undef#undef的作用,使的作用,使PIPI的作用范围在的作用范围在#undef#undef行处终止。若在行处终止。若在#undef PI#undef PI之后再出现之后再出现PIPI,则是无效的。,则是无效的。 (4)(4)宏定义是用宏名代替一个字符串,凡在宏定义有效范围内的宏名都宏定义是用宏名代替一个字符串,凡在宏定义有效范围内的宏名都用该字符串代替,但要注意:双引号内的与宏名相同的字符串不认为是宏用该字符串代替,但要注意:双引号内的与宏名相同的字符串不认为是宏名,不进行替换。名,不进行替换。 例如:例如: #de
11、fine YES 1#define YES 1 printf(“YES”);printf(“YES”); 程序将显示程序将显示YESYES,而不是,而不是1 1。 (5)(5)可以引用前面已经定义的宏名来定义新的宏,例如:可以引用前面已经定义的宏名来定义新的宏,例如: define I1 30define I1 30 define I2 60define I2 60 define J I1+I2define J I1+I2 define K Jdefine K J* *2+J/2+I22+J/2+I2 这里这里J J引用了引用了I1I1和和I2I2,K K引用了引用了J J和和I2I2。 注意
12、注意K K展开是:展开是:30+6030+60* *2+30+60/2+602+30+60/2+60, 不要以为是:不要以为是:(30+60)(30+60)* *2+(30+60)/2+602+(30+60)/2+60。 除非前面的定义是:除非前面的定义是:define J (I1+I2)define J (I1+I2)。8.1.2 带参数的宏定义带参数的宏定义 带参数的宏定义的一般形式为:带参数的宏定义的一般形式为: #define#define标识符标识符( (形参表形参表) ) 字符串字符串 带参数的宏展开时,还要进行参数替换。宏定义中形参表中的形带参数的宏展开时,还要进行参数替换。宏定
13、义中形参表中的形参,在程序中将用实参替换。参,在程序中将用实参替换。例如:例如: #define PI 3.14159 #define PI 3.14159 #define V(r) 4 #define V(r) 4* *PIPI* *r r* *r r* *r/3r/3 V(r)V(r)为带参数的宏,例如在程序中使用为带参数的宏,例如在程序中使用V(6)V(6)时,是用时,是用6 6代替宏定代替宏定义中的形式参数义中的形式参数r r,V(6)V(6)展开为:展开为:4 4* *3.141593.14159* *6 6* *6 6* *6/36/3,这是用来计,这是用来计算半径为算半径为6 6
14、的球的体积。的球的体积。 l例8.2l # include l #define S(a, b, h) (a+b)*h/2l int main()l int c1=6,c2=8,c3=10;l printf(“S=%dn”,S(c1, c2, c3);l return 0;l S(c1,c2,c3)展开为:展开为:(c1+c2)*c3/2。程序实际执行的是下面的。程序实际执行的是下面的输出语句:输出语句: printf(“S=%dn”,(c1+c2)*c3/2); 如果将上面的如果将上面的S(c1,c2,c3)换成换成S(6, c2, 2+8),运行程序,运行程序后,输出结果还是后,输出结果还是
15、70吗?吗? 在使用带参数的宏定义时,宏名和括号之间不能有空格,否则系统会把在使用带参数的宏定义时,宏名和括号之间不能有空格,否则系统会把括号、形参和字符串认为是一个字符串。括号、形参和字符串认为是一个字符串。 例如,如果有例如,如果有 define S (x,y) xdefine S (x,y) x* *y y 会被认为:会被认为: S S是符号常量(不带参的宏名),它代表字符串是符号常量(不带参的宏名),它代表字符串“(x,y) x(x,y) x* *y y”。 上面介绍的用带参数的宏求球的体积和梯形的面积等问题显然也可以用函上面介绍的用带参数的宏求球的体积和梯形的面积等问题显然也可以用函
16、数解决。数解决。 带参数的宏和函数在形式上有相似的地方,但是它们有许多不同点:带参数的宏和函数在形式上有相似的地方,但是它们有许多不同点: (1)(1)宏展开是在编译时进行的,不占用程序运行时间,在展开时并不分配宏展开是在编译时进行的,不占用程序运行时间,在展开时并不分配内存单元,即使是带参数的宏也不分配内存单元;而函数调用则是在程序运内存单元,即使是带参数的宏也不分配内存单元;而函数调用则是在程序运行时进行处理的,占用程序运行时间,要为形参分配临时的内存单元。行时进行处理的,占用程序运行时间,要为形参分配临时的内存单元。 (2) (2) 宏展开只是替换;而函数调用时,要计算实参表达式的值后传
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- kj 预处理 命令 课件
限制150内