条件编译指令 条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。 一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件下才进行编译,即对一部分内容指定编译条件,这就是“条件编译”。(conditional compile)
条件编译语句排版时,需考虑以下三种位置:
(1)条件编译语句块与函数定义体之间不存在相互嵌套(主要在(.h)文件中)
◆ 条件编译关键字语句顶格左对齐;
◆ 所含的#include语句(块) #define语句(块)甚至是被嵌套下级条件编译语句块,按照语句块嵌套的排版方式进行缩进排版 。
(2)条件编译语句块嵌套在函数体之外(主要在(.c)文件中)
这种情况下,条件编译语句块不影响函数体
◆ 条件编译关键字语句顶格左对齐;
◆ 所含的函数体定义无需缩进,依旧按照单个函数体定义的排版方式进行。
(3)条件编译语句嵌套在函数体内 (主要在(.c)文件中)
a)当条件编译语句块与被包语句所属的语句块之间没有逻辑路径交叉时,以下两种方式均可
◆ 按照语句块嵌套方式进行缩进排版 (推荐);
◆ 条件编译语句不影响原先语句块排版,条件编译语句与所包含的关键字语句块左对齐 。
b)当条件编译语句块与被包语句所属的语句块之间存在逻辑路径交叉时
◆ 条件编译语句顶格左对齐,其它语句按照正常顺序排版。
1.#if指令 #if指令检测跟在关键字后的常量表达式。如果表达式为真,则编译后面的代码,知道出现#else、#elif或#endif为止;否则就不编译。 条件编译的形式如下所示(NNN、MMM等都是在某处已经定义为 1 或者 0 的):- #if NNN
- statement1;
- #elif MMM
- statement2;
- #else
- statement3;
- #endif
复制代码重要解释:若宏NNN为True则只留下statement1编译;若NNN为False且MMM为True则只编译statement2;若NNN和MMM都为False则编译statement3。 #if是在编译前进行抉择的,而一般的if指令是在程序运行时才做抉择的,因此#if可以提升程序的执行速度,这是两者的重要区别。另外,#if指令还可协助查错。
2.#endif指令 #endif用于终止#if预处理指令。 - #defineDEBUG0
- main()
- {
- #if DEBUG
- printf("Debugging\n");
- #endif
- printf("Running\n");
- }
复制代码 由于程序定义DEBUG宏代表0,所以#if条件为假,不编译后面的代码直到#endif,所以程序直接输出Running。
如果去掉#define语句,效果是一样的。
3.#ifdef和#ifndef - #define DEBUG
- main()
- {
- #ifdef DEBUG
- printf("yes\n");
- #endif
- #ifndef DEBUG
- printf("no\n");
- #endif
- }
复制代码#ifdefined等价于#ifdef; #if!defined等价于#ifndef 防止一个头文件被重复包含 - #ifndef COMDEF_H
- #define COMDEF_H //头文件内容
- #endif
复制代码 4.#else指令#else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。 #endif指令将中指上面的条件块。
5.#elif指令 #elif预处理指令综合了#else和#if指令的作用。 - #define TWO
- main()
- {
- #ifdef ONE
- printf("1\n");
- #elif defined TWO
- printf("2\n");
- #else
- printf("3\n");
- #endif
- }
复制代码 程序很好理解,最后输出结果是2。
区分:
#ifdef 宏 //若已定义了此宏,则留下#ifdef与#endif间的指令;否则删除之。 #ifndef 宏 //若未定义过此宏,则留下#ifndef与#endif间的指令;否则删除之。 #endif //定义#ifdef及#ifndef的范围。 #undef 宏 //与#defined相反的动作---解除定义。 #else //可构成#ifdef~#else~#endif结构或#ifndef~#else~#endif结构。 #ifdef与#if的区别 #if 宏:此宏必须已定义,依宏所代表的值来做判断; #ifdef 宏:此宏不一定已定义,依此宏是否已定义来判断。
组合:
1:情况1:
#ifdef _XXXX
...程序段1...
#else
...程序段2...
#endif
这表明如果标识符_XXXX已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。例:
#define NUM
.............
.............
.............
#ifdef NUM
printf("之前NUM有过定义啦! ");
#else
printf("之前NUM没有过定义! ");
#endif
}
如果程序开头有#define NUM这行,即NUM有定义,碰到下面#ifdef NUM的时候,当然执行第一个printf。否则第二个printf将被执行。
我认为,用这种,可以很方便的开启/关闭整个程序的某项特定功能。 2:情况2:
#ifndef _XXXX
...程序段1...
#else
...程序段2...
#endif
这里使用了#ifndef,表示的是if not def。当然是和#ifdef相反的状况(如果没有定义了标识符_XXXX,那么执行程序段1,否则执行程序段2)。例子就不举了。 3:情况3:
#if 常量
...程序段1...
#else
...程序段2...
#endif
这里表示,如果常量为真(非0,随便什么数字,只要不是0),就执行程序段1,否则执行程序段2。
这种方法可以将测试代码加进来。当需要开启测试的时候,只要将常量变1就好了。而不要测试的时候,只要将常量变0。
6.其他一些标准指令 #error指令将使编译器显示一条错误信息,然后停止编译。 #line指令可以改变编译器用来指出警告和错误信息的文件号和行号。 #pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息。
关于宏定义的用法
移步http://www.firebbs.cn/forum.php?mod=viewthread&tid=123&highlight=%BA%EA
|