do...while(0) do...while(false)的妙用.doc_第1页
do...while(0) do...while(false)的妙用.doc_第2页
do...while(0) do...while(false)的妙用.doc_第3页
do...while(0) do...while(false)的妙用.doc_第4页
do...while(0) do...while(false)的妙用.doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

do.while(0) do.while(false)的妙用 在C+中,有三种类型的循环语句:for, while, 和do.while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do.while相对不受重视。 但是,最近在读我们项目的代码时,却发现了do.while的一些十分聪明的用法,不是用来做循环,而是用作其他来提高代码的健壮性。1. do.while(0)消除goto语句。通常,如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样:version 1cpp view plaincopy1. boolExecute()2. 3. /分配资源4. int*p=newint;5. boolbOk(true);6. 7. /执行并进行错误处理8. bOk=func1();9. if(!bOk)10. 11. deletep;12. p=NULL;13. returnfalse;14. 15. 16. bOk=func2();17. if(!bOk)18. 19. deletep;20. p=NULL;21. returnfalse;22. 23. 24. bOk=func3();25. if(!bOk)26. 27. deletep;28. p=NULL;29. returnfalse;30. 31. 32. /.33. 34. /执行成功,释放资源并返回35. deletep;36. p=NULL;37. returntrue;38. 39. 这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。于是我们想到了goto:version 2 cpp view plaincopy1. boolExecute()2. 3. /分配资源4. int*p=newint;5. boolbOk(true);6. 7. /执行并进行错误处理8. bOk=func1();9. if(!bOk)gotoerrorhandle;10. 11. bOk=func2();12. if(!bOk)gotoerrorhandle;13. 14. bOk=func3();15. if(!bOk)gotoerrorhandle;16. 17. /.18. 19. /执行成功,释放资源并返回20. deletep;21. p=NULL;22. returntrue;23. 24. errorhandle:25. deletep;26. p=NULL;27. returnfalse;28. 29. 代码冗余是消除了,但是我们引入了C+中身份比较微妙的goto语句,虽然正确的使用 goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码 冗余呢,请看do.while(0)循环:version3 cpp view plaincopy1. boolExecute()2. 3. /分配资源4. int*p=newint;5. 6. boolbOk(true);7. do8. 9. /执行并进行错误处理10. bOk=func1();11. if(!bOk)break;12. 13. bOk=func2();14. if(!bOk)break;15. 16. bOk=func3();17. if(!bOk)break;18. 19. /.20. 21. while(0);22. 23. /释放资源24. deletep;25. p=NULL;26. returnbOk;27. 28. “漂亮!”, 看代码就行了,啥都不用说了. 2 宏定义中的do.while(0) 如果你是C+程序员,我有理由相信你用过,或者接触过,至少听说过MFC, 在MFC的afx.h文件里面, 你会发现很多宏定义都是用了do.while(0)或do.while(false), 比如说:#define AFXASSUME(cond) do bool _afx_condVal=!(cond); ASSERT(_afx_condVal); _analysis_assume(_afx_condVal); while(0)粗看我们就会觉得很奇怪,既然循环里面只执行了一次,我要这个看似多余的do.while(0)有什么意义呢? 当然有!为了看起来更清晰,这里用一个简单点的宏来演示:#define SAFE_DELETE(p) do delete p; p = NULL while(0)假设这里去掉do.while(0),#define SAFE_DELETE(p) delete p; p = NULL;那么以下代码:if(NULL != p) SAFE_DELETE(p)else .do sth.就有两个问题,1) 因为if分支后有两个语句,else分支没有对应的if,编译失败2) 假设没有else, SAFE_DELETE中的第二个语句无论if测试是否通过,会永远执行。你可能发现,为了避免这两个问题,我不一定要用这个令人费解的do.while, 我直接用括起来就可以了#define SAFE_DELETE(p) delete p; p = NULL;的确,这样的话上面的问题是不存在了,但是我想对于C+程序员来讲,在每个语句后面加分号是一种约定俗成的习惯,这样的话,以下代码:if(NULL != p) SAFE_DELETE(p);else .do sth.其else分支就无法通过编译了(原因同上),所以采用do.while(0)是做好的选择了。也许你会说,我们代码的习惯是在每个判断后面加上, 就不会有这种问题了,也就不需要do.while了,如:if(.) else诚然,这是一个好的,应该提倡的编程习惯,但一般这样的宏都是作为library的一部分出现的,而对于一个library的作者,他所要做的就是让其库具有通用性,强壮性,因此他不能有任何对库的使用者的假设,如其编码规范,技术水平等。3 消除多层嵌套的条件语句举个例子:你去商店买裙子,进入商店后发现只有一条(假设哈)。你想要红色的连衣裙。有个Check函数,以商店的裙子作为参数,检查它是否符合你的要求。符合则付钱,然后离开,不符合直接离开。那么正常情况的代码如下:cpp view plaincopy1. boolCheck(item)2. 3. if(是连衣裙)4. 5. if(是红色)6. 7. if(合身)8. 9. 付钱10. 11. 12. 13. 离开商店14. 当条件不适合的时候,就要跳过付钱环节,但离开商店是必须得做的。是不是觉得这个if的嵌套太复杂呢?如果还不明显,你可以在条件中再加入价钱等其他更多的条件,这样,这个深层次的if嵌套就很不美观了。(换用否定条件也不能改变if的嵌套)而如果使用do-while(false),则可去除这种嵌套。代码变成如下:cpp view plaincopy1. voidCheck(item)2. 3. do4. 5. if(不是连衣裙)6. break;7. if(不是红色)8. break;9. if(不合身)10. break;11. 付钱12. while(false);13. 14. 15. 16. 离开商店17

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论