首页 > 代码库 > 改善C++程序的建议:语法篇1

改善C++程序的建议:语法篇1

参考自李健的《编写高质量代码--改善C++程序的150个建议》


建议0 不要让main函数返回void

      操作系统将main作为程序入口,main函数执行程序代码,最后返回程序的退出状态。但是C++中有一个好坏难定的规定:

      在main函数中,return语句用于离开main函数(析构掉所有的具有动态生存时间的对象),并将其返回值作为参数来调用exit函数。如果函数执行到结尾而没有遇到return语        句,其效果等同于执行了return 0;。

      也就是说编译器会协助完成返回值的问题。

      然而,这样的坏处就是,当编译器不支持这个规定的时候,程序就会出错,比如

      int main()

      {

      }

      在VC下编译是成功的,在g++下编译,就会提示错误:‘main’必须返回’int‘



建议1 区分0的4个面孔

      1 整型0

      2 空指针NULL

      3 字符串结束标记‘\0‘

‘            \0‘是一个字符,占8位,其二进制位表示是 00000000,在C/C++中,‘\0‘作为字符串的结束标记,是唯一的结束标记

      4 逻辑FALSE/false

            false/true是标准C++语言里新增的关键字,而FALSE/TRUE是通过#define定义的宏:

            #ifndef FALSE

            #define FALSE 0

            #endif

            #ifndef TRUE

            #defineTRUE 1

            #endif

            也就是说FALSE/TRUE是int类型,而false/true是bool型,两者是不一样的,bool在C++里是占用1个字节


建议2 避免那些有运算符引起的混乱


         =和==  :在if语句中 比较两个表达式是否相等,

            if( nValue =http://www.mamicode.com/= 0)

            {  ...  }

        如果程序员出现疲劳或精神不集中,把’==‘写成’=‘,这样if(nValue = http://www.mamicode.com/0),那么这个if条件是恒成立,并且nValue被赋值为0,并且不会提示错误

       这恐怕不是程序员想要的。。。

       但如果把常量写在前面,如if(0 == nValue){  },这样如果程序员写成if(0 = nValue){  },编译器会直接的提示错误

       但是对于&和&& 、|和|| 这类运算符,就需要平时养成谨慎的习惯了。



建议3 对表达式计算顺序不要向当然

      让我们来看一个例子

      if(nGrade & MASK == GRAND_ONE)

      {...}

      我们的本意是,通过nGrade和MASK取与,然后在比较是否等于GRAND_ONE,

      可是,实际上上面的代码的真实效果是if( nGrade & (MASK == GRAND_ONE)){}

      这个建议的核心是,不要吝啬括号,让语义表达的更准确,这样可以减少出错

      如: a = p() + q() * r();

      三个函数p() 、q() 、r()的执行顺序可能是6种组合中的一个,所以a的值是不确定的,在这种情况下,就需要明确一种执行顺序,

             int x=p();

            int y = q();

            a = x+y*r();


            类似的: expr1 ? expr2 : expr3

建议4 小心宏#define使用中的陷阱

      定义宏时,要使用完备的括号:

      比如定义两个参数相加, #define ADD(a,b) ((a)+(b))是一个安全的方式

      使用宏时,不允许参数发生变化,

      定义宏时,用大括号将宏所定义的多条表达式括起来

建议5 不要忘记指针变量的初始化

      局部变量的指针未初始化,可能导致程序崩溃

      全局变量的指针,编译器会悄悄完成变量的初始化(0)。


建议6 明晰逗号分隔表达式的奇怪之处

      逗号表达式是从C继承来的,其中每个表达式都会被执行,不过,整个表达式的值仅是最右边表达式的结果

      如:if(++x,--y,x<20 && y >0),该语句返回的是“ x<20 && y>0”与0比较的结果

      另外,逗号表达式既可以用作左值,也可以用作右值。


建议7 时刻提防内存溢出

      C语言中的字符串库没有响应的安全保护措施,strcpy、strcat等函数操作时没有检查缓冲区大小,容易引起安全问题

      好的方法是,定义一个函数,并传递确定的长度,如:

      const int DATA_LENGTH = 16;

      void DataCopy(char* src ,int len)

      {

      char dst[DATA_LENGTH];

      for(int i=0;src[i] != 0 && i<DATA_LENGTH; i++)

            cout<<src[i]<<endl;

      if(len < DATA_LENGTH)

            strcpy(dst,src);

      }

      这里如果,src的长度是10,当i=10时,src[10]就已经越界了。。。



建议8 拒绝晦涩难懂的函数指针

      比如 void (*p[10])  (void  (*)() );

      1 声明一个无参数、返回空的函数指针的typedef,如:typedef void (*pfv)();

      2 声明一个指向参数为pfv且返回空的函数指针, 如 : typedef  void (*pFun_taking_pfv) (pfv));

      3 定义数组,pFun_taking_pfv p[10];


建议9 防止头文件重发包含

      方式一:

            #ifndef __TEST_H__

            #define __TEST_H__

            ......

            #endif

      方式二:

            #pragma once

      优缺点:方式一的缺点是宏导致的编译时间长

            方式二的缺点是只是针对物理路径相同的文件,而不是文件的内容



改善C++程序的建议:语法篇1