4.10编译预处理 所谓编译预处理就是编译器在对源程序进行正式编译前,根据 预处理指令先做一些特殊的处理工作,然后将源程序与预处理 的结果一起进行编译。 C++语言的预处理主要包括3方面的操作:嵌入指令、宏定 义和条件编译指令 应当说明的是,编译预处理指令不属于++语言的语法范畴。 因此,预处理指令具有其特有语法:起始字符必须为“#, 并以“回车”结束
4.10 编译预处理 所谓编译预处理就是编译器在对源程序进行正式编译前,根据 预处理指令先做一些特殊的处理工作,然后将源程序与预处理 的结果一起进行编译。 C++ 语言的预处理主要包括 3 方面的操作:嵌入指令、宏定 义和条件编译指令。 应当说明的是,编译预处理指令不属于 C++ 语言的语法范畴。 因此,预处理指令具有其特有语法:起始字符必须为 “#”, 并以“回车”结束
10.1嵌入指令 嵌入指令的一般形式为: Include d #include"file name 其中: file name是一个可以带有全路径的文本文件名。例如: include include"C: mypathlahead h 嵌入指令的作用是指示编译器将 file name所指定的文本文 件插入到该指令所在的位置,然后再进行编译。例如: ∥/ MAINPROG. CPP INCFILE. CPP #include incfile cpp #include void maino void f(void cout < Helloin
4.10.1 嵌入指令 嵌入指令的一般形式为: #include 或 #include "file_name" 其中:file_name 是一个可以带有全路径的文本文件名。例如: #include #include "C:\mypath\ahead.h" 嵌入指令的作用是指示编译器将 file_name 所指定的文本文 件插入到该指令所在的位置,然后再进行编译。例如: // MAINPROG.CPP // INCFILE.CPP #include "incfile.cpp" #include void main() void f(void) { { f(); cout << "Hello\n"; } }
则经编译器预处理后,文件 MAINPROG. CPP将变成如下的 形式 ∥/ MAINPROG. CPP ∥/这里是 NCFILE CPP中的内容 ∥这里是 iostream. h中的内容 void f(void) cout < Hello void main(
则经编译器预处理后,文件 MAINPROG.CPP 将变成如下的 形式: // MAINPROG.CPP // 这里是 INCFILE.CPP 中的内容 // 这里是 iostream.h 中的内容 void f(void) { cout << "Hello\n"; } void main() { f(); }
4.10.2宏 4.10.2.1无参宏定义 define macro mame text 其中: macro name是一个标识符,它是程序员为宏所取的 名字;可选的text是一段文本,叫做替换正文,它就是程序 员为宏所作的具体定义。例如 define ONE 1 #define TWO 2 将使编译器把源程序中所有的ONE都解释成1:所有的 TWO解释成2
4.10.2 宏 4.10.2.1 无参宏定义 #define macro_mame 其中:macro_name 是一个标识符,它是程序员为宏所取的 名字;可选的 text 是一段文本,叫做替换正文,它就是程序 员为宏所作的具体定义。例如: #define ONE 1 #define TWO 2 将使编译器把源程序中所有的 ONE 都解释成 1;所有的 TWO 解释成 2
几点说明: 1.宏定义必须以“注意:由于编译器在宏替换时是逐级进行 均属于宏定义 的,所以在定义宏时要防止出现二义性。 例如,若将宏 THREE定义成: define TRUE define THREE ONE TWO 将使得编译器把宏则赋值语句: 2.宏定义的替换正 i= THREE* 3: # efine_MYHE将使i的值为7,而不是预期的9。 这里,将标识符N编译器对该语句的解释过程为: 编译预处理指令进 i=1+2*3 3.替换正文可以是 i=1+6 #define UL 7 4.一个已存在的宏可以用作另一个宏定义的替换正文: define THREE (ONE TWO)
几点说明: 1. 宏定义必须以“回车”结束,“回车”符前边所有的字符 均属于宏定义: #define TRUE 1; 将使得编译器把宏 TRUE 解释成 1;。 2. 宏定义的替换正文可以为空: #define _MYHEAD_H_ 这里,将标识符 _MYHEAD_H_ 作为一个标志,以便于条件 编译预处理指令进行测试。 3. 替换正文可以是 C++ 语言的关键字: #define UL unsigned long int 4. 一个已存在的宏可以用作另一个宏定义的替换正文: #define THREE (ONE + TWO) 注意:由于编译器在宏替换时是逐级进行 的,所以在定义宏时要防止出现二义性。 例如,若将宏 THREE定义成: #define THREE ONE + TWO 则赋值语句: i = THREE * 3; 将使 i 的值为 7,而不是预期的 9。 编译器对该语句的解释过程为: i = ONE + TWO * 3; i = 1 + 2 * 3; i = 1 + 6; i = 7;
4.10.2.2定义带参宏 define macro name (arg list) text 其中, arg list为宏的形参表。例如: # efine MA(xy)(x)>=()?(x):(y) 这时,宏MAX就如同一个带参数的内联函数。例如: m= MAX(a, b); cout < MAX(3*i/k, 4+j*k)<<endl 注意:由于带参宏出现二义性的可能性更大,所以在实用中建 议多用内联函数而少用带参宏
4.10.2.2 定义带参宏 #define macro_name(arg_list) text 其中,arg_list 为宏的形参表。例如: #define MAX(x, y) ((x) >= (y) ? (x) : (y)) 这时,宏 MAX 就如同一个带参数的内联函数。例如: m = MAX(a, b); cout << MAX(3 * i / k, 4 + j * k) << endl; 注意:由于带参宏出现二义性的可能性更大,所以在实用中建 议多用内联函数而少用带参宏
4.10.2.3# undef指令 #undef macro name 该指令的作用是撤消对宏 macro name的定义。例如: #define MAXLEN 512 ∥对宏 MAXLEN的一些应用 #undef MAXLEN #define MAXLEN 128 ∥对宏 MAXLEN的一些应用
4.10.2.3 #undef 指令 #undef macro_name 该指令的作用是撤消对宏 macro_name 的定义。例如: #define MAXLEN 512 // 对宏 MAXLEN 的一些应用 #undef MAXLEN #define MAXLEN 128 // 对宏 MAXLEN 的一些应用
4.10.3条件编译 条件编译指令是用来控制编译器有选择地对源程序进行编译 的。它们指示编译器可以忽略除#,#idef,# ifndef,#elf 和#endf指令外的所有预处理指令,以及由于条件编译指令 的结果而不用参加编译的行
4.10.3 条件编译 条件编译指令是用来控制编译器有选择地对源程序进行编译 的。它们指示编译器可以忽略除 #if,#ifdef,#ifndef,#elif 和 #endif 指令外的所有预处理指令,以及由于条件编译指令 的结果而不用参加编译的行
4.10.3.1#f,#ei,#else和# endif条件指令 这几条预处理指令与C++语言中的语句类似。例 #include define NUM 100 void maino #fNUM==100 cout <<This line is compiled\n ielse cout <<This line is not compiled fendi
4.10.3.1 #if,#elif,#else 和 #endif 条件指令 这几条预处理指令与 C++ 语言中的 if 语句类似。例: #include #define NUM 100 void main() { #if NUM == 100 cout << "This line is compiled\n"; #else cout << "This line is not compiled\n"; #endif }
4.10.3.2#fdef,# ifndef指令和 defined运算符 这几条指令可以用来测试某个宏是否定义,进而决定编译器的 下一步操作。例: ∥/ MYHEAD.H #ifndef MYHEAD H #define MYHEAD H ∥文件 MYHEAD H中的内容 fendi 等价表示: 注意:在较新的C++标准中, #de和# Ifndef预处理指令是 ∥/ MYHEAD.H 为保持兼容性而保留的,新标 # f !defined MYHEAD H准推荐使用 defined运算符 #define MYHEAD H ∥文件 MYHEADH中的内容#def→># defined fendi # ifndef→>#f! defined
4.10.3.2 #ifdef,#ifndef 指令和 defined 运算符 这几条指令可以用来测试某个宏是否定义,进而决定编译器的 下一步操作。例: // MYHEAD.H #ifndef _MYHEAD_H_ #define _MYHEAD_H_ // 文件 MYHEAD.H 中的内容 #endif 等价表示: // MYHEAD.H #if !defined _MYHEAD_H_ #define _MYHEAD_H_ // 文件 MYHEAD.H 中的内容 #endif 注意:在较新的 C++ 标准中, #ifdef 和 #ifndef 预处理指令是 为保持兼容性而保留的,新标 准推荐使用 defined 运算符。 #ifdef → #if defined #ifndef → #if !defined