分享

【条件编译】一份代码适配多种机型,就要用这个关键词

 乐创客搬运工 2021-01-27

文/Edward


有时候我们在做项目的时候,一个全新的项目代码并不会全部重新写,这个新项目往往只是某一个主线项目的分支,因此可以借鉴之前的代码,然后对需要修改的地方进行修改。但是,如果这两份代码改动的地方仅仅是某些逻辑判断,或是某些AD电压阈值判断标准。其余两份代码之间的架构完全相同,那么其实新代码基于老代码的改动微乎其微,其代码量相似度可能达到95%以上。那么有没有一种方法可以将这两份代码统一成一份,并且根据不同的选项编译不同的代码。这样的话也便于程序开发以及后续的代码管理。

在C语言里面有一种机制可以决定编译那些代码,这个机制就是预处理中的条件编译。
使用条件编译,你可以选择代码的一部分是被正常编译还是完全忽略。C语言中条件编译的主要形式有三种,接下来我们将会对其一一讨论。



  #if……#endif
第一种最简单的选择编译形式就是判断条件编译。这里面会用到两个预处理命令#if和#endif。其表达形式为:
#if 常量表达式 执行语句#endif
其中的常量表达式是由预处理器进行求值。如果它的值是非零值(真),那么执行语句部分就会参与到代码的编译中来。否则,预处理器就会忽略它们,使它们不参与编译。如图8-3-1中的代码。

图8-3-1 判断类型条件编译

在图8-3-1所示的代码中,我们使用#define定义了两个符号,一个符号是DEBUG1,其常量值为0,又定义了DEBUG2,其常量值为1。在程序执行处,我们可以看到有两个判断类型的条件编译。一旦满足一个条件,就将其相应的printf函数进行编译。最终我们可以看到,只有当DEBUG2这个调试信息可以打印出来,就是由于DEBUG2为1,满足了#if的条件编译,因此其相应的代码会被编译进去。
需要注意一点的是,这里面的#if和之前我们学过的条件判断语句if有着不同的机制,条件判断语句的if是将整个if……else中的代码编译进工程。而#if是预处理命令,因此其产生的影响是文本级别的,即在预处理阶段直接修改.c源文件。我们可以查看其中间文件,如图8-3-2所示。

图8-3-2条件编译的中间文件

如图8-3-2中所生成的中间文件a.out,我们可以看到,只要不满足#if条件的代码,它完完全全会被编译器舍弃。
#if……#endif还有一种扩展的形式,即多重条件判断的条件编译。其形式为:
#if 常量表达式 代码#elif 常量表达式 代码#else 代码#endif
如,我们有一份标准的代码需要去适配多个个机型,这几个机型只有一个功能不同,其余的都一样。这个功能即为,当按键输入的值是1的时候,1号机型输出“Hello,Iam 1”,2号机型输出“Hello,I am 2”,其它机型输出“Hello,I am other”。那么上述这种情况除了输出不同之外,其余的功能都一模一样,因此我们根本不需要将这些代码分开管理,只需要使用条件编译,即可将这些代码合并。如图8-3-3所示。

图8-3-3 判断语句条件编译


  是否被定义
在编写C语言程序的时候,“是否被定义”这个条件编译往往是备用的最频繁的。实现是否被定义主要有两种方式。
第一种方式为,使用#if预处理和defined,!defined预处理相结合的方式。这里的defined为具体的判断符号是否被定义,一旦这个符号X被定义之后,使用defined(X),其最终结果会返回一个1,使用!defined(X),其最终结果会返回一个0。最终#if会根据返回值来选择代码是否要被编译。其使用形式为:
#if defined(符号) 程序语句#endif#if !defined(符号) 程序语句#endif
如,我们要判断符号DEBUG是否被定义,一旦被定义之后,就输出“Indebug mode”。如果DEBUG没有被定义,那么就定义RELEASE,如果RELASE被定义,那么就输出“In release mode”。具体代码如图8-3-4和图8-3-5所示。

图8-3-4 DEBUG被定义之后的输出

图8-3-5 DEBUG未被定义之后的输出

第二种方式,可以使用简写的#ifdef和#ifndef的形式来完成这个功能。
#if define(符号) <==> #ifdef 符号#if !define(符号) <==> #ifndef 符号
如图8-3-6中的代码,我们可以使用#ifdef和ifndef的形式,进行替换。

图8-3-6 #ifdef和#ifndef

最后大家再考虑下,为何每个源代码的.h文件中,都要使用#ifndef来检查标号是否被定义呢?如图8-3-7所示。
图8-3-7 .h文件常用的条件编译




    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多