您的位置:首页 > 编程语言 > C语言/C++

do{}while(0)的妙用

2015-01-05 12:36 211 查看
其实关注do{}while(0)的用法还是一次偶然的机会

当时还在实习,连个工作都找不到,面试的时候有个面试题。

请问do{}while(0)这样写有什么作用?

我当时想这有什么作用,就是里面的代码块执行一遍就是了呗,费劲,胡乱答了几句在上面。

虽然那公司把我录了,但是真的还是很坑的一家公司,呆了两个月自己闪人了。

后面觉得这问题奇怪,就在网上搜了很多关于do{}while(0)用法的文章来看。

总体的作用就是一下几个方面:

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

下面是Cocos2dx的一个宏定义:

#define CC_SAFE_DELETE(p)            do { if(p) { delete (p); (p) = 0; } } while(0)
不得不说Cocos2dx的源码写得还是很严谨的

但是假设这里去掉do{}while(0)和里面的if(p)然后变成下面的这个样子:
#define CC_SAFE_DELETE(p)            delete (p); (p) = 0; 如果用这个宏定义在代码中使用,像以下代码
if(NULL != p)
CC_SAFE_DELETE(p)
else
wordOff();这段代码就有问题了:
a. 因为if分支后面有两条语句了,所以编译就会出问题。这里如果养成好习惯别装大神,加上一对{}这个问题也可以解决。

b. 还有个问题就是如果没有else分支里面的(p)=0会永远执行。因为if后面没括号只执行紧邻的一句代码。

我们在写代码的时候可以让代码严谨细致一点,加一点括号多两行,但是你以后修改Bug不会那么痛苦。

2. 跳出代码块,不执行后面的语句

其实这个功能比较实用一些

很多的条件判断可以用到do{}while(0)的写法

这个用法其实也很简单,精髓就在于用break或者continue来控制流程,跳出代码块。

就像下面的一串代码,看看就能明白了:

bool bFlag = false;
do {
if (!bFlag) {
print("The flag is FALSE");
break;// 用break(continue)跳出了之后就不用执行下面的语句了
//continue;
}
print("Work off.\n");
} while (0);
这里的break跳出循环就有点类似于goto语句了,不过goto太粗糙。

可以自己写个do{}while(0)的代码语句来调试调试,自然而然就领悟了。
还是邓大爷那句话啊,实践是检验真理的唯一标准。

下面是我的项目中通信块用到的do{}while(0)的示例,可以看看加深印象。

do
{
BYTE byProtocol = *(LPBYTE)pMsg;
if (byProtocol <= S2C_BEGIN || byProtocol >= S2C_END){
printf("Invalid Protocol %d\n", (INT)byProtocol);
assert(false);
continue;
}
INT nProSize = GetProtocolSize(byProtocol);
if (nProSize == -1){
nProSize = PROTOCOL_MSG_SIZE + (*(USHORT*) (((CHAR*)pMsg) + PROTOCOL_MSG_SIZE));
}
printf(">>>>ProtocolType %d, Size:%d != ProSize:%d\n", (INT)byProtocol, nSize, nProSize);
//协议出错跳出
if (nProSize != nSize){
printf("Invalid ProtocolType %d, Size:%d != ProSize:%d\n", (INT)byProtocol, nSize, nProSize);
assert(false);
continue;
}
//网络断开
if (!ProcessFunc[byProtocol]){
assert(false);
continue;
}
if(GHLandProtocol::m_pGameSence!=NULL){
(this->*ProcessFunc[byProtocol])(pMsg, nSize);
}
} while(FALSE);好了,关于do{}while(0)我也就只学习到这里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ dowhile0 面试题