8.2.2 条件编译
一般情况下,在生成可执行文件的过程中,源程序文件中的所有代码行都参加编译,但有时候希望对其中的一部分内容只在满足一定的条件下才进行编译,也就是对一部分内容指定编译的条件,也有的时候,希望当满足某条件时对一组语句进行编译,而当条件不满足时编译另外一组语句,这都叫条件编译。
条件编译用得也比较频繁,尤其是写一些跨操作系统平台的代码,例如这个代码既要求能在Windows下编译运行,也能在Linux下编译运行,但程序代码中有些特殊的系统调用函数只能在Windows下编译运行或者只能在Linux下编译运行,此时,就有必要使用条件编译。
条件编译有几种形式,分别看一看。
(1)形式1。

作用:当标识符被定义过(#define来定义),则对程序段1进行编译,否则对程序段2进行编译。当然,“#else程序段2”这部分可以没有,此时的形式就变成:

在进行程序调试的时候,常常需要输出一些信息,调试完毕后,不再输出这些信息。看看如下范例:

然后在其他一些需要输出调试信息的地方(如main函数中),可以写类似如下代码:

(2)形式2。

作用:若标识符未被定义(未用#define来定义),则编译程序段1,否则编译程序段2。与形式1正好相反,看看如下范例:

然后在其他一些需要输出调试信息的地方(如main函数中),可以写类似如下代码:

(3)形式3。

作用:当指定的表达式值为真(非0)时就编译程序段1,否则编译程序段2,所以,事先给出一定的条件,就可以使程序代码在不同条件下进行不同程序段的编译。
当然可以将上述形式扩展一下,引入#elif。如下:

作用:当表达式1值为真(非0)时就编译程序段1,否则当表达式2的值为真(非0)则编译程序段2,否则编译程序段3。
看看如下范例:

然后在其他一些需要输出调试信息的地方(如main函数中),可以写类似如下的代码:

从以上范例看起来,如果不用条件编译,似乎用if语句也可以做这些事情,那么用条件编译的好处是什么呢?
(1)最明显,条件编译可以减少目标程序长度。因为上面5行程序代码只相当于一行:

(2)项目开发也许会面临跨平台的问题,为了增加程序代码在各平台之间的可移植性,往往采用条件编译,如果不用条件编译,就很难解决同一套程序代码在Windows平台下和Linux平台下都能够在不修改源代码的情况下编译通过并生成可执行文件的问题。看看如下跨平台代码范例:
