閱讀689 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《高質量C++C編程指南》糾錯與拾遺(一)

使用C++/C編程的程序員,幾乎都看過林銳博士寫的《高質量C++C編程指南》這篇百頁經書,並且通過閱讀這篇百頁經書,受益匪淺。我也是這篇文章的受益者。通過這篇百頁經書,我學到很多知識,也給於了我深入學習C++的動力。

最近,偶得機會,再次拜讀林銳博士的《高質量C++C編程指南》,發現裏麵有些觀點頗有爭議,本文作者對這些觀點進行的了考證,整理,匯總,形成了此文檔,這裏絕無批駁,貶低《高質量C++C編程指南》之意,其目的有二,一:闡述本文作者對《高質量C++C編程指南》的一些觀點,如果這些觀點能夠對讀者學習C++起到的啟迪作用,作者就萬分歡喜了,2:見證作者的C++學習之路。如果您在閱讀此文時,發現任何問題,包括文字,符號,觀點,用例,歡迎您和我交流,我將及時更正,謝謝。

所謂糾錯:是本文作者對林銳博士的《高質量C++C編程指南》中有爭議的技術,觀點做進一步的考證和整理。
    所謂拾遺:是本文作者對林銳博士的《高質量
C++C編程指南》中點到為止的技術,觀點,做一些簡短的補充和解釋。
       林銳博士的《高質量C++C編程指南》是一本很好的編程規範手冊,在具體項目中,具體環境中這些規範並不一定是最好的,但是已經足夠好,所以我不想找這些規範的錯誤,不想對這些規範作更多的解釋。本文的重點將放在對技術的討論上,此乃一家之言,切勿較真。      

1:盡量使用小寫的bool類型

關於BOOL類型的if判斷在林銳博士的《高質量C++C編程指南》的4.3.1 布爾變量與零值比較如下說明

【規則4-3-1不可將布爾變量直接與TRUEFALSE或者10進行比較。

根據布爾類型的語義,零值為“假”(記為FALSE),任何非零值都是“真”(記為TRUE)。TRUE的值究竟是什麼並沒有統一的標準。例如Visual C++ TRUE定義為1,而Visual Basic則將TRUE定義為-1

假設布爾變量名字為flag,它與零值比較的標準if語句如下:

if (flag)   // 表示flag為真
     if (!flag)  //
表示flag為假

其它的用法都屬於不良風格,例如:

    if (flag == TRUE)
        
if (flag == 1 )
   
     if (flag == FALSE) 


在這裏首先說明的一點是,在標準C/C++中沒有內置大寫的BOOLTRUEFALSE關鍵字,這些關鍵字是VC的擴展,在windef.h文件中我們找到如下的聲明

typedef int                 BOOL;
         #ifndef FALSE
         #define FALSE               0
         #endif


#ifndef TRUE
         #define TRUE                1
         #endif

可見在VCBOOL類型是int型的宏,而TRUEFALSE分別代表01。通過下麵的例子更能說明問題
         cout << "sizeof(BOOL): "<<sizeof(BOOL) << endl; // 值為4
         cout << "sizeof(TRUE): "<<sizeof(TRUE) << endl; //
值為4
         cout << "sizeof(FALSE): "<<sizeof(FALSE) << endl; //
值為4

林銳博士博士在文章中提到“TRUE的值究竟是什麼並沒有統一的標準,Visual C++ TRUE定義為1,而Visual Basic則將TRUE定義為-1其實我認為在此舉例並不能很好說明問題,因為Visual Basic是並沒有采用C/C++編程語言,所以無法例證TRUE的聲明。當把BOOL定義為intTRUE定義為1FALSE定義為0時,會引發諸多問題,比較典型的集中情況如下

1:不會存在如下類型的函數重載

void fun(BOOL);
         void fun(int);
     
此時BOOLint型,編譯器並不認為上麵兩個函數是重載,而認為是重複定義。
2
:當定義void fun(int)函數時,出現以下情況編譯器都將按int型處理
        int i = 5;
        int j = 3;
        BOOL bState = FALSE;
        fun(i<j);
        fun(bState);

       3++--問題

       這種問題更為隱秘,當我們定義BOOL state(TRUE);如果程序代碼很長,並且複雜,那麼我們無意中執行了—state操作,編譯器不會提示任何錯誤,並且我們的if判斷也不會出現任何判斷問題。這條隱藏的bug將是非常難找的。

       標準C/C++的中內置的關鍵字是小寫的bool,true,false,如果我們采用bool類型可以很好避免如上提到的問題。所以,在平時編程時盡量使用bool類型而不是BOOL類型。

       有的平台上是如下定義BOOL類型的
       enum BOOL {FALSE=0,TRUE};采用這種方法,解決問題並不徹底。讀者可以根據上麵例子,判斷這種方式的優缺點。

       關於bool類型在if語句中的判斷,如果我們在編寫一個跨平台,並且不想受C++語言的發展對程序代碼的影響,在if判斷時最好采用

        if (flag == false)
    
if (flag == true)  

方式。因為C++沒有規定true的值為什麼,同樣也就沒有規定false的值為什麼,隻是編譯器一般的做法是把false定義為0(這裏的0並不是int中的0,它可能是二進製0,也可以能是一個字節中的0),而把非false的值,定義為true,如果將來C++明確規定false1ture2,那麼按照原來的寫法,所有的if語句都要修改,這種說法可能有些杞人憂天,至少說明,將來可能會出現這種情況。所以最好采用

        if (flag == false) 
    
if (flag == true)  


這種方式。

 

最後更新:2017-04-02 00:06:17

  上一篇:go [原創]對《科學家別出心裁用數學計算證明不存在吸血鬼》的質疑!
  下一篇:go 關於Debug和Release之本質區別