`
liyiwen007
  • 浏览: 105561 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

do {} while (0)的用途

 
阅读更多

#define MACRO_NAME(para) do{macro content}while(0)

  的格式,总结了以下几个原因: 

 

1、空的宏定义避免warning:

#define foo() do{}while(0)
  

2、存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。 

 

3、如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:

#define foo(x) \
    action1(); \
    action2();
  

 在以下情况下:

if(NULL == pPointer)
   foo();
 就会出现action1action2不会同时被执行的情况,而这显然不是程序设计的目的。

  

4,以上的第3种情况用单独的{}也可以实现,但是为什么一定要一个do{}while(0)呢,看以下代码: 

 

#define switch(x,y) {int tmp; tmp="x";x=y;y=tmp;}
  
if(x>y)
    switch(x,y);
else       //error, parse error before else
    otheraction();
 在把宏引入代码中,会多出一个分号,从而会报错。

 

//------------------------------------------------

使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。

 

 

do...while(0)消除goto语句。
通常,如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样:

bool Execute()
{
   // 分配资源
   int *p = new int;
   bool bOk(true);

   // 执行并进行错误处理
   bOk = func1();
   if(!bOk) 
   {
      delete p;   
      p = NULL;
      return false;
   }

   bOk = func2();
   if(!bOk) 
   {
      delete p;   
      p = NULL;
      return false;
   }

   bOk = func3();
   if(!bOk) 
   {
      delete p;   
      p = NULL;
      return false;
   }

   // ..........

   // 执行成功,释放资源并返回
    delete p;   
    p = NULL;
    return true;   
}

     这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。于是我们想到了goto:

 

bool Execute() {
   // 分配资源
   int *p = new int;
   bool bOk(true);

   // 执行并进行错误处理
   bOk = func1();
   if(!bOk) goto errorhandle;

   bOk = func2();
   if(!bOk) goto errorhandle;

   bOk = func3();
   if(!bOk) goto errorhandle;

   // ..........

   // 执行成功,释放资源并返回
    delete p;   
    p = NULL;
    return true;

errorhandle:
    delete p;   
    p = NULL;
    return false;   
}
  代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,虽然正确的使用goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码冗余呢,请看do...while(0)循环:
bool Execute()
{
   // 分配资源
   int *p = new int;

   bool bOk(true);
   do
   {
      // 执行并进行错误处理
      bOk = func1();
      if(!bOk) break;

      bOk = func2();
      if(!bOk) break;

      bOk = func3();
      if(!bOk) break;

      // ..........

   }while(0);

    // 释放资源
    delete p;   
    p = NULL;
    return bOk;   
}
 

分享到:
评论

相关推荐

    浅谈do {…} while (0) 在宏定义中的作用

    如果你是一名C程序员,你肯定很熟悉宏,它们非常强大,如果正确使用可以让你的工作事半功倍。...在Linux内核和其它一些著名的C库中有许多使用do{…}while(0)的宏定义。这种宏的用途是什么?有什么好处? Google的Robert

    十进位,八进制,十六进位,二进位相互转换大全

    十进位,八进制,十六进位,二进位相互转换大全 ' 用途:将十进位转化为二进位 ' 输入:Dec(十进位数字) ... Do While Dec > 0 DEC_to_BIN = Dec Mod 2 & DEC_to_BIN Dec = Dec \ 2 Loop End Function

    PPT抽奖程序-名单抽取

    Do While True Sleep 30 I = Int(((UBound(arrRM) + 1) * Rnd) + 0) ' TextBox3 = TextBox3 & "-" & I TextBox2.Text = arrRM(I) If F = 1 Then Exit Do DoEvents Loop Else F = 1 End If End Sub ...

    C语言程序设计(第四版)笔记

    ④具有结构化的控制语句(如if…else、while、do…while、switch、for) ⑤语法限制不太严格,程序设计自由度大。 ⑥允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。 ⑦生成目标代码质量高,...

    Shell脚本一次读取文件中一行的2种写法

    写法一: 代码如下: #!/bin/bash while read line do  echo $line #这里可根据实际用途变化 done 码如下: var1=$(grep>/dev/null) <=读

    揭秘数据解密的关键技术

    内容简介  《揭秘数据解密的关键技术》[1]是一本以游戏资源...2.6 汇编中的循环——C语言中的循环 2.6.1 循环的定义 2.6.2 while语句的实现机制 2.6.3 do...while语句实现机制 2.6.4 for语句的实现机制。。。。。。。

    C_gjz.rar_float

    do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void Volatile while 说明: 1、关键字auto用于说明自动变量,由于变量...

    一些C面试题,希望能对大家有帮助

    5、do……while和while……do有什么区别? 答:前一个循环一遍再判断,后一个判断以后再循环 6、请写出下列代码的输出内容 #include main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c,d:%d,%d...

    tcon:一个稍微懒惰的shell脚本,用于通过FIFO队列与tmux窗格运行并行命令

    tcon用途引擎盖下,你可以通过xpanes参数tcon并发限制后利用它充分利用。 用法 # Echo a line and sleep afterwards with a concurrency of 4. `-x` is passed along to tmux-xpanes. seq 1 10 | (while read f ;...

    如何编写批处理文件批处理文件批处理文件

    DOS程序运行时都会返回一个数字给DOS,称为错误码errorlevel或称返回码,常见的返回码为0、1。 10.for 命令 for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。 在批处理文件中使用 FOR 命令...

    零起点学通C++多媒体范例教学代码

    7.4. do……while循环 7.5 for循环 7.5.1 灵活的for循环 7.5.2 条件为空的for循环 7.5.3 执行为空的for循环 7.5.4 嵌套的for循环 7.6 switch语句 7.6.1 switch语句常见错误 7.6.2 switch的菜单功能 7.7 总结 第8章 ...

    零起点学通C++学习_多媒体范例教学代码

    7.4. do……while循环 7.5 for循环 7.5.1 灵活的for循环 7.5.2 条件为空的for循环 7.5.3 执行为空的for循环 7.5.4 嵌套的for循环 7.6 switch语句 7.6.1 switch语句常见错误 7.6.2 switch的菜单功能 7.7 ...

    java基础知识下载

    abstract,break,byte,boolean,catch,case,class,char,continue,default,double,do,else,extends,false,final,float,for,finally,if,import,implements,int,interface,instanceof,long,...

    Node.js MongoDB AngularJSWeb开发中文版.part1

    2.4.2 do/while循环 17 2.4.3 for循环 17 2.4.4 for/in循环 18 2.4.5 中断循环 19 2.5 创建函数 19 2.5.1 定义函数 20 2.5.2 传递变量给函数 20 2.5.3 从函数返回值 20 2.5.4 使用匿名函数 21 2.6 理解变量作用域 22...

    最新名企标准通用C++面试题,

    1、const 有什么用途?(请至少说明两种) 答: (1)可以定义 const 常量 (2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 ...

    Visual C# 2005程序设计自学手册 随书源码第一部分(共三部)

    3.2.2 使用do while循环语句控制程序 55 3.2.3 使用for循环语句控制程序 56 3.2.4 使用foreach循环语句控制程序 57 3.3 跳转语句 58 3.3.1 使用break语句实现程序跳转 58 3.3.2 使用continue语句的实现...

    编程思想下篇

    4.3.1 do-while 4.3.2 for 4.3.3 逗号操作符 4.4 Foreach语法 4.5 return 4.6 break和 continue 4.7 臭名昭著的“goto” 4.8 switch 4.9 总结 第5章 初始化与清理 5.1 用构造器确保初始化 5.2 方法重载 5.2.1 区分...

    Thinking in java4(中文高清版)-java的'圣经'

    3.14 使用操作符时常犯的错误 3.15 类型转换操作符 3.15.1 截尾和舍入 3.15.2提升 3.16 Java没有“sizeof” 3.17 操作符小结 3.18 总结 第4章 控制执行流程 4.1 true和false 4.2 if-else 4.3 迭代 4.3.1 do-while ...

    Javascript中的关键字和保留字整理

    break do instanceof typeof case else new var catch finally return void continue for switch while debugger* function this with default if throw delete in try  ECM

    JAVA基础课程讲义

    While和dowhile的区别 41 For循环 42 break语句和continue语句 47 语句块 48 递归结构 49 本章作业 50 本章上机操作 51 第三章 JAVA面向对象程序开发 52 编程语言发展史 52 类和对象是如何产生发展的?如何进化的? 52...

Global site tag (gtag.js) - Google Analytics