do{...}while(0)的意义

    do{

    ...

    }while(0)

    这样的代码不会循环执行,表面上看没有什么意义,为什么还要这么用呢?这不仅仅是用于美化代码。主要有以下几点好处:

   1、辅助定义复杂的宏,避免引用的时候出错:

    比如要定义这样的一个宏:

    #define DOSOMETHING()\

                                   foo1();\

                                   foo2();

    本意是在调用DOSOMETHING()时,函数 foo1() 和 foo2() 都会被调用。但是在遇到条件判断的时候,会出错:

    if(a>0)

        DOSOMETHING();

    宏在预处理的时候会直接被展开,展开后会变成下面的样子:

     if(a>0)

          foo1();

     foo2();

      这就会出错,那么用 {} 将 foo1() 和 foo2() 包起来行么?答案是不行,因为在上例调用 DOSOMETHING() 的时候在末尾加上了分号,如果使用 {},则代码会变成:

     if(a>0)

     {

         foo1();

         foo2();

     };

     这样编译甚至不会通过。所以采用 do{...}while(0)来解决。

     #define DOSOMETHING() \

                     do{   \

                            foo1(); \

                            foo2(); \

                       }while(0) \

       这样,宏展开后,才会保留初始的语义。GCC提供了 Statement-Expressions 用以替代 do{...}while(0),所以也可以这样定义宏:

       #define  DOSOMETHING()  ({ \

                           foo1(); \

                           foo2(); \

                                })

       2、避免使用 goto 对程序流进行统一的控制:

       有些函数中,在函数 return 之前我们经常会进行一些收尾的工作,比如 free 掉一块函数开始 malloc 的内存,goto一直都是一个比较简便的方法:

       int foo()

       {

            somestruct* ptr = malloc(...);

            dosomething...;

            if(error)

            {

                 goto  END;

            }

            dosomething...;

            if(error)

            {

                  goto END;

            }

            dosomething...;

       END:

             free(ptr);

             return 0;

       }

       由于 goto 不符合软件工程的结构化,而且有可能使得代码难懂,所以很多人都不提倡使用,这时就可以用 do{...}while(0) 来统一管理:

       int  foo()

       {

            somestruct* ptr = malloc(...);

            do{

                   dosomething...;

                   if(error)

                   {

                        break;

                   }

                   dosomething...;

                   if(error)

                   {

                        break;

                   }

                   dosomething...;

            }while(0)

            free(ptr);

            return 0;

       }

       3、避免空宏引起的 warning

       内和中由于不同架构的限制,很多时候会用到空宏,在编译的时候,空宏会给出 warning ,为了避免这样的 warning ,就可以用 do{}while(0) 来定义空宏:

              #define  EMPTYMICRO  do{}while(0)

       4、定义一个单独的函数块来实现复杂的操作:

       当你的功能很复杂,变量很多你又不愿意增加一个函数的时候,使用 do{}while(0);,将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复。





  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值