当前位置: 首页 > news >正文

do{}while(0)

do{}while(0)

do{}while(false)

do{}while(__LINE__==-1)

1.用在出错处理中,替代goto


  
// 使用goto
bool Func()
{
bool ret = true ;

ret
= Func1();
if ( ! ret) goto err;

ret
= Func2();
if ( ! ret) goto err;

ret
= Func3();
if ( ! ret) goto err;

// ...
return true ;

err:
// ...
return false ;
}

但由于goto地位比较特殊,对是否使用它有很大争议,容易让程序逻辑不易看清,下面是用do{}while(0)替代


  
// 使用do{}while(0)
bool Func()
{
bool ret = true ;

do
{
ret
= Func1();
if ( ! ret) break ;

ret
= Func2();
if ( ! ret) break ;

ret
= Func3();
if ( ! ret) break ;

// ...
return true ;

}
while ( 0 );

// ...
return false ;
}

2.用在宏中,用来封闭代码

一般会定义这么一个宏专门用于封闭代码,防止在if...else...语句中出错


  
#define st(x) do { x } while (__LINE__ == -1)

比如定义一个简单的宏,有下面四种方法,第一和第二种是一样的,后面两种在if/else结构中就会出错:


  
#define SET_REGS_1() st( ioreg1 = 0; ioreg2 = 0; )
#define SET_REGS_2() do{ ioreg1 = 0; ioreg2 = 0; }while(__LINE__ == -1)
#define SET_REGS_3() { ioreg1 = 0; ioreg2 = 0; }
#define SET_REGS_4() ioreg1 = 0; ioreg2 = 0;

分析:

比如下面语段会编译出错


  
if (ret)
SET_REGS_3();
else
{
// ...
}

将其宏展开就会发现,这里多出一个分号,造成后面的else无法找到匹配的if,同样的,将第四种宏展开也可以发现类似的问题。


  
if (ret)
{ ioreg1
= 0 ; ioreg2 = 0 ; };
else
{
// ...
}

当只有if时能编译,但用第四种也会出问题


  
if (ret)
SET_REGS_4();

展开后会发现无论ret为何值,ioreg2 = 0;这条语句都会被执行


  
if (ret)
ioreg1
= 0 ; ioreg2 = 0 ;;

如果写成这样,就不会出问题,但宏的定义需要考虑到通用性,所以,一般用do{}while(0)来封闭代码,这里也同样

看出,在写代码时,要有好习惯


  
if (ret)
{
SET_REGS_3();
}
else
{
// ...
}

展开后为


  
if (ret)
{
{ ioreg1
= 0 ; ioreg2 = 0 ; };
}
else
{
// ...
}

参考:

1. http://bbs.chinaunix.net/viewthread.php?tid=670238

2. http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html

转载于:https://www.cnblogs.com/YYi_H/archive/2011/04/25/2027314.html

相关文章:

  • 操作系统复习
  • 精通Camel-2-Camel的生命周期
  • zabbix命令之:zabbix_sender命令
  • 一打开网页,任务栏就消失的问题
  • Oracle 10g11g安装卸载Oracle Label Security
  • 如何在CentOS 5.5上安装Kippo蜜罐(1)
  • MySQL入门:下载
  • Pycharm 快捷键
  • 我那魂牵梦绕的故乡
  • RESTful风格编程
  • 修复fstab文件
  • 广域网协议配置四
  • LeetCode 894. All Possible Full Binary Trees
  • git预览项目
  • How does SGA/PGA allocate on AMM?
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • Android系统模拟器绘制实现概述
  • Java反射-动态类加载和重新加载
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • JS专题之继承
  • tensorflow学习笔记3——MNIST应用篇
  • vue数据传递--我有特殊的实现技巧
  • 技术胖1-4季视频复习— (看视频笔记)
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端工程化(Gulp、Webpack)-webpack
  • 微信小程序实战练习(仿五洲到家微信版)
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​ubuntu下安装kvm虚拟机
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (floyd+补集) poj 3275
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (二)springcloud实战之config配置中心
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (六)激光线扫描-三维重建
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)菜鸟学数据库(三)——存储过程
  • (转载)Google Chrome调试JS
  • **PHP二维数组遍历时同时赋值
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET 5种线程安全集合
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net Remoting常用部署结构
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .Net中的集合