清华大学出版社 TSINGHUA UNIVERSITY PRESS 第9章 预处理命令 9.1 宏定义 9.2 “文件包含”处理 9.3 条件编译 习题
9.1 宏定义 9.2 “文件包含”处理 9.3 条件编译 习题 第9章 预处理命令
清华大学出版社 TSINGHUA UNIVERSITY PRESS ANSI C标准规定可以在C源程序中加入一些“预处 理命令”(preprocessor DireCtiveS),以改进程序 设计环境,提高编程效率。这些预处理命令是由 ANSI C:统一规定的,但是它不是C语言本身的组 成部分,不能直接对它们进行编译(因为编译程序 不能识别它们)。必须在对程序进行通常的编译(包 括词法和语法分析、代码生成、优化等)之前,先 对程序中这些特殊的命令进行“预处理”,即根 据预处理命令对程序作相应的处理(例如,若程序 中用#define命令定义了一个符号常量A,则在预 处理时将程序中所有的A都置换为指定的字符串。 若程序中用#inClude命令包含一个文件“StDio.h
ANSI C标准规定可以在C源程序中加入一些“预处 理命令”(preprocessor DireCtiveS) ,以改进程序 设计环境,提高编程效率。这些预处理命令是由 ANSI C统一规定的,但是它不是C语言本身的组 成部分,不能直接对它们进行编译(因为编译程序 不能识别它们)。必须在对程序进行通常的编译(包 括词法和语法分析、代码生成、优化等)之前,先 对程序中这些特殊的命令进行“预处理”, 即根 据预处理命令对程序作相应的处理(例如,若程序 中用#define命令定义了一个符号常量A,则在预 处理时将程序中所有的A都置换为指定的字符串。 若程序中用#inClude命令包含一个文件“StDio.h
清华大学出版社 TSINGHUA UNIVERSITY PRESS 则在预处理时将StDio.h文件中的实际内容代替该命 令)。经过预处理后程序不再包括预处理命令了,最 后再由编译程序对预处理后的源程序进行通常的编 译处理,得到可供执行的目标代码。现在使用的许 多C编译系统都包括了预处理、编译和连接等部分, 在进行编译时一气呵成。因此不少用户误认为预处 理命令是C语言的一部分,甚至以为它们是C语句, 这是不对的。必须正确区别预处理命令和C语句、 区别预处理和编译,才能正确使用预处理命令。C 语言与其他高级语言的一个重要区别是可以使用预 处理命令和具有预处理的功能
则在预处理时将StDio.h文件中的实际内容代替该命 令)。经过预处理后程序不再包括预处理命令了,最 后再由编译程序对预处理后的源程序进行通常的编 译处理,得到可供执行的目标代码。现在使用的许 多C编译系统都包括了预处理、编译和连接等部分, 在进行编译时一气呵成。因此不少用户误认为预处 理命令是C语言的一部分,甚至以为它们是C语句, 这是不对的。必须正确区别预处理命令和C语句、 区别预处理和编译,才能正确使用预处理命令。C 语言与其他高级语言的一个重要区别是可以使用预 处理命令和具有预处理的功能
清华大学出版社 TSINGHUA UNIVERSITY PRESS C提供的预处理功能主要有以下三种: 1.宏定义 2.文件包含 3.条件编译 分别用宏定义命令、文件包含命令、条件编译命令 来实现。为了与一般C语句相区别,这些命令以符 号“#》开头
C提供的预处理功能主要有以下三种: 1. 宏定义 2. 文件包含 3. 条件编译 分别用宏定义命令、文件包含命令、条件编译命令 来实现。为了与一般C语句相区别,这些命令以符 号“#”开头
清华大学出版社 TSINGHUA UNIVERSITY PRESS 9.1宏定义 9.1.1不带参数的宏定义 用一个指定的标识符(即名字)来代表一个字符串, 它的一般形式为#define标识符字符串。这就是已 经介绍过的定义符号常量。 如#defineP3.1415926它的作用是指定用标识符 PI来代替“3.1415926”这个字符串,在编译预处 理时,将程序中在该命令以后出现的所有的P都 用“3.1415926”代替。这种方法使用户能以一个 简单的名字代替一个长的字符串,因此把这个标 识符(名字)称为“宏名”,在预编译时将宏名替 换成字符串的过程称为“宏展开”。#define-是宏 定义命令
9.1 宏定义 9.1.1 不带参数的宏定义 用一个指定的标识符(即名字)来代表一个字符串, 它的一般形式为#define 标识符字符串。这就是已 经介绍过的定义符号常量。 如:#definePI3.1415926它的作用是指定用标识符 PI来代替“3.1415926”这个字符串,在编译预处 理时,将程序中在该命令以后出现的所有的PI都 用“3.1415926”代替。这种方法使用户能以一个 简单的名字代替一个长的字符串,因此把这个标 识符(名字)称为“宏名”,在预编译时将宏名替 换成字符串的过程称为“宏展开”。#define是宏 定义命令
清华大学出版社 TSINGHUA UNIVERSITY PRESS 例9.1 #define PI 3.1415926 mainO {floatl,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"=%10.4fnS=%10.4fnv=%10.4fn",1,s, V)为
例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); }
清华大学出版社 TSINGHUA UNIVERSITY PRESS 运行情况如下: input radius:4 =25.1328 s=50.2655 v=150.7966 说明: (1)宏名一般习惯用大写字母表示,以便与变量名相 区别。但这并非规定,也可用小写字母。 (2)使用宏名代替一个字符串,可以减少程序中重复 书写某些字符串的工作量。例如,如果不定义P代 表3.1415926,则在程序中要多处出现3.1415926,不 仅麻烦,而且容易写错(或敲错),用宏名代替
运行情况如下: input radius:4 l=25.1328 s=50.2655 v=150.7966 说明: (1) 宏名一般习惯用大写字母表示,以便与变量名相 区别。但这并非规定,也可用小写字母。 (2) 使用宏名代替一个字符串,可以减少程序中重复 书写某些字符串的工作量。例如,如果不定义PI代 表3.1415926,则在程序中要多处出现3.1415926,不 仅麻烦,而且容易写错(或敲错),用宏名代替
清华大学出版社 TSINGHUA UNIVERSITY PRESS 简单不易出错,因为记住一个宏名(它的名字往往 用容易理解的单词表示)要比记住一个无规律的字 符串容易,而且在读程序时能立即知道它的含义, 当需要改变某一个常量时,可以只改变#define命令 行,一改全改。例如,定义数组大小,可以用 #define array-size 1000 int array[array-size]; 先指定array-sizc代表常量1000,因此数组array大小 为1000,如果需要改变数组大小,只需改#define 行: #define array-size 500 使用宏定义,可以提高程序的通用性
简单不易出错,因为记住一个宏名(它的名字往往 用容易理解的单词表示)要比记住一个无规律的字 符串容易,而且在读程序时能立即知道它的含义, 当需要改变某一个常量时,可以只改变#define命令 行,一改全改。例如,定义数组大小,可以用 #define array- size 1000 int array[array-size]; 先指定array-size代表常量1000,因此数组array大小 为1000,如果需要改变数组大小,只需改 #define 行: #define array-size 500 使用宏定义,可以提高程序的通用性
清华大学出版社 TSINGHUA UNIVERSITY PRESS 3)宏定义是用宏名代替一个字符串,也就是作简单 的置换,不作正确性检查。如果写成 #define PI 3.14159 即把数字1写成小写字母1,预处理时也照样代入, 不管含义是否正确。也就是说预编译时不作任何 语法检查。只有在编译已被宏展开后的源程序时 才会发现错误并报错。 (4)宏定义不是C语句,不必在行末加分号。如果加 了分号则会连分号一起进行置换。如: #define PI 3.1415926; area=PI*r*r;
(3) 宏定义是用宏名代替一个字符串,也就是作简单 的置换,不作正确性检查。如果写成 #define PI 3.l4l59 即把数字1写成小写字母l,预处理时也照样代入, 不管含义是否正确。也就是说预编译时不作任何 语法检查。只有在编译已被宏展开后的源程序时 才会发现错误并报错。 (4) 宏定义不是C语句,不必在行末加分号。如果加 了分号则会连分号一起进行置换。如: #define PI 3.1415926; area=PI*r*r;
清华大学出版社 TSINGHUA UNIVERSITY PRESS 经过宏展开后,该语句为 area=3.1415926;*r*r; 显然出现语法错误。 (⑤)#define命令出现在程序中函数的外面,宏名的有 效范围为定义命令之后到本源文件结束。通常, #define命令写在文件开头,函数之前,作为文件 一部分,在此文件范围内有效。 (6)可以用#undef命令终止宏定义的作用域。例如:
经过宏展开后,该语句为 area=3.1415926;*r*r; 显然出现语法错误。 (5) #define命令出现在程序中函数的外面,宏名的有 效范围为定义命令之后到本源文件结束。通常, #define命令写在文件开头,函数之前,作为文件 一部分,在此文件范围内有效。 (6) 可以用#undef命令终止宏定义的作用域。例如: