9.1宏定义9.2文件包含处理9.3条件编译习题(精)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C提供的预处理功能主要有以下三种: 1. 宏定义 2. 文件包含 3. 条件编译 分别用宏定义命令、文件包含命令、条件编译命令 来实现。为了与一般C语句相区别,这些命令以符号 “#”开头。
9.1 宏定义
9.1.1 不带参数的宏定义 用一个指定的标识符(即名字)来代表一个字符串, 它的一般形式为#define 标识符字符串。这就是已 经介绍过的定义符号常量。 如:#definePI3.1415926它的作用是指定用标识 符PI来代替“3.1415926”这个字符串,在编译预 处理时,将程序中在该命令以后出现的所有的PI都 用“3.1415926”代替。这种方法使用户能以一个 简单的名字代替一个长的字符串,因此把这个标识 符(名字)称为“宏名”,在预编译时将宏名替换成 字符串的过程称为“宏展开”。#define是宏定义 命令。
(3) 宏定义是用宏名代替一个字符串,也就是作简 单的置换,不作正确性检查。如果写成 #define PI 3.l4l59 即把数字1写成小写字母l,预处理时也照样代入, 不管含义是否正确。也就是说预编译时不作任何语 法检查。只有在编译已被宏展开后的源程序时才会 发现错误并报错。 (4) 宏定义不是C语句,不必在行末加分号。如果加 了分号则会连分号一起进行置换。如: #define PI 3.1415926; area=PI*r*r;
运行情况如下: L=18.849556 s=28.274333 经过宏展开后,printf函数中的输出项L被展开为 2*3.1415926*3.0,S展开为 3.1415926*3.0*3.0,printf函数调用语句展开 为printf("L=%f\ns=%f\n", 2*3.1415926*3.0,3.1415926*3.0*3.0); (8) 对程序中用双括号括起来的字符串内的字符, 即使与宏名相同,也不进行置换。如例9.2中的 printf函数内有两个l字符,一个在双引号内,它不 被宏置换,另一个在双引号外,被宏置换展开。
第9章
预处理命令
9.1 宏定义 9.2 “文件包含”处理 9.3 条件编译 习题
ANSI C标准规定可以在C源程序中加入一些“预处 理命令”(preprocessor DireCtiveS) ,以改进程 序设计环境,提高编程效率。这些预处理命令是由 ANSI C统一规定的,但是它不是C语言本身的组成 部分,不能直接对它们进行编译(因为编译程序不能 识别它们)。必须在对程序进行通常的编译(包括词 法和语法分析、代码生成、优化等)之前,先对程序 中这些特殊的命令进行“预处理”, 即根据预处理 命令对程序作相应的处理(例如,若程序中用 #define命令定义了一个符号常量A,则在预处理时 将程序中所有的A都置换为指定的字符串。若程序 中用#inClude命令包含一个文件“StDio.h”,
则在预处理时将StDio.h文件中的实际内容代替该 命令)。经过预处理后程序不再包括预处理命令了,最 后再由编译程序对预处理后的源程序进行通常的编译 处理,得到可供执行的目标代码。现在使用的许多C 编译系统都包括了预处理、编译和连接等部分,在进 行编译时一气呵成。因此不少用户误认为预处理命令 是C语言的一部分,甚至以为它们是C语句,这是不对 的。必须正确区别预处理命令和C语句、区别预处理 和编译,才能正确使用预处理命令。C语言与其他高 级语言的一个重要区别是可以使用预处理命令和具有 预处理的功能。
例9.1 #define PI 3.1415926 main() {float l,s,r,v; printf("input raDiuS∶"); scanf("%f",&r); l=2.0*PI*r; s=PI*r*r; v=3.0/4*PI*r*r*r; printf("l=%10.4f\nS=%10.4f\nv=%10.4f\n", l,s,v); }
运行情况如下: input radius:4 l=25.1328 s=50.2655 v=150.7966 说明: (1) 宏名一般习惯用大写字母表示,以便与变量名相 区别。但这并非规定,也可用小写字母。 (2) 使用宏名代替一个字符串,可以减少程序中重复 书写某些字符串的工作量。例如,如果不定义PI代表 3.1415926,则在程序中要多处出现3.1415926, 不仅麻烦,而且容易写错(或敲错),用宏名代替,
#define g 8.8 main() { |
… } #undef g f1() { … } 由于#undef的作用,使G的作用范围在#undef行处终止, 因此在f1函数中,g不再代表8.8。这样可以灵活控制宏定义 的作用范围。
G的有效范围
(7) 在进行宏定义时,可以引用已定义的宏名,可 以层层置换。 例9.2 #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main() { printf("L=%f\ns=%f\n",L,S); }
经过宏展开后,该语句为 area=3.1415926;*r*r; 显然出现语法错误。 (5) #define命令出现在程序中函数的外面,宏名的 有效范围为定义命令之后到本源文件结束。通常, #define命令写在文件开头,函数之前,作为文件 一部分,在此文件范围内有效。பைடு நூலகம்(6) 可以用#undef命令终止宏定义的作用域。例如:
简单不易出错,因为记住一个宏名(它的名字往往 用容易理解的单词表示)要比记住一个无规律的字符 串容易,而且在读程序时能立即知道它的含义,当需 要改变某一个常量时,可以只改变#define命令行, 一改全改。例如,定义数组大小,可以用 #define array- size 1000 int array[array-size]; 先指定array-size代表常量1000,因此数组array 大小为1000,如果需要改变数组大小,只需改 #define行: #define array-size 500 使用宏定义,可以提高程序的通用性。