我的主题是,有时候知道一些细节会让你写出更好的代码。

============================================

之前学coocs2d-x的时候,发现有非常多do...while(0)的写法,一開始不明确为什么如此写,(起不到循环的作用),然后找了一下资料,发现这东西用处还蛮多的。如今来总结一下:

do...while(0)的妙用。

1.避免goto的使用

比方说我们须要在函数中处理一些错误。遇到错误则退出函数。当然退出之前我们须要释放一下资源。比方以下这样子:

bool HelloWorld::init()
{
// 分配资源
int *p = new int;
bool bRet = true; // 运行并进行错误处理
bRet = func1();
if(!bRet)
{
delete p;
p = NULL;
return false;
} bRet = func2();
if(!bRet)
{
delete p;
p = NULL;
return false;
} bRet = func3();
if(!bRet)
{
delete p;
p = NULL;
return false;
} // .......... // 运行成功,释放资源并返回
delete p;
p = NULL;
return true;
}

这样写最大的问题就是代码冗余。每次添加一个操作,就要处理一次,不灵活。所以这时候哦我们想到了goto,然后上面的版本号变成例如以下:

bool HelloWorld::init()
{
// 分配资源
int *p = new int;
bool bRet = true; // 运行并进行错误处理
bRet = func1();
if(!bRet) goto error; bRet = func2();
if(!bRet) goto error; bRet = func3();
if(!bRet) goto error; // 运行成功。释放资源并返回
delete p;
p = NULL;
return true; error:
delete p;
p = NULL;
return false;
}

当然,goto这东西尽管灵活方便,可是非常危急(这就跟红颜祸水这是一个意思,咦。怎么扯上这个了?)所以大部分的书籍都会建议你尽量程序中不要使用这个东西。

所以我们能够使用do...while来消除它。

例如以下:

bool HelloWorld::init()
{
// 分配资源
int *p = new int;
bool bRet = true; do
{
// 运行并进行错误处理
bRet = func1();
if(!bRet) break; bRet = func2();
if(!bRet) break; bRet = func3();
if(!bRet) break; }while(0); // 运行成功,释放资源并返回
delete p;
p = NULL;
return bRet;
}

2.宏定义中的do...while(0)

常常我们能在宏定义中看到这货的影子,比方说cocos2d-x中的

#define CC_SAFE_DELETE(p)    do { delete (p); (p) = nullptr; } while(0)

那么又没有循环,也仅仅运行了一次,这样子写有什么意义呢?

假如我们去掉do...while。例如以下:

#define CC_SAFE_DELETE(p)    delete (p); (p) = nullptr; 

if (p != NULL)
CC_SAFE_DELETE(p); //上面会转换成这样子
if (p != NULL)
delete (p);
(p) = nullptr;

如上。第二句永远运行,明显不合意思。有人可能会说,假设再加个括号呢,比方:

#define CC_SAFE_DELETE(p)    {delete (p); (p) = nullptr; }

//有可能碰到这样的情况
if (p != NULL)
CC_SAFE_DELETE(p);
else
//do else sth //上面会转换成这样
if (p != NULL)
{
delete (p);
(p) = nullptr;
};
else
//do else sth

else直接就编译错误了。

或许你会说,我们代码的习惯是在每一个推断后面加上{}, 就不会有这样的问题了,也就不须要do...while了,如:

if(...)
{
}
else
{
}

诚然,这是一个好的,应该提倡的编程习惯。可是我们须要做的是让代码具有通用性,强壮性,因此我们更提倡do...while(0)的使用方法。

========================================

转载请注明出处:http://blog.csdn.net/shun_fzll/article/details/37776429

【C++基础 03】do...while(0)妙用的更多相关文章

  1. javaSE基础03

    javaSE基础03 生活中常见的进制:十进制(0-9).星期(七进制(0-6)).时间(十二进制(0-11)).二十四进制(0-23) 进制之间的转换: 十进制转为二进制: 将十进制除以2,直到商为 ...

  2. 从零3D基础入门XNA 4.0(2)——模型和BasicEffect

    [题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...

  3. 03、NetCore2.0下Web应用之搭建最小框架

    03.NetCore2.0下Web应用之搭建最小框架 这里我们不使用VS2017或者CLI命令的方式创建Asp.Net Core 2.0网页应用程序,而是完全手工的一点点搭建一个Web框架,以便更好的 ...

  4. day33-线程基础03

    线程基础03 6.用户线程和守护线程 用户线程:也叫工作线程,当线程的任务执行完或者通知方法结束.平时用到的普通线程均是用户线程,当在Java程序中创建一个线程,它就被称为用户线程 守护线程(Daem ...

  5. 从零3D基础入门XNA 4.0(1)——3D开发基础

    [题外话] 最近要做一个3D动画演示的程序,由于比较熟悉C#语言,再加上XNA对模型的支持比较好,故选择了XNA平台.不过从网上找到很多XNA的入门文章,发现大都需要一些3D基础,而我之前并没有接触过 ...

  6. javascript基础03

    javascript基础03 1. 算术运算符 后增量/后减量运算符 ++ ,-- 比较运算符 ( >, <, >=, <=, ==, !=,===,!== ) 逻辑运算符( ...

  7. C语言在linux内核中do while(0)妙用之法

    为什么说do while(0) 妙?因为它的确就是妙,而且在linux内核中实现是相当的妙,我们来看看内核中的相关代码: #define db_error(fmt, ...) \ do { \ fpr ...

  8. Thread.Sleep(0)妙用

    Thread.Sleep(0)妙用 我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确的理解这个函数的用法呢?思考下面这两个问题: 假设现在是 2008-4-7  ...

  9. 零基础快速入门SpringBoot2.0 (一)

    零基础快速入门SpringBoot2.0 (一) 一.SpringBoot2.x依赖环境和版本新特性说明 简介:讲解新版本依赖环境和springboot2新特性概述 1.依赖版本jdk8以上, Spr ...

  10. 零基础入门 实战mpvue2.0多端小程序框架

    第1章 课程快速预览(必看!!!)在这一章节中,老师讲带领你快速预览课程整体.其中,涉及到为什么要做这么一门实战课程.制作一个小程序的完整流程是怎么样的,以及如何做项目的技术选型. 第2章 30 分钟 ...

随机推荐

  1. 使用maven进行Javadoc下载

    project -> maven -> Download Sources and Download JavaDocs

  2. Python 进阶 之 socket模块

    Python Socket 编程详细介绍 转载地址:https://gist.github.com/kevinkindom/108ffd675cb9253f8f71?signup=true Pytho ...

  3. Python 进阶 之 lambda 匿名函数

    lambda 是个匿名函数,通常用于简单判断或者处理,例如判断一个数的奇偶性,过滤字符串,逻辑运算等等. lambda表达式: >>>lambda x:x*x >>> ...

  4. (七)MySQL数据操作DQL:多表查询2

    (1)准备环境 1)创建员工表 mysql> create table company.employee6( -> emp_id int auto_increment primary ke ...

  5. 第八届省赛 B:Quadrat (打表找规律)

    Description It is well-known that for any n there are exactly four n-digit numbers (including ones w ...

  6. HDU 1180 诡异的楼梯【BFS/楼梯随时间变化】

    诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submis ...

  7. HDU 多校1.9

  8. python3爬虫爬取网页思路及常见问题(原创)

    学习爬虫有一段时间了,对遇到的一些问题进行一下总结. 爬虫流程可大致分为:请求网页(request),获取响应(response),解析(parse),保存(save). 下面分别说下这几个过程中可以 ...

  9. 树链剖分【p2568】[SDOI2011]染色

    Description 给定一颗有\(n\)个节点的无根树和\(m\)个操作,操作有\(2\)类: 1.将节点\(a\)到节点\(b\)路径上所有点染成颜色\(c\) 2.询问节点\(a\)到节点\( ...

  10. 谜题15:令人晕头转向的Hello

    下面的程序是对一个老生常谈的例子做出了稍许的变化之后的版本.那么,它会打印出什么呢? /** * Generated by the IBM IDL-to-Java compiler, version ...