欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

do...while(0)的妙用詳細(xì)解析

 更新時(shí)間:2013年09月18日 08:50:07   作者:  
do...while(0)消除goto語句;通常,如果在一個(gè)函數(shù)中開始要分配一些資源,然后在中途執(zhí)行過程中如果遇到錯誤則退出函數(shù),當(dāng)然,退出前先釋放資源

在C++中,有三種類型的循環(huán)語句:for, while, 和do...while, 但是在一般應(yīng)用中作循環(huán)時(shí), 我們可能用for和while要多一些,do...while相對不受重視。
但是我發(fā)現(xiàn)了do...while的一些十分聰明的用法,不是用來做循環(huán),而是用作其他來提高代碼的健壯性。

1. do...while(0)消除goto語句
通常,如果在一個(gè)函數(shù)中開始要分配一些資源,然后在中途執(zhí)行過程中如果遇到錯誤則退出函數(shù),當(dāng)然,退出前先釋放資源,我們的代碼可能是這樣:
version 1

復(fù)制代碼 代碼如下:

bool Execute()
{
   // 分配資源
   int *p = new int;
   bool bOk(true);

   // 執(zhí)行并進(jìn)行錯誤處理
   bOk = func1();
   if(!bOk)
   {
      delete p;  
      p = NULL;
      return false;
   }

   bOk = func2();
   if(!bOk)
   {
      delete p;  
      p = NULL;
      return false;
   }

   bOk = func3();
   if(!bOk)
   {
      delete p;  
      p = NULL;
      return false;
   }

   // ..........

   // 執(zhí)行成功,釋放資源并返回
    delete p;  
    p = NULL;
    return true;

}


這里一個(gè)最大的問題就是代碼的冗余,而且我每增加一個(gè)操作,就需要做相應(yīng)的錯誤處理,非常不靈活。于是我們想到了goto:
version 2
復(fù)制代碼 代碼如下:

bool Execute()
{
   // 分配資源
   int *p = new int;
   bool bOk(true);

   // 執(zhí)行并進(jìn)行錯誤處理
   bOk = func1();
   if(!bOk) goto errorhandle;

   bOk = func2();
   if(!bOk) goto errorhandle;

   bOk = func3();
   if(!bOk) goto errorhandle;

   // ..........

   // 執(zhí)行成功,釋放資源并返回
    delete p;  
    p = NULL;
    return true;

errorhandle:
    delete p;  
    p = NULL;
    return false;

}


代碼冗余是消除了,但是我們引入了C++中身份比較微妙的goto語句,雖然正確的使用goto可以大大提高程序的靈活性與簡潔性,但太靈活的東西往往是很危險(xiǎn)的,它會讓我們的程序捉摸不定,那么怎么才能避免使用goto語句,又能消除代碼冗余呢,請看do...while(0)循環(huán):
version3
復(fù)制代碼 代碼如下:

bool Execute()
{
   // 分配資源
   int *p = new int;

   bool bOk(true);
   do
   {
      // 執(zhí)行并進(jìn)行錯誤處理
      bOk = func1();
      if(!bOk) break;

      bOk = func2();
      if(!bOk) break;

      bOk = func3();
      if(!bOk) break;

      // ..........

   }while(0);

    // 釋放資源
    delete p;  
    p = NULL;
    return bOk;
}


2 宏定義中的do...while(0)
如果你是C++程序員,我有理由相信你用過,或者接觸過,至少聽說過MFC, 在MFC的afx.h文件里面, 你會發(fā)現(xiàn)很多宏定義都是用了do...while(0)或do...while(false), 比如說:
#define AFXASSUME(cond)      
do { bool __afx_condVal=!!(cond);
ASSERT(__afx_condVal);
__analysis_assume(__afx_condVal);} while(0)

粗看我們就會覺得很奇怪,既然循環(huán)里面只執(zhí)行了一次,我要這個(gè)看似多余的do...while(0)有什么意義呢?
當(dāng)然有!
為了看起來更清晰,這里用一個(gè)簡單點(diǎn)的宏來演示:
#define SAFE_DELETE(p) do{ delete p; p = NULL} while(0)
假設(shè)這里去掉do...while(0),
#define SAFE_DELETE(p) delete p; p = NULL;

那么以下代碼:
if(NULL != p) SAFE_DELETE(p)
else   ...do sth...

就有兩個(gè)問題,
1) 因?yàn)閕f分支后有兩個(gè)語句,else分支沒有對應(yīng)的if,編譯失敗

2) 假設(shè)沒有else, SAFE_DELETE中的第二個(gè)語句無論if測試是否通過,會永遠(yuǎn)執(zhí)行。
你可能發(fā)現(xiàn),為了避免這兩個(gè)問題,我不一定要用這個(gè)令人費(fèi)解的do...while,  我直接用{}括起來就可以了
#define SAFE_DELETE(p) { delete p; p = NULL;}
的確,這樣的話上面的問題是不存在了,但是我想對于C++程序員來講,在每個(gè)語句后面加分號是一種約定俗成的習(xí)慣,這樣的話,以下代碼:
if(NULL != p) SAFE_DELETE(p);
else   ...do sth...
其else分支就無法通過編譯了(原因同上),所以采用do...while(0)是做好的選擇了。

也許你會說,我們代碼的習(xí)慣是在每個(gè)判斷后面加上{}, 就不會有這種問題了,也就不需要do...while了,如:
if(...)
{
}
else
{
}
誠然,這是一個(gè)好的,應(yīng)該提倡的編程習(xí)慣,但一般這樣的宏都是作為library的一部分出現(xiàn)的,而對于一個(gè)library的作者,他所要做的就是讓其庫具有通用性,強(qiáng)壯性,因此他不能有任何對庫的使用者的假設(shè),如其編碼規(guī)范,技術(shù)水平等。

相關(guān)文章

  • 用pybind11封裝C++實(shí)現(xiàn)的函數(shù)庫的方法示例

    用pybind11封裝C++實(shí)現(xiàn)的函數(shù)庫的方法示例

    這篇文章主要介紹了用pybind11封裝C++實(shí)現(xiàn)的函數(shù)庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • C語言實(shí)現(xiàn)俄羅斯方塊源代碼

    C語言實(shí)現(xiàn)俄羅斯方塊源代碼

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)俄羅斯方塊的源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • C語言自定義軍旗游戲源碼

    C語言自定義軍旗游戲源碼

    這篇文章主要為大家詳細(xì)介紹了C語言自定義軍旗游戲源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++多線程編程時(shí)的數(shù)據(jù)保護(hù)

    C++多線程編程時(shí)的數(shù)據(jù)保護(hù)

    這篇文章主要介紹了C++多線程編程時(shí)的數(shù)據(jù)保護(hù),作者針對C++11版本中的新特性做出了一些解說,需要的朋友可以參考下
    2015-07-07
  • va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    這些宏定義在stdarg.h中,所以用到可變參數(shù)的程序應(yīng)該包含這個(gè)頭文件.下面我們寫一個(gè)簡單的可變參數(shù)的函數(shù),該函數(shù)至少有一個(gè)整數(shù)參數(shù),第二個(gè)參數(shù)也是整數(shù),是可選的.函數(shù)只是打印這兩個(gè)參數(shù)的值
    2013-09-09
  • C++操作.json文件的超詳細(xì)新手教程

    C++操作.json文件的超詳細(xì)新手教程

    最近因?yàn)轫?xiàng)目原因需要解析JSON格式數(shù)據(jù),所以這篇文章主要給大家介紹了關(guān)于C++操作.json文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • C語言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問題探究

    C語言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問題探究

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問題,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路
    2023-01-01
  • c++ 臨時(shí)對象的來源

    c++ 臨時(shí)對象的來源

    大家可能對這個(gè)臨時(shí)對象這個(gè)概念還不是很清楚,那么首先我們花一些時(shí)間來理解臨時(shí)對象
    2013-01-01
  • VC++ 6.0 C語言實(shí)現(xiàn)俄羅斯方塊詳細(xì)教程

    VC++ 6.0 C語言實(shí)現(xiàn)俄羅斯方塊詳細(xì)教程

    這篇文章主要為大家介紹了VC++ 6.0 C語言實(shí)現(xiàn)俄羅斯方塊詳細(xì)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 如何讓C++函數(shù)返回值死心塌地為你工作

    如何讓C++函數(shù)返回值死心塌地為你工作

    這篇文章主要介紹了如何讓C++函數(shù)返回值死心塌地為你工作,小編覺得還是挺不錯的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01

最新評論