2.4 条件编译指令的使用

预处理程序提供了条件编译的功能,用户可以选择性地编译程序,进而产生不同的目标代码文件,这对程序的移植和调试来说是非常有用的。下面先来看看条件编译命令的几种使用方式。

第一种方式:


if常量表达式

程序段1;

[#else

程序段2;]

endif


功能:当常量表达式为非0(“逻辑真”)时,编译程序段1,否则编译程序段2。第二种方式:


ifdef标识符

程序段1;

[#else

程序段2;]

endif


功能:如果标识符已经被#define命令定义过,则编译程序段1,否则编译程序段2。第三种方式:


ifndef标识符

程序段1;

[#else

程序段2;]

endif


功能:如果标识符未被#define命令定义过,则编译程序段1,否则编译程序段2。

了解了条件编译指令的使用方式之后,我们在调试代码的时候,就不能再随心所欲地删减代码了。如果不希望某段代码被编译,那么可以使用条件编译指令来将其注释掉,例如:


if(0)

注释代码段;

endif


这样就可以将代码注释掉。需要的时候还可以将注释掉的代码重新启用,不必为需要重新编辑代码时发现代码已被删除而头疼了。下面通过具体的代码来了解条件编译命令的使用。


include<stdio.h>

define NUM 0

define ON_OFF 0

int main(int argc,char*argv)

{

if NUM>0

printf("NUM的值大于0\n");

elif NUM<0

printf("NUM的值小于0\n");

else

printf("NUM的值等于0\n");

endif

if ON_OFF

printf("使用条件编译命令注释掉的语句部分\n");

endif

return 0;

}


运行结果:


NUM的值等于0


通过上面的代码,我们学会如何使用条件编译命令。值得注意的是,常量表达式在编译时求值,所以表达式只能是常量或者已经定义过的标识符,不能是变量,也不能是那些在编译时候求值的操作符,如sizeof。

看看下面的代码。


include<stdio.h>

define N 1

int main(int argc,char*argv)

{

int a=3;

if(a)

printf("#if后面的表达式为变量\n");

endif

if(N)

printf("#if后面的表达式已定义,且不为0—-success\n");

else

printf("#if后面的表达式已定义,且不为0—-fail\n");

endif

return 0;

}


运行结果:


if后面的表达式已定义,且不为0—-success


从上面的代码我们发现,当表达式为变量a时,并没有打印出其后面的语句来,所以不能在其后的常量表达式中使用变量。如果使用sizeof操作符会怎么样呢?为了加深印象,我们来看下面的代码。


include<stdio.h>

int main(int argc,char*argv)

{

int a=9;

if(sizeof(a))

printf("#if后面的表达式含有sizeof操作符\n");

endif

return 0;

}


编译时产生了如下错误:


fatal error C1017:invalid integer constant expression


所以,在使用条件编译时要牢记:常量表达式不能是变量和含有sizeof等在编译时求值的操作符,在使用条件编译命令时尤其要注意。接下来看看另外两种条件编译命令的使用。


include<stdio.h>

define NUM

int main(int argc,char*argv)

{

ifdef NUM

printf("NUM已经定义过了\n");

else

printf("NUM没有定义过\n");

endif

return 0;

}


运行结果:


NUM已经定义过了


在编写程序时,对于那些不确定是否已经定义过的宏采用这种方法来测试输出。适当地修改上面的代码,再看看另外一种实现方法。


include<stdio.h>

define NUM

int main(int argc,char*argv)

{

undef NUM

ifndef NUM

printf("NUM没有定义过\n");

else

printf("NUM已经定义过了\n");

endif

return 0;

}


运行结果:


NUM没有定义过


在条件编译命令前面用“#undef NUM”取消了接下来的作用域中NUM宏的作用,所以接下来使用条件编译命令时打印出来的就是“NUM没有定义过”。