简单的看起来,do { } while(0) 可能比较奇怪,看起来像是只是把代码块中的全部执行一遍,但在事实上,这种写法主要有两大用处:
1. do{}while(0) 事实上是一个非常好的用作顺序判断的方法,因为可以在顺序判断的任何一步判断出错时跳出(保存当前出错代码且跳过后续判断),并且可以减少使用if语句的嵌套来让代码看起来可读性更强:
比如在程序初始化的时候我们会做一些各种模块的检查,这时候任何的致命错误应该都会导致程序停止运行并返回错误代码:
sysStatus_e status = STATUS_FAIL;
do
{
if(check1() != STATUS_PASS)
{
status = STATUS_ERR1;
break;
}
if(check2() != STATUS_PASS)
{
status = STATUS_ERR2;
break;
}if(check3() != STATUS_PASS)
{
status = STATUS_ERR3;
break;
}
status = STATUS_PASS;
} while(0);
这时候可以通过这种方法来控制程序当前的错误/通过的状态。当然还有很多其他的方法也可以做到相同的结果,但使用do{}while(0)不失为一种简单的方法,代码也比较简洁易懂。
2. 在C中,如果需要宏定义多个执行语句,可以用do{}while(0)把所有语句绑定在一起执行,尤其是这个宏定义需要用于if条件语句中,这种用法在网上有很多示例,这里只做简单介绍:
比如需要定义一个宏定义:
#define doSomething() action1(); action2();
这个宏定义在if条件中调用时候:
if (statement==1)
doSomething();
else
// so something else
代码在真正运行时是:
if (statement==1)
action1();
action2();
else
// do something else
如果稍作更改,用大括号将两个执行语句放在一起,那么会变成:
#define doSomething() {action1(); action2();};
但这样在代码在真实运行时如果后面有else,else会因为最后分号的影响而无法找打对应的if从而导致编译出错。
if (statement==1)
{
action1();
action2();
};
else
// do something else
其实这个宏定义的问题可以通过代码规范性来避免,就是每一个if和else的执行语句都使用大括号来形成代码块。
如果使用do{}while(0)也可以达到相同目的,宏定义会变成:
#define doSomething() do{action1(); action2();}while(0)