第9章 C/C++编译预处理
预编译伪指令一般都以#号打头,且其前面只能出现空白字符。预编译伪指令不是C/C++语句,它们只是能够被预编译器展开成合法的C/C++语句。因此所有的预编译伪指令都不会进入编译阶段。C/C++中常用的一些预编译伪指令有文件包含(#include),宏定义(#define),条件编译(#if....#else....#endif)等。
9.1 文件包含(#include)
1、(文件包含(#include)
1) #include <头文件名称>
2) #include "头文件名称"
第一种尖括号的形式一般用来包含开发环境提供的库文件,它指示编译预处理器在开发环境设定的搜索路径中查找所需的头文件。第二种形式一般用来包含自己编写的头文件,它指示编译预处理器首先在当前目录下搜索头文件,如果找不到的话再到开发环境的路径中去查找。
使用include伪指令时,头文件前面可以加相对路径或绝对路径(此处的"\"并不会解释为转义字符)。
#include ".\myinclude\abc.h"
#include "C:\myproject\test001\source\include\abc.inl"
2、内部包含卫哨和外部包含卫哨
1)内部包含卫哨:我们在平常的编码中都会用到,很多IDE都会自动为你添加内部包含卫哨。目的是避免同一个编译单元包含同一个头文件的内容超过一次,也就防止了莫名其妙类型重定义错误。
2)外部包含卫哨:在包含一个头文件的时候,如果能始终如一地使用外部包含卫哨,可以显著地提高编译速度。
#if !defined(STD_INCLUDE_H) // STD_INCLUDE_H 是在stddef.h里定义的宏
#include <stddef.h>
#endif
建议可以仅在头文件中包含其他头文件时使用外部包含卫哨,源文件中可以不适用,这样也基本不会影响编译速度。
3、头文件的包含顺序
可以参考 http://blog.csdn.net/clever101/article/details/7269058
9.2 宏定义
1、宏定义具有文件作用域,在宏定义后面的任何地方都可以引用宏。
2、虽然我们总提倡,在C++中应该尽量不使用宏。但是const和inline不能完全取代宏,各有各的好处。例如在MFC,Qt等类似的库中,我们可以看到充斥着许多的宏定义。当然,我们在实际的编码中还是要尽量的减少使用宏。
3、不要使用宏来定义新类型名,应该使用typedef。
9.3 条件编译
9.4 #error
9.5 #pragma
9.6 #和##运算符
# 构串操作符
## 合并操作符
9.7 预定义符号常量
_LINE_
_FILE_
_DATA_
_TIME_
_TIMESTAMP_
_STDC_
预编译伪指令一般都以#号打头,且其前面只能出现空白字符。预编译伪指令不是C/C++语句,它们只是能够被预编译器展开成合法的C/C++语句。因此所有的预编译伪指令都不会进入编译阶段。C/C++中常用的一些预编译伪指令有文件包含(#include),宏定义(#define),条件编译(#if....#else....#endif)等。
9.1 文件包含(#include)
1、(文件包含(#include)
1) #include <头文件名称>
2) #include "头文件名称"
第一种尖括号的形式一般用来包含开发环境提供的库文件,它指示编译预处理器在开发环境设定的搜索路径中查找所需的头文件。第二种形式一般用来包含自己编写的头文件,它指示编译预处理器首先在当前目录下搜索头文件,如果找不到的话再到开发环境的路径中去查找。
使用include伪指令时,头文件前面可以加相对路径或绝对路径(此处的"\"并不会解释为转义字符)。
#include ".\myinclude\abc.h"
#include "C:\myproject\test001\source\include\abc.inl"
2、内部包含卫哨和外部包含卫哨
1)内部包含卫哨:我们在平常的编码中都会用到,很多IDE都会自动为你添加内部包含卫哨。目的是避免同一个编译单元包含同一个头文件的内容超过一次,也就防止了莫名其妙类型重定义错误。
2)外部包含卫哨:在包含一个头文件的时候,如果能始终如一地使用外部包含卫哨,可以显著地提高编译速度。
#if !defined(STD_INCLUDE_H) // STD_INCLUDE_H 是在stddef.h里定义的宏
#include <stddef.h>
#endif
建议可以仅在头文件中包含其他头文件时使用外部包含卫哨,源文件中可以不适用,这样也基本不会影响编译速度。
3、头文件的包含顺序
可以参考 http://blog.csdn.net/clever101/article/details/7269058
9.2 宏定义
1、宏定义具有文件作用域,在宏定义后面的任何地方都可以引用宏。
2、虽然我们总提倡,在C++中应该尽量不使用宏。但是const和inline不能完全取代宏,各有各的好处。例如在MFC,Qt等类似的库中,我们可以看到充斥着许多的宏定义。当然,我们在实际的编码中还是要尽量的减少使用宏。
3、不要使用宏来定义新类型名,应该使用typedef。
9.3 条件编译
9.4 #error
9.5 #pragma
9.6 #和##运算符
# 构串操作符
## 合并操作符
9.7 预定义符号常量
_LINE_
_FILE_
_DATA_
_TIME_
_TIMESTAMP_
_STDC_