《高質量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
#endif
可見在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)
if (flag == true)
這種方式。
最後更新:2017-04-02 00:06:17