第9章预处理命令
1 第9章 预处理命令
9.0编译预处理概述 C源程序编译之前,编译程序将对它作至少两 个阶段的编译预处理。 编译程序预处理阶段 编译程序首先将源程序代码中的注解替换成空 格字符;例如: int/变量sum用于存放两个数的和*sum; 将替换成: int sum 然后查找源代码中由续行符(反斜线后紧跟换行 符)组成的物理行,并把它们合并成一个逻辑行;例 如:
2 9.0 编译预处理概述 C源程序编译之前,编译程序将对它作至少两 个阶段的编译预处理。 编译程序预处理阶段 编译程序首先将源程序代码中的注解替换成空 格字符;例如: int /*变量sum用于存放两个数的和*/ sum ; 将替换成: int sum ; 然后,查找源代码中由续行符(反斜线后紧跟换行 符)组成的物理行,并把它们合并成一个逻辑行;例 如:
printf(“ That's wond erfu!”) 将合并成: printf ("Thats wonderful 最后,对源代码中的那些仅用空白字符作分隔符 的多个字符串直接量进行连接。例如: printf(“ A string is a sequence of characters” “ surrounded by” “ double quotes.”) 将连接成: printf ("a string is a sequence of characters surrounded by double quotes. )i
3 printf ( “That’s wond\ erful!” ) ; 将合并成: printf ( “That’s wonderful!” ) ; 最后,对源代码中的那些仅用空白字符作分隔符 的多个字符串直接量进行连接。例如: printf ( “A string is a sequence of characters” “surrounded by” “double quotes.” ) ; 将连接成: printf ( “A string is a sequence of characters surrounded by double quotes.” ) ;
预处理程序预处理阶段 C源程序中像# define、# include…等这类特 别代码: 称之为“预处理命令”,一共有三类 (1)宏定义命令 (2)文件包含命令 (3)条件编译命令 ■它们由C语言预处理程序解释 ■不是C语言本身的语言成分,它们有自己的独 立语法:
4 预处理程序预处理阶段 C源程序中像#define、 #include…..等这类特 别代码: 称之为“预处理命令” , 一共有三类: (1) 宏定义命令 (2) 文件包含命令 (3) 条件编译命令 它们由C语言预处理程序 解释 不是C语言本身的语言成分,它们有自己的独 立语法:
一条预处理指令写在一行上(逻辑行 预处理命令行可插入在源程序文件中的任何行中。 必须以#号开头,预处理命令的内容跟在#号之后, 允许在#号的前后插入若干(至少一个)空格或制表 符。(注:允许仅由单一的#号组成的空预处理命令行 空预处理指令行没有作用,处理时总被忽略)。 ■预处理命令的作用域是从该行所在位置起到它所 在的源文件的未尾 新行(回车换行符)字符作为行结束符
5 一条预处理指令写在一行上(逻辑行) 预处理命令行可插入在源程序文件中的任何行中。 必须以#号开头,预处理命令的内容跟在#号之后, 允许在#号的前后插入若干(至少一个)空格或制表 符。(注:允许仅由单一的#号组成的空预处理命令行, 空预处理指令行没有作用,处理时总被忽略)。 预处理命令的作用域是从该行所在位置起到它所 在的源文件的末尾。 新行(回车换行符)字符作为行结束符
在预处理程序预处理阶段,预处理程序扫描插入 在源程序文件中的预处理命令,并实现预处理命令 规定的功能。经预处理程序处理后的源程序文件, 再交给编译程序作编译处理。 c预处理程序扩充了C语言的处理能力及程序设 计环境,为有效地开发C语言程序提供了便利。 本章将介绍各种预处理命令的功能与使用
6 在预处理程序预处理阶段,预处理程序扫描插入 在源程序文件中的预处理命令,并实现预处理命令 规定的功能。经预处理程序处理后的源程序文件, 再交给编译程序作编译处理。 C预处理程序扩充了C语言的处理能力及程序设 计环境,为有效地开发C语言程序提供了便利。 本章将介绍各种预处理命令的功能与使用
9宏定义 所谓宏定义是指用一个标识符来代替一个字 符序列,因此也称之为标识符替换。 宏定义用预处理命令# define进行。 有两种宏定义形式: 一种为类对象宏( object-like macro),这是无 参数形式的宏定义; 另一种为类函数宏( function-like macro)它是 带参数形式的宏定义
7 9.1 宏定义 所谓宏定义是指用一个标识符来代替一个字 符序列,因此也称之为标识符替换。 宏定义用预处理命令 #define 进行。 有两种宏定义形式: 一种为类对象宏(object-like macro),这是无 参数形式的宏定义; 另一种为类函数宏(function-like macro),它是 带参数形式的宏定义
类对象宏定义 类对象宏定义是一种最简单的宏定义,其一般形 式为: # define宏名宏主体 其中: 宏名( macro name)按标识符规则确定。 习惯上宏名用大写字母表示但这不是规定,可 用小写字母 宏名前后至少有一个空格以便与前面的 define 及其后的字符序列之间隔开
8 1、类对象宏定义 类对象宏定义是一种最简单的宏定义,其一般形 式为: #define 宏名 宏主体 其中: 宏名(macro name)按标识符规则确定。 习惯上宏名用大写字母表示但这不是规定,可 用小写字母。 宏名前后至少有一个空格以便与前面的 define 及其后的字符序列之间隔开
宏主体也称之为替换列表,是语言符号组成的 字符序列(注:可以为空,不是C字符串) 例如: #define four 2*2 类对象宏定义的作用是用宏名这个标识符来表 示随后的宏主体部分给定的字符序列 在预处理程序扫描源文件时,每遇到一个宏名, 便用宏主体部分所指定的字符序列替换(替换过程 称为“宏展开”)。注意:包含在字符串常量中的 宏名和位于注解行中的宏名不被替换牣如:
9 宏主体 也称之为替换列表,是语言符号组成的 字符序列(注:可以为空,不是C字符串)。 例如: #define FOUR 2*2 类对象宏定义的作用是用宏名这个标识符来表 示随后的宏主体部分给定的字符序列。 在预处理程序扫描源文件时,每遇到一个宏名, 便用宏主体部分所指定的字符序列替换(替换过程 称为“宏展开”)。注意:包含在字符串常量中的 宏名和位于注解行中的宏名不被替换!例如:
#define yes 1.o #define tabsize 10n tableTabsizej; man y= YES 将被替换成: 将被替换成: table [100; y=1.0; float y i in table( ABSIZEI字符串中 的YES将不 y=YES 被替换 printf(TYES)%f”,y);
10 #define YES 1.0 #define TABSIZE 100 main ( ) { float y ; int table [ TABSIZE ] ; y = YES ; printf ( "YES = %f " , y ) ; } table[TABSIZE]; 将 被 替 换 成 : table [100] ; y = YES ; 将被替换成: y = 1.0 ; 字符 串中 的 YES将不 被替换