中年C/C++编程笔记:C语言预编译指令—条件编译,零基础推荐收藏


一、 内容概述
本文主要介绍c语言中条件编译相关的预编译指令 , 包括#define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined 。
中年C/C++编程笔记:C语言预编译指令—条件编译,零基础推荐收藏
本文插图
二、条件编译 条件编译是根据实际定义宏(某类条件)进行代码静态编译的手段 。 可根据表达式的值或某个特定宏是否被定义来确定编译条件 。
最常见的条件编译是防止重复包含头文件的宏 , 形式跟下面代码类似:
1 #ifndef ABCD_H2 #define ABCD_H3 4 // ... some declaration codes5 6 #endif // #ifndef ABCD_H
在实现文件中通常有如下类似的定义:
1 #ifdef _DEBUG 23 // ... do some operations 45 #endif 67 #ifdef _WIN32 89 // ... use Win32 API10 11 #endif
这些都是条件编译的常用情境 。
三、条件编译中使用的预编译指令 #define 定义一个预处理宏
#undef 取消宏的定义
#if 编译预处理中的条件命令 , 相当于C语法中的if语句
#ifdef 判断某个宏是否被定义 , 若已定义 , 执行随后的语句
#ifndef 与#ifdef相反 , 判断某个宏是否未被定义
#elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足 , 则执行#elif之后的语句 , 相当于C语法中的else-if
#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足 , 则执行#else之后的语句 , 相当于C语法中的else
#endif #if, #ifdef, #ifndef这些条件命令的结束标志.
defined 与#if, #elif配合使用 , 判断某个宏是否被定义
四、预编译指令应用举例 1. #define、#undef
#define命令定义一个宏:
#define MACRO_NAME[(args)] [tokens[(opt)]]
【中年C/C++编程笔记:C语言预编译指令—条件编译,零基础推荐收藏】之后出现的MACRO_NAME将被替代为所定义的标记(tokens) 。 宏可带参数 , 而后面的标记也是可选的 。
宏定义 , 按照是否带参数通常分为对象宏、函数宏两种 。
对象宏: 不带参数的宏被称为"对象宏(objectlike macro)" 。 对象宏多用于定义常量、通用标识 。 例如:
// 常量定义#define MAX_LENGTH 100// 通用标识 , 日志输出宏#define SLog printf// 预编译宏#define _DEBUG
函数宏:带参数的宏 。 利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈, 这一过程如果过于频繁会耗费掉大量的CPU运算资源 。
所以一些代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率 。 但多数c++程序不推荐使用函数宏 , 调试上有一定难度 , 可考虑使用c++的inline代替之 。 例如:
// 最小值函数#define MIN(a,b) ((a)&gt(b)? (a):(b))// 安全释放内存函数#define SAFE_DELETE(p) {if(NULL!=p){delete p p = NULL}}
#undef可以取消宏定义 , 与#define对应 。
2. defined
defined用来测试某个宏是否被定义 。 defined(name): 若宏被定义 , 则返回1 , 否则返回0 。
它与#if、#elif、#else结合使用来判断宏是否被定义 , 乍一看好像它显得多余, 因为已经有了#ifdef和#ifndef 。 defined可用于在一条判断语句中声明多个判别条件;#ifdef和#ifndef则仅支持判断一个宏是否定义 。
#if defined(VAX) &amp&amp defined(UNIX) &amp&amp !defined(DEBUG)
和#if、#elif、#else不同 , #ifdef、#ifndef、defined测试的宏可以是对象宏 , 也可以是函数宏 。
3. #ifdef、#ifndef、#else、#endif
条件编译中相对常用的预编译指令 。 模式如下:


推荐阅读