C++中,有三种类型的循环语句:for、while、do...while
在一般应用中作循环时,我们可能用for和while要多一些,do...while相对不受重视。但是,最近在读我们项目的代码时,却发现了do...while的一些十分聪明的用法,不是用来做循环,而是用作其他来提高代码的健壮性
1.do...while(0)消除goto语句
通常,如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样:
version1
boolExecute()
{
//分配资源
int*p=newint;
boolbOk(true);
//执行并进行错误处理
bOk=func1();
if(!bOk)
{
deletep;
p=NULL;
returnfalse;
}
bOk=func2();
if(!bOk)
{
deletep;
p=NULL;
returnfalse;
}
bOk=func3();
if(!bOk)
{
deletep;
p=NULL;
returnfalse;
}
//..........
//执行成功,释放资源并返回
deletep;
p=NULL;
returntrue;
}
这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。于是我们想到了goto:
version2
boolExecute()
{
//分配资源
int*p=newint;
boolbOk(true);
//执行并进行错误处理
bOk=func1();
if(!bOk)gotoerrorhandle;
bOk=func2();
if(!bOk)gotoerrorhandle;
bOk=func3();
if(!bOk)gotoerrorhandle;
//..........
//执行成功,释放资源并返回
deletep;
p=NULL;
returntrue;
errorhandle:
deletep;
p=NULL;
returnfalse;
}
代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,虽然正确的使用goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码冗余呢,请看do...while(0)循环:
version3
boolExecute()
{
//分配资源
int*p=newint;
boolbOk(true);
do
{
//执行并进行错误处理
bOk=func1();
if(!bOk)break;
bOk=func2();
if(!bOk)break;
bOk=func3();
if(!bOk)break;
//..........
}while(0);
//释放资源
deletep;
p=NULL;
returnbOk;
}
“漂亮!”,看代码就行了,啥都不用说了...
2宏定义中的do...while(0)
如果你是C++程序员,我有理由相信你用过,或者接触过,至少听说过MFC,在MFC的afx.h文件里面,你会发现很多宏定义都是用了do...while(0)或do...while(false),比如:
#defineAFXASSUME(cond)do{bool__afx_condVal=!!(cond);ASSERT(__afx_condVal);__analysis_assume(__afx_condVal);}while(0)
粗看我们就会觉得很奇怪,既然循环里面只执行了一次,我要这个看似多余的do...while(0)有什么意义呢?
当然有!
为了看起来更清晰,这里用一个简单点的宏来演示:
#defineSAFE_DELETE(p)do{deletep;p=NULL}while(0)
假设这里去掉do...while(0),
#defineSAFE_DELETE(p)deletep;p=NULL;
那么以下代码:
if(NULL!=p)SAFE_DELETE(p)
else...dosth...
就有两个问题,
1)因为if分支后有两个语句,else分支没有对应的if,编译失败
2)假设没有else,SAFE_DELETE中的第二个语句无论if测试是否通过,会永远执行。
你可能发现,为了避免这两个问题,我不一定要用这个令人费解的do...while,我直接用{}括起来就可以了
#defineSAFE_DELETE(p){deletep;p=NULL;}
的确,这样的话上面的问题是不存在了,但是我想对于C++程序员来讲,在每个语句后面加分号是一种约定俗成的习惯,这样的话,以下代码:
if(NULL!=p)SAFE_DELETE(p);
else...dosth...
其else分支就无法通过编译了(原因同上),所以采用do...while(0)是做好的选择了。
也许你会说,我们代码的习惯是在每个判断后面加上{},就不会有这种问题了,也就不需要do...while了,如:
if(...)
{
}
else
{
}
诚然,这是一个好的,应该提倡的编程习惯,但一般这样的宏都是作为library的一部分出现的,而对于一个library的作者,他所要做的就是让其库具有通用性,强壮性,因此他不能有任何对库的使用者的假设,如其编码规范,技术水平等。
转载声明: 本文转自http://tieba.baidu.com/f?kz=263292825(百度贴吧)
分享到:
相关推荐
C++ 2015 英文第三章 数组do...while语句
1 Writing an ANSI C++ Program 1 1.1 Getting Ready to Program....... 2 1.1 A First Program......... 3 1.2 Problem Solving: Recipes....... . 7 1.2.1 Algorithms—Being Precise...... . . 8 1.3 ...
主要介绍了c++中do{...}while(0)的意义和用法,需要的朋友可以参考下
关于 if while do-while 的循环练习
Indefinite Iteration: The while and do Statements 83 Section 3.3. Solving a Problem with Indefinite Iteration 96 Section 3.4. Definite Iteration 105 Section 3.5. Nested Loops 118 Chapter ...
While excitement among C++ experts about these capabilities has reached the community at large, their practical application remains out of reach for most programmers. This book explains what ...
在C++中,有多种类型的循环结构可供选择,包括for循环、while循环和do-while循环。这些循环结构可以帮助程序员重复执行特定的代码块,直到满足某个条件为止。 for循环: for循环是一种常用的循环结构,用于按照指定...
Thus, while we may see a car as a means to transport us and our friends, the automotive brake engineer may see it as a large mass with a small contact area between it and the road (Figure 1.1)....
Many of the problems are drawn directly from experiences I and others have encountered while working with production C++ code. The goal of the questions is to help you draw conclusions from things ...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
完整代码,实验课程设计好帮手!C++语言,结构清晰易于理解
C++ 循环中的一种,它是出口条件循环,这种循环先执行循环体,再判定测试表达式,决定是否应继续执行循环,通常在程序需要获得输入时使用入口条件循环,否则使用出口条件循环更好。 此循环方式较为特殊,需要多练习...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
3.2.4 do-while循环 3.2.5 嵌套的循环 3.3 C++/CLI编程 3.4 小结 3.5 练习 第4章 数组、字符串和指针 4.1 处理多个相同类型的数据值 4.1.1 数组 4.1.2 声明数组 4.1.3 初始化数组 4.1.4 字符数组和字符串处理 4.1.5 ...
do/while(0)的妙用 ....................................................................................................................... 120 28. exit()和return()的区别 .................................
2、实验任务: 1、输入并运行教材《C++语言程序设计》例题2-7,即:用do-while语句编程,求自然数1—10之和。程序正确运行之后,去掉源程序中#include语句.重新编译,观察会有什么问题。 #include...
主要介绍了C++编程中的while与do-while循环语句使用,区别就是while是先判断再执行,而do-while是先执行再判断,需要的朋友可以参考下