使用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)
这种方式。