C语言中的条件编译
通常情况,我们想让程序选择性地执行,多会使用分支语句,比如if-else 或者switch-case 等。但有些时候,可能在程序的运行过程中,某个分支根本不会执行。
比如我们要写一个跨平台项目,要求项目既能在Windows下运行,也能在Linux下运行。这个时候,如果我们使用if-else,如下:
Windows 有专有的宏_WIN32
,Linux 有专有的宏__linux__
if(_WIN32)
printf("Windows下执行的代码\n");
else if(__linux__)
printf("Linux下执行的代码\n");
else
printf("未知平台不能运行!\n");
这段代码存在两个问题:1、 在Windows下并没有定义__linux__,编译的时候会报错,同样在Linux中也没有定义_WIN32。2、 假定这段程序可以运行,那么在Windows环境下另外两个分支的代码根本不可能运行,同理在Linux下也一样。
处理这种情况我们可以使用条件编译。条件编译,顾名思义,就是根据一定的条件进行选择性的编译,我们要达到的效果,就是在Windows环境下另外两个分支的语句根本不会编译,这样生成的可执行文件中,也不会还有对应语句的机器码,这样既提高了编译效率,同时也减小了可执行文件的体积。
条件编译通常可以用三种方式实现:
1、 #if--#elif--#else--#endif语句实现
通过这种方法实现的代码为:
#if(_WIN32)
printf("Windows下执行的代码\n");
#elif (__linux__)
printf("Linux下执行的代码\n");
#else
printf("未知平台不能运行!\n");
#endif
使用这种方式时需要注意,宏定义为真实#if才会执行,也就是说:
假如有宏定义#define _WIN32 0 这个时候#if是不会执行的。需要定义为#define _WIN32 1才会执行
2、 通过#ifdef--#else--#endif语句实现
通过这种方式实现的代码为
#ifdef(_WIN32)
printf("Windows下执行的代码\n");
#else
printf("Linux下执行的代码\n");
#endif
这种方法下只需要定义了_WIN32就可以,没有必要为真,也就是说
如果有宏定义#define _WIN32 0 上面#ifdef语句也是可以执行的,甚至#define _WIN32 上面的#ifdef也可以运行
当然也可以加入第一种方法中的#elif语句
#ifdef(_WIN32)
printf("Windows下执行的代码\n");
#elif (__linux__)
printf("Linux下执行的代码\n");
#else
printf("未知平台不能运行!\n");
#end
但是需要注意的是,这种情况下,要想#elif语句执行__linux__的值必须为真!(同时没有定义_WIN32)
3、 使用#ifndef语句,这种情况类似第二种,ifndef就是如果没有定义宏,就执行。
在gcc编译工具中
我们可以使用-D选项,动态地定义程序所需要的宏
比如我们可以这样编译 gcc test.c -o test -D _WIN32 这样程序就可以在Windows下运行了(当然,实际情况是在Windows环境下,_WIN32已经被定义) gcc中的-D选项会默认将宏定义为1,如果要定义为其他的值使用等于号如:-D _WIN32=0
很多的时候,尤其是实际的项目中,我们会使用cmake工具来构建自己的程序。
在cmake中
我们可以在CMakeLists.txt中写入ADD_DEIFNITIONS(-D _WIN32)来添加程序运行时用到的宏。但是这样,一旦我们需要修改使用的宏,就要修改CMakeLists.txt文件,会很麻烦。
这时我们可以这样做:
在CMakeLists.txt中写入
IF(ENVIRO)
ADD_DEFINITIONS(-D _WIN32)
ENDIF(ENVIRO)
这样,我们可以在使用cmake命令的时候加入-D选项,定义ENVIRO 命令如下
cmake -D ENVIRO=1,或者 cmake -D ENVIRO=ON
如果要取消这个定义可以使用: cmake -D ENVIRO=OFF 或 cmake -D ENVIRO=0 或者cmake -U ENVIRO
就写到这里了,希望对你有帮助。。水平有限,有错误的地方还请谅解,并诚邀指正。。
C语言中的条件编译的更多相关文章
- golang项目中使用条件编译
golang项目中使用条件编译 C语言中的条件编译 golang中没有类似C语言中条件编译的写法,比如在C代码中可以使用如下语法做一些条件编译,结合宏定义来使用可以实现诸如按需编译release和de ...
- C语言学习笔记--条件编译
C语言中的条件编译的行为类似于 C 语言中的 if…else…,是预编译指示命令,用于控制是否编译某段代码 . 1.条件编译的本质 (1)预编译器根据条件编译指令有选择的删除代码 (2)编译器不知道代 ...
- c语言中条件编译相关的预编译指令
一. 内容概述 本文主要介绍c语言中条件编译相关的预编译指令,包括#define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. 二.条件编 ...
- C语言中的宏定义
目录(?)[-] 简单宏定义 带参数的宏 运算符 运算符 宏的通用属性 宏定义中圆括号 创建较长的宏 较长的宏中的逗号运算符 宏定义中的do-while循环do 空操作的定义 预定义宏 C语言中常用的 ...
- C语言中的调试小技巧
C语言中的调试小技巧 经常看到有人介绍一些IDE或者像gdb这样的调试器的很高级的调试功能,也听人说过有些牛人做工程的时候就用printf来调试,不用特殊的调试器.特别是在代码经过编译器一些比较复杂的 ...
- C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)
c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络 ...
- C 语言中的预处理
C 语言中以 # 开头的就是预处理指令,例如 #include . 预处理指令的用途 所有的预处理指令都会在 GCC 编译过程的预处理步骤解析执行,替换为对应的内容.在下一步编译过程中,看不到任何预处 ...
- JAVA语言中的修饰符
JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...
- Java语言中的面向对象特性总结
Java语言中的面向对象特性 (总结得不错) [课前思考] 1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类? 2. 面向对象编程的特性有哪三个?它们各自又有哪些特性? 3. 你知 ...
随机推荐
- hdu 4983 欧拉函数
http://acm.hdu.edu.cn/showproblem.php?pid=4983 求有多少对元组满足题目中的公式. 对于K=1的情况,等价于gcd(A, N) * gcd(B, N) = ...
- web.xml文件中context-param、listener、filter、servlet的执行顺序
首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出的结论是:listener -> ...
- Android-DateUtil工具类
时间相关工具类 public class DateUtil { private DateUtil(){} /** * 枚举日期格式 */ public enum DatePattern{ /** * ...
- AndroidPn服务端部分bug解决方案
目前推送的情况已经大致可以了,可以正常推送.但是要在实际生产中使用,要改进很多地方. 原本的版本,是不会对消息重新发送的.消息如果丢失,或者用户没有在线,消息也不会重新的发送.所以,这些问题都是要解决 ...
- 【实战TFS】【QQ群】了解别人是如何使用TFS的
长时间在这个QQ群里面混,了解到其他人是如何使用TFS系统的,也与网友们一起探讨,共同提高,还有分享的大量资料文档. 推荐一下:):)
- LeetCode146:LRU Cache
题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...
- ASP.NET下使用Combres对JS、CSS合并和压缩
记录一下,如何简单快捷压缩js和css,通过合并来减少请求次数. 用到的网址: http://www.nuget.org/packages/combres/ https://github.com/bu ...
- SQL 2012新分页方式
--2012的OFFSET分页方式 (推荐使用 - 较为方便) select number from spt_values where type='p' order by number offset ...
- Plugin 'FEDERATED' is disabled. /usr/sbin/mysqld: Table 'mysql.plugin' doesn't exist
问题:在linux上安装mysql的时候出现Plugin ‘FEDERATED’ is disabled. /usr/sbin/mysqld: Table ‘mysql.plugin’ doesn’t ...
- MySQL(增删改查补充)
SQL语句数据行操作补充 create table tb12( id int auto_increment primary key, ...