C语言中宏定义(#define)时do{}while(0)的价值(转)
C语言中宏定义(#define)时do{}while(0)的价值
最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总结了一下讨论,加上自己的理解,do{...}while(0)的价值主要体现在:
1. 增加代码的适应性
下面的宏定义没有使用do{...}while(0)
#define FOO(x) foo(x); bar(x);
这样宏定义,单独调用不会出现问题,例如:
FOO(100)
宏扩展后变成:
|
1
|
foo(x);bar(x); |
这样调用FOO没有任何问题,但是FOO(x)不能放入控制语句中,例如
|
1
2
3
4
|
if (condition) FOO(x);else ...; |
经过宏扩展后,变成了
if (condition)
foo(x);bar(x);
else
...;
这样就导致了语法错误,语法错误并不可怕,在编译阶段就能发现,更致命的是他有可能导致逻辑错误,这种错误编译器发现不了,一出这种问题,程序员就抓狂吧。例如:
if (condition)
FOO(x);
这段代码经过扩展后变成:
if (condition)
foo(x); bar(x);
这样一来,无论condition是true还是false,bar(x)都会被调用。有没有被这煎熬过的兄弟啊?
这时候do{...}while(0)的价值就体现出来了,修改一下FOO的定义
#define FOO(x) do { foo(x); bar(x); } while (0)
这样FOO,放入控制语句中就没有问题了。
也许有人说:把foo(x);bar(x)用大括号括起来不就行了吗?比如这样定义:
#define FOO(x) { foo(x); bar(x); }
再看下面代码:
if (condition)
FOO(x);
else
...;
扩展后:
if (condition)
{foo(x);bar(x);} ; //注意最后这个分号,语法错误
else
...;
照样语法错误;
2.增加代码的扩展性
我理解的扩展性,主要是宏定义中还可以引用其他宏,比如:
#define FOO(x) do{OTHER_FOO(x)} while(0)
这样我们不用管OTHER_FOO是但语句还是符合语句,都不会出现问题
3.增加代码的灵活性
灵活性主要体现在,我们可以从宏中break出来,例如下面的定义:

#define FOO(x) do{ \
foo(x); \
if(condition(x)) \
break; \
bar(x) \
..... \
} while(0)

C语言中宏定义(#define)时do{}while(0)的价值(转)的更多相关文章
- C语言中宏定义#define 、 typedef 和枚举类型
替换时机 #define :预编译阶段简单替换,编译阶段展开源程序(1.词法扩展==程序生成期间的字符串替换 2.语义扩展==生成特定指令) 枚举常量:编译阶段确定其值 内联函数:编译阶段插入代码 t ...
- c 语言中宏定义和定义全局变量的区别
宏定义和定义全局变量的区别: 1 作用时间不同. 宏定义在编译期间即会使用并替换,而全局变量要到运行时才可以. 2 本质类型不同. 宏定义的只是一段字符,在编译的时候被替换到引用的位置.在运行中是没有 ...
- C语言中宏定义(#define)时do{}while(0)的价值
最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总结了一下讨论,加上自己的理解,do{...}while(0)的价值 ...
- C语言中宏定义(#define)时do{}while(0)
参考链接: http://www.cnblogs.com/fengc5/p/5083134.html 1.用于宏定义, 在该函数可以调用其它的宏,做其它内容的处理
- C语言中宏定义与C++中的内联函数
一,宏定义:在预处理的时候把宏定义的内容替换到代码中,正常编译. 1,无参数宏定义和有参数宏定义 (1)宏定义不能加分号,比如:#define PI 3.24;错的,#define PI 3.24 ...
- c语言中宏定义和常量定义的区别
他们有共同的好处就是"一改全改,避免输入错误"哪两者有不同之处吗?有的. 主要区别就在于,宏定义是在编译之前进行的,而const是在编译阶段处理的 宏定义不占用内存单元而const ...
- c语言中宏定义#和 ##的作用:
转载:http://www.cnblogs.com/cyttina/archive/2013/05/11/3072969.html 看了这篇文章后了解了,但是文章中的例子比较特别,我在这里加个注释好了 ...
- C语言宏定义#define用法
#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...
- 宏定义#define整理
一.宏定义#define 优点:一方面可以节省程序的空间上的篇幅,另外,恰当地使用宏定义可提高程序的时间效率.代码可以写的通俗易懂.可以提高程序的清晰性.可读性,使于修改移植等. 缺点:宏定义的使用实 ...
随机推荐
- 更新Android SDK 出错 Failed to rename directory \temp\ToolPackage.old01
打算更新Android SDK 版本到 Android SDK Tools 20,打开SDK Manager.exe 开始更新,结果安装时弹出错误提示:Failed to rename directo ...
- (转) 学习C++ -> 类(Classes)的定义与实现
学习C++ -> 类(Classes)的定义与实现 一."类" 的介绍 在C++中, 用 "类" 来描述 "对象", 所谓的&q ...
- (原)测试intel的并行计算pafor
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/4988264.html 参考网址: 关于mt19937:http://www.cnblogs.com/e ...
- WAMP下定义wordpress固定连接出现文章页面404
在修改为如下设置后,一切更新正常,但回到博客主页访问单独文章时出现了404问题 最后一项改为index.php/%postname%后可正常访问,但是去掉那个php文件则不行. 找到的解决方法为:开启 ...
- 【转载】solr教程,值得刚接触搜索开发人员一看
转载:http://blog.csdn.net/awj3584/article/details/16963525 Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍 ...
- 数字转化为人民币大写(PHP)
<?php function numTrmb($num) { $d = array("零", "壹", "贰", "叁&qu ...
- 小插曲之变量和字符串 - 零基础入门学习Python003
小插曲之变量和字符串 让编程改变世界 Change the world by program 变量 (此处只是省略N多细节,详细通过视频学习) 变量名就像我们现实社会的名字,把一个值赋值给一个名字时, ...
- [statsvn]-svn代码量统计
用statasvn进行代码量统计的时候,第一步需要获取到项目的日志,但是我本机的svn1.4没有安装命令行,重新运行1.4的安装包也没有命令行的选项... 那就升级到最新的svn1.8好了,下载最新的 ...
- 巧用Graphviz和pvtrace等工具可视化C函数调用
http://guiquanz.github.io/2012/10/15/linux_c_call_trace/
- grok 官方文档
<pre name="code" class="html">grok: 解析任意文本并构造它: Grok 是当前最好的方式在logstash 解析蹩 ...