阅读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之本质区别