版权归原作者所有,如有侵权,请联系我们

[科普中国]-条件编译

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

条件编译功能

预处理程序提供了条件编译的功能。条件编译允许只编译源文件中满足条件的程序 段,使生成的目标程序较短,从而减少了内存的开销,并提高程序的效率,可以按不同的 条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。2

另外,条件编译是为了让程序在各种不同的软硬件环境下都以运行。即,提高了程序的可移植性和灵活性。

例如,一个商业性的软件,所面向的用户群有着:不同的软件系统(有的是Windows XP系统,有的是Window 7系统)、不同的硬件系统(有的是Inter的处理器,有的是AMD的处理器) ,而这会导致同—段程序代码 在不同用户的电脑上产生不同的运行效果(有的流畅、有的卡顿、有的甚至无法运行),如图15-16所示。3

解决这类问题可以有两种方法。方法一:针对不同的环境编写不同的代码,如图 15-17所示。方法二:同一段代码,针对不同的环境,预编译成不同代码,从而使得生成的程序最大程度上适应用户的软硬件环境,如图15-18所示。3

条件编译格式在C语言中,若要对程序中的代码段有条件地进行编译,就要用到条件编译命令,条件编译主要有如下几种格式:1

if格式#if 表达式 语句序列①[#else 语句序列②]#endif功能:当表达式的值为真时,编译语句序列①,否则编译语句序列②。其中,#else和语句序列②可有可无。1

ifdef格式#ifdef 标识符 语句序列①[#else 语句序列②]#endif功能:当标识符已被定义时(用#define定义),编译语句序列①,否则编译语句序列②。其中#else和语句序列②可有可无。1

ifndef格式#ifndef 标识符 语句序列①[#else 语句序列②]#endif功能:该格式功能与ifdef相反。1

排版不相互嵌套条件编译关键字语句顶格左对齐;

所含的#include语句(块) #define语句(块)甚至是被嵌套下级条件编译语句块,按照语句块嵌套的排版方式进行缩进排版 。4

函数体外这种情况下,条件编译语句块不影响函数体

条件编译关键字语句顶格左对齐;

所含的函数体定义无需缩进,依旧按照单个函数体定义的排版方式进行。

函数体内a)当条件编译语句块与被包语句所属的语句块之间没有逻辑路径交叉时,以下两种方式均可

按照语句块嵌套方式进行缩进排版 (推荐);

条件编译语句不影响原先语句块排版,条件编译语句与所包含的关键字语句块左对齐 。

b)当条件编译语句块与被包语句所属的语句块之间存在逻辑路径交叉时

条件编译语句顶格左对齐,其它语句按照正常顺序排版。4

应用举例设有3个源文件如图16-2所示,其中存在着对同一个源文件重复包含的问题。请修改程序,不要删除代码,利用条件编译避免重复包含,使得每个源文件都能通过编译。5

分析:

源文件a.c中的main()函数要调用b.c中的subl()函数,也要调用c.c中的sub2()函数,所以,文件a.c包含了b.c和c.c。 源文件b.c中的sub3()函数要调用c.c中的 sub2()函数,所以b.c也包含c.c。这样一来就造成了重复包含的问题,即文件a.c包含了两次c.c,a.c的内容相当于是这样的:

其中c.c的内容出现了两遍,就有了两次sub2()函数的定义,导致编译错误。

要解决这个问题,需要用条件编译,将c.c的内容放在条件编译控制之下,即将c.c 的内容修改为

//c.c#ifndef FILE_C#define FILE_Cvoid sub(){ ...}#endif这样就可以避免c.c的内容被重复包含。5