天天看點

《高品質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】不可将布爾變量直接與true、false或者1、0進行比較。

根據布爾類型的語義,零值為“假”(記為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++中沒有内置大寫的bool,true,false關鍵字,這些關鍵字是vc的擴充,在windef.h檔案中我們找到如下的聲明

typedef int                 bool;

         #ifndef false

         #define false               0

         #endif

#ifndef true

         #define true                1

可見在vc下bool類型是int型的宏,而true,false分别代表0,1。通過下面的例子更能說明問題

         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定義為int,true定義為1,false定義為0時,會引發諸多問題,比較典型的集中情況如下

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

void fun(bool);

         void fun(int);

      此時bool是int型,編譯器并不認為上面兩個函數是重載,而認為是重複定義。

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++明确規定false為1,ture為2,那麼按照原來的寫法,所有的if語句都要修改,這種說法可能有些杞人憂天,至少說明,将來可能會出現這種情況。是以最好采用

        if (flag == false) 

這種方式。

繼續閱讀