C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)
1、条件编译介绍
- 条件编译(conditional compiling)命令指定预处理器依据特定的条件来判断保留或删除某段源代码。例如,可以使用条件编译让源代码适用于不同的目标系统,而不需要管理该源代码的各种不同版本。
- 条件编译区域以 #if、#ifdef 或 #ifndef 等命令作为开头,以 #endif 命令结尾。条件编译区域可以有任意数量的 #elif 命令,但最多一个 #else 命令。以 #if 开头的条件编译区域具有下面的格式:
#if 表达式1
[ 组1]
[#elif 表达式2
[ 组2]]
...
[#elif 表达式n
[ 组n ]]
[#else
[ 组n+1 ]]
#endif
- 预处理器会依次计算条件表达式,直到发现结果非 0(也就是 true)的条件表达式。预处理器会保留对应组内的源代码,以供后续处理。如果找不到值为 true 的表达式,并且该条件式编译区域中包含 #else 命令,则保留 #else 命令组内的代码。
- 组 1、组 2 等代码段,可以包含任意 C 源代码,也可以包含更多的命令,包括嵌套的条件式编译命令。在预处理阶段结束时,没有被预处理器保留以用于后续处理的组会从程序中全部删除。
2、#if 和 #elif 命令
- 作为 #if 或 #elif 命令条件的表达式,必须是整数常量预处理器表达式。这与普通的整数常量表达式不同,主要区别在于:
- (1) 不能在 #if 或 #elif 表达式中使用类型转换运算符。
- (2) 可以使用预处理运算符 defined。
- (3) 在预处理器展开所有宏,并且计算完所有 defined 表达式之后,会使用字符 o 替换掉表达式中所有其他标识符或关键字。
- (4) 表达式中所有带符号值都具有 intmax_t 类型,并且所有无符号值都具有 uintmax_t 类型。字符常量也会受该规则的影响。intmax_t 和 uintmax_t 定义在头文件 stdint.h 中。
- (5) 预处理器会把字符常量和字符串字面量中的字符与转义序列转换成运行字符集中对应的字符。然而,字符常量在预处理器表达式和在后期编译阶段是否具有相同的值,取决于实现版本。
3、defined 运算符
- 一元运算符 defined 可以出现在 #if 或 #elif 命令的条件中。它的形式如下:
defined 标识符
defined (标识符)
- 如果指定的 identifier 是一个宏名称(也就是说,它已被 #define 命令定义,并且未被 #undef 命令取消定义),则 defined 表达式会生成值 1。否则,defined 表达式会生成值 0。
- defined 运算符相对于 #ifdef 和 #ifndef 命令的优点是:你可以在更大型的预处理器表达式中使用它的值。如下例所示:
#if defined( __unix__ ) && defined( __GNUC__ )
/* ... */
#endif
- 大多数编译器会提供预定义宏,例如上例所使用的宏,它用来识别目标系统和编译器。因此,在 Unix 系统中,通常预先定义好了宏 _unix_,而 GCC 编译器则会预先定义好了宏 _GNUC_。类似地,微软 Windows 平台上的 Visual C 编译器会自动定义好宏 _WIN32 和宏 _MSC_VER。
4、#ifdef 和 #ifndef 命令
- 你可以通过 #ifdef 和 #ifndef 命令测试某个宏是否已被定义。它们的语法是:
#ifdef 标识符
#ifndef 标识符
- 这等同于下面的 #if 命令:
#if defined 标识符
#if !defined 标识符
- 如果 identifier 不是宏名称,则 #ifndef 标识符后面的条件代码被保留。
C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)的更多相关文章
- uni-app条件编译:#ifdef #ifndef #endif
语法: // #ifdef %PLATFORM% 这些代码只在该平台编译 // #endif #ifdef : if defined 仅在某个平台编译 #ifndef : if n ...
- C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等)
转自:http://www.kuqin.com/language/20090806/66164.html 预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器.可见预处理过程先于编译器 ...
- C/C++预处理指令#define,#ifdef,#ifndef,#endif…
2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...
- C/C++预处理指令#define,#ifdef,#ifndef,#endif… (转)
本文转自博文C/C++预处理指令#define,#ifdef,#ifndef,#endif….这篇博文写得特别好,特转载. 本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何 ...
- 史上最全条件编译解析 #ifdef #ifndef #undef #else #endif
C语言和C++语言程序中广泛存在着#ifdef或#ifndef等条件编译语句,本篇就系统介绍下他们的用法. 这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分 ...
- C语言的#if #ifdef #ifndef
#if #ifedf #ifndef —般情况下,C语言源程序中的每一行代码.都要参加编译.但有时候出于对程序代码优化的考虑.希望只对其中一部分内容进行编译.此时就需要在程序中加上条件,让编译器只 ...
- iOS ifdef ifndef endif
#ifdef DEBUG //标识符//定义过执行#else//未定义过执行#endif #ifndef DEBUG//标识符//未定义过执行#else//定义过执行#endif #if (5> ...
- C/C++预处理指令#include,#define,#undef,#if,#ifdef,#ifndef,#elif,#endif,#error......
本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下 ...
- #ifdef #else #endif #fi #ifndef 的用法
预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作.说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译.这样做的好处是,经过处理后的代码,将会变的很精短. ...
- #ifdef,#else,#endif,#if 拾忆
预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作.说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译.这样做的好处是,经过处理后的代码,将会变的很精短. ...
随机推荐
- 注册驱动时如何调用probe函数 ?
platform_driver_register driver_register bus_add_driver //把驱动放入总线的驱动链表里 ...
- 环境搭建:Vue环境搭建和项目初始化(ubuntu)
1. 安装node.js(版本6.10.3) 首先确保系统安装来gcc,g++,如果没有则安装: $ sudo apt-get update $ sudo apt-get install gcc ...
- Python之购物商场
作业:购物商场 1.流程图 2.初始化用户账号存储文件 初始化存储一个空的用户账号字典,保存到文件 user.pkl.执行如下代码,即可初始化完成. #!/usr/bin/env python # - ...
- 相关不同Linux系统的性能监控命令整理
Linux系统 查看系统版本情况: $uname -a 监控进程的CPU,MEM使用情况: $ps –aux 过滤方式命令:$ ps -aux|awk '{print $3,$4,$11}'|sort ...
- C#递归所以部门展示到TreeView
C#递归所以部门展示到TreeView 1.首先是数据库表的设计 新建一张部门表:TestUser表 1.ID自增int主键 2.DeptName:nchar(10)3.DeptCode:nchar( ...
- CBV中的dispatch
之前介绍了FBV和CBV ,下面我们看一下CBV中的dispatch dispatch函数在类View中定义,作用就是通过反射查找get或post函数,所以在执行get或post函数之前,dispat ...
- Monthly Expense(二分--最小化最大值)
Farmer John is an astounding accounting wizard and has realized he might run out of money to run the ...
- localtime 的性能问题及其替代者
在系统从redhat5升到redhat6的过程中,服务的性能差了很多.经过定位发现是程序中频繁调用localtime/localtime_r所致. 而调用localtime_r 的实现中,对时区进行了 ...
- Java多线程-线程的交互
一.线程交互的基础知识void notify():唤醒在此对象监视器上等待的单个线程. void notifyAll():唤醒在此对象监视器上等待的所有线程. void wait():导致当前的线程等 ...
- Unity抗锯齿的设置
[Unity抗锯齿的设置] "Edit"->"Project Settings"->"Quality",可以质量设置Inspec ...