预处理器的命令都是无条件执行的,而预处理器也支持有条件的复合命令,也就是有条件的根据常量的值选择替换的预处理器命令。当然,由于是预处理器命令,在正式的编译之前所有的替换都已经执行好了,因此替换也必须是一个常量表达式。
条件编译的命令有: #f 、 #ifdef 、 #else 、#elif 、#endif 和 #defined。
下面我们将通过条件编译的常见应用来逐个介绍这些命令。
- List item
#include<iostream>
#include<string>
using namespace std;
//条件编译在跨平台代码中的应用
//这些参数一般会在配置文件中定义
#define WINDOWS
#define VS2017
#if defined (WINDOWS) && defined (VS2015)
string output = "平台: Windows,编译环境:Visual Studio 2015";
#elif defined (WINDOWS) && defined (VS2017)
string output = "平台:Windows,编译环境:Visual studio 2017";
#else //在Visual Studio中不被执行的代码的颜色会变浅
string output = "平台:其他平台,编译环境:未知";
#endif
int main()
{
cout << output << endl;
return 0;
}
输出结果为:
在跨平台程序中,我们一般会在某个头文件或配置文件中集中放上平台的信息以及其他的一些配置选项,这些信息在某个平台上是永远不变的,因此在于处理阶段就可以确定。有了这些常数或是定义的宏名之后,我们就可以用条件编译命令编写不同版本的代码了。
我们指定#define的时候并没有指定符号代表的语义,这是完全可以的,因为我们使用defined()就是要判断这个符号是否存在,至于他代表什么,我们不需要关心。 #if 后面跟着任意的常量表达式,也可以用1>0 这样的。因为我们没有定义“VS2015” #if后面的条件不满足,所以预处理器就忽略这一行代码。接着看#elif 后面的条件(“elif”是“else if”的缩写),如果所有条件都不满足,就会保留 # else 后面的代码。最后的 #endif 是条件编译的必须终止符,如果没有#endif ,预处理器就不知道后面的代码是不是只有# else 的时候才保留了。