原创 【学习笔记】C++之二 -- 预处理命令

2011-3-22 13:39 2437 6 6 分类: 软件与OS

                               条件编译                   条件编译的实现

条件编译是通过预编译指令来实现的,主要方法有:

1.   #if,#elif, #else, #endif

#if 表达式 1

 代码段 1

#elif 表达式 2

 代码段 2

#elif 表达式 n

 代码段 n

#else

 代码段 n+1

#endif

   即可以设置不同的条件,在编译时编译不同的代码。预编译指令中的表达式与C语言本身的表达式[微软用户1] 基本一至如逻辑运算、算术运算、位运算等均可以在预编译指令中使用。

2.   #ifdef,#else, #endif或#ifndef, #else,#endif

   条件编译的另一种方法是用#ifdef与#ifndef命令,它们分别表示“如果有定义”及“如果无定义”。有定义是指在编译此段代码时是否有某个宏通过 #define 指令定义的宏,#ifndef指令指找不到通过#define定义的某宏,该宏可以是在当前文件此条指令的关面定义的,也可以是在其它文件中,但在此指令之前包含到该文件中的。

  通过ifdef/ifndef只能针对一个宏名是否定义做出判断。不能实现像if那样的灵活的表达式控制。只有能处理两段代码,如要处理多段,则需要defined()处理。

#ifdef macro_name

    代码段 1

#else

    代码段 2

#endif

#ifndef macro_name

    代码段 2

#else

    代码段 1

#endif

3.   通过宏函数defined(macro_name)

   参数为宏名(无需加""),如果该macro_name定义过则返回真,否则返回假,用该函数则可以写比较复杂的条件编译指令。

  通过defined和#if条件判断的结合,可灵活的针对多个宏名是否定义做出判断。类似于if,使用表达式,可实现较为灵活的控制。

#if defined(macro1) || (!defined(macro2) && defined(macro3))

...

#else

...

#endif

                    条件编译示例

4.   使用条件编译进行版本控制

#define MY_PRINTF_SIMPLE
#ifdef MY_PRINTF_SIMPLE                       // 使用多个ifdef
 void printf(*str){}
#endif
#ifdef MY_PRINTF_STANDARD
void printf(*str){}
#endif

#define MY_PRINTF_SIMPLE                  // 使用if + defined函数
#if defined(MY_PRINTF_SIMPLE)
void printf(*str){}
#elif defined(MY_PRINTF_STANDARD)
void printf(*str){}
#endif

#define MY_PRINTF_VERSION              // 使用if + 条件表达式

#if MY_PRINTF_VERSION == 1
void printf(*str){}
#elif MY_PRINTF_VERSION ==2
void printf(*str){}
#elif MY_PRINTF_VERSION ==3
int printf(unsigned char com_number, char* str)
void printf(*str){}
#else
void printf(*str){}
#endif

 

5.   针对多个版本实现一个默认版本,避免提供未定义信息。

#incldue "config.h"

 #if MY_PRINTF_VERSION == 1
  #undef MY_PRINTF_VERSION              // 可做到为保持以前的兼容性,不取消V1的定义

  #define MY_PRINTF_VERSION   1                           // 提供的默认版本

#endif

#if MY_PRINTF_VERSION == 1

void printf(*str){}
#elif MY_PRINTF_VERSION == 2

void printf(*str){}
#elif MY_PRINTF_VERSION == 3

int printf(unsigned char com_number, char* str)

#endif

 

6.   避免头文件的多次包含

#ifndef <标识>
#define <标识>

......
#endif

                    文件包含

#include<my.h>

#include"my.h"

  第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件第二种方法是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。一般包含用户头文件时用后者,而包含系统头文件时用前者,以便进行区分。

                    #运算符

  出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符。例如:

#definePASTE(n)"adhfkj"#n

main()

{

printf("%s\n",PASTE(15));

}

宏定义中的#运算符告诉预处理程序,把源代码中任何传递给该宏的参数转换成一个字符串。所以输出应该是adhfkj15。

                    ##运算符

##运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号。看下面的例子:

#defineNUM(a,b,c)a##b##c

#defineSTR(a,b,c)a##b##c

 

main()

{

printf("%d\n",NUM(1,2,3));

printf("%s\n",STR("aa","bb","cc"));

}

 

最后程序的输出为:

123

aabbcc

千万别担心,除非需要或者宏的用法恰好和手头的工作相关,否则很少有程序员会知道##运算符。绝大多数程序员从来没用过它。


也即可使用一些运算符来进行操作,以实现更为灵活的控制。

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条