Chinaunix首页 | 论坛 | 博客
  • 博客访问: 448643
  • 博文数量: 62
  • 博客积分: 1312
  • 博客等级: 中尉
  • 技术积分: 1555
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 18:10
文章分类

全部博文(62)

文章存档

2014年(1)

2013年(5)

2012年(56)

分类: C/C++

2012-10-08 19:34:21

以下文章是我读《高质量C++变成指南》的笔记。
 
第一章 文件结构
 
一、版权和版本信息
    版权和版本信息位于文件的开头。主要内容包括:
    (1)版权信息
    (2)文件名称、标示符、摘要
    (3)当前版本号、作者/修改者、完成日期
    (4)版本历史信息
图1.1、版权和版本声明
 
二、头文件的结构
    规则:
    (1)文件开头的版权和版本信息
    (2)预处理块
    (3)函数和类结构声明等
    建议:1.头文件中只出现声明不出现定义
          2.不建议使用全局变量。即使用extern int value;等。
 
三、定义文件的结构
    (1)文件开头的版权和版本信息
    (2)对一些头文件的引用
    (3)程序的实现,包括数据和代码
 
四、头文件的作用
    (1)调用库,源代码不便向用户公布,只需要提供头文件和二进制的库即可。
    (2)加强类型安全检查,接口被调用的时候如果方式与头文件中的声明不一致,编译器会指出错误。
 
五、目录结构
    如果程序中的头文件和实现文件比较多,则可以将头文件和实现文件分别放在不同的目录下面。例如:可以将全部的头文件都放在inc目录下面,将全部的实现文件存放在src目录下面。
    如果某些头文件的是私有的,不会被用户直接调用,没有必要公开“声明”。这些文件可以将头文件和定义存放在同一个目录中。
 
 
第二章 程序的版式
一、空行
    (1)在每个类声明之后、函数定义之后需要加上空行。如图2.1(a)
    (2)函数体内,逻辑上密切相关的语句之间不加空行,其它的地方应该加空行。如图2.1(b)
(a)                                          (b)
图2.1 空行
 
二、代码行
    规则:
    (1)一行代码只做一件事
    (2)if、for、while、do等语句自占一行,执行语句不得紧跟其后。后面必须加{},防止书写错误。
    建议:
    (1)定义变量的时候初始化变量(就近原则)
 
三、代码行内的空格
    规则:
    (1)关键字之后需要加空格
    (2)函数名之后不能留空格
    (3)‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。
    (4)‘,’之后要留空格,如果‘;’不是一行的结束符,其后应该留空格。
    (5)一般的二元操作符前后都应该留空格。
    (6)一般一元操作符前后都不加空格。
    (7)像“[]”、“.”、“->”这类操作符前后不加空格。
    建议:
    (1)当for、if表达式较长的时候可以适当去掉一些空格。
以上代码演示见图2.2
图2.2 代码内的空格
 
四、对齐
    规则:
    (1)程序的{}应该独占一行并且位于同一列,并且与其它的语句左对齐。
    (2){}内的代码在{右边数格(个人比较习惯四个空格的tab)处左对齐。
 
五、长行拆分
    规则:
    (1)一行代码的长度控制在70到80字符之内。代码行不应该过长,负责阅读不方便而且不便于打印。
    (2)长的表达式要在低优先级的操作符处拆分成新行,操作符放在新行之首。
 
六、修饰符的位置
    规则:
    (1)*、& 应该紧靠变量名。
    例如:char *name;  //而不是char* name;
 
七、注释
    规则:
    (1)注释不能太多,进而喧宾夺主。也不能太长,是的代码不知所云。
    (2)边写代码边写注释,修改代码的时候也要修改注释。保证代码和注释的一致性。
    (3)注释在代码的右边或者上边。不能放在代码的下边。
    (4)代码较长,或者嵌套比较多的时候要加一些注释在一些段落的结束处。
 
八、类的版式
    (1)一般以行为中心,public在前面prvate在后面。
    public体现了类提供的接口,体现了函数的功能。
    private体现的主要是类的内部数据结构。
 
 
第三章 命名规则
一、共性规则
    (1)变量、函数等由有意义的单词组成。可以望文知义。
    (2)命名规则应该尽量与操作系统或者开发工具保持一致。
    (3)程序中不能出现靠大小写就区分的相似的标识符。如:int x,X;
    (4)程序中不能出现标示符完全相同的局部变量和全局变量。尽管两者的作用域不同而不会发生语法错误,但是这会使人误解,不方便程序的阅读。
    (5)变量的名字应该使用名词或者形容词+名词。
         类的成员函数应该只使用动词。被省略掉的名词就是对象本身。
    (6)合理使用反义词。如:SetValue();GetValue()等。
 
二、Windows应用程序命名规则
    (1)类名必须以C开头。如:class CNode;
    (2)类的数据成员前面加“m_”,防止数据成员与函数成员混淆或者同名。

点击(此处)折叠或打开

  1. void Object::SetValue(int width,int height)
  2. {
  3.     m_width = width;
  4.     m_height = height;
  5. }
    (3)函数名使用大写字母开头的单词组合而成。如:void Draw(void);
    (4)变量和参数用小写字母开头的单词组合而成,而且后面的单词开头需要大写。如:int drawMode;
    (5)常量用全大写字母表示,用下划线分割单词。如:

点击(此处)折叠或打开

  1. const int MAX = 100;
  2. const int MAX_LENGTH = 100;
    (6)静态变量之前加“s_”如:

点击(此处)折叠或打开

  1. void Init(void)
  2. {
  3.     static int s_initValue;//静态变量
  4. }
    (7)全局变量尽量少用,如果必须要使用全局变量则在变量前面加“g_”。其中g 表示global。如:

点击(此处)折叠或打开

  1. int g_howManyPeiple; //全局变量
  2. int g_howMuchMoney; //全局变量
   
 
 第四章 表达式和基本语句
一、运算符的优先级
    (1)如果在一行代码中的优先级比较多,用括号确定表达式的操作顺序
 
二、复合表达式
    (1)不要太复杂的复合表达式。
    (2)不要有多重用途的复合表达式。例如:

点击(此处)折叠或打开

  1. d = (a = b + c) + r;
    说明:该表达式既求a值,又求d值。正确的做法是拆分成两个独立的语句:

点击(此处)折叠或打开

  1. a = b + c;
  2. d = a + r;
    (3)不要把程序中的表达式与“真正的数学表达式混淆”例如:

点击(此处)折叠或打开

  1. if(a < b < c)
  2. {
  3.     ... //dosomething
  4. }
    说明:上面的表达式并不表示if((a
三、if语句
    规则:
    (1)BOOL变量与零值比较时不能直接与1、0比较。应该如下表示:

点击(此处)折叠或打开

  1. bool flag;

  2. if(flag)
  3. {
  4.     //表示flag为真
  5. }

  6. if(!flag)
  7. {
  8.     //flag表示为假
  9. }
    (2)整型与零值比较时用 “==”和“!=”判断即可。
    (3)浮点变量与零值比较时应该考虑到精度限制,将“零值”放在一个范围之内。如:

点击(此处)折叠或打开

  1. if((x>=-EPSINON) && (x<=EPSINON))
    (4)指针与零值比较时应该将指针变量与NULL用“==”“!=”比较。
    建议:
    (1)指针或者变量与一个常量进行比较的时候将常量放在“==”、“!=”的前面。防止由于被赋值而造成持续逻辑的错误。
 
四、循环语句的效率
    建议:
    (1)在多重循环中将长循环放在循环的额内层,短循环放在循环的外层。以减少CPU跨切循环的次数。
    (2)如果循环体内有逻辑判断,而且循环的次数比较多的时候,可以将逻辑判断的部分放在循环外面,这样就不会打断循环的“流水线”作业。
 
五、for循环的循环控制变量
    规则:
    (1)不可以在循环体内部改变控制变量,防止循环失去控制。
    (2)循环控制变量的区间属于半开半闭区间,而不是全闭合区间。如:

点击(此处)折叠或打开

  1. for(int i=0;i<N;i++)
  2. {
  3.     DoSomething();
  4. }

 


第五章 常量
一、常量定义的时候建议使用const而非#define。
    使用const而非#define的原因:
    (1)const常量有数据类型,但是#define没有。使用const的话,可以在编译的过程中即对数据类型进行安全检查。
    (2)使用集成化的工具可以对const常量进行调试,但是不能对#define进行调试。
二、常量定义规则
    (1)需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的开头。可以把不同模块的常量集中放在一个头文件中。
    (2)如果某一常量与其它常量直接相关应该在定义的时候就体现出来。如:

点击(此处)折叠或打开

  1. const int RADIUS = 100;
  2. const int DIAMETER = RADIUS * 2;

 
第六章 函数
一、函数参数的规则:
    (1)无论是在定义还是在实现中,函数的参数都要写全。尤其是在声明的时候也要写全。如果没有参数,应该写void。
    (2)参数名称要有意义,参数的顺序按照目的参数在前面,源参数在后面的原则。
    (3)如果参数是指针,而且仅起到输入的作用。应该在类型的前面加上const。以防止指针在函数体内被修改。
    (4)如果输入参数以值传递的方式传递对象,则采用const &的方式传递,这样可以省去临时构造对象和析构对象的过程所消耗掉的时间。提高效率。
    (5)尽量不要使用参数个数不确定的参数,这样会使编译器在编译的时候丧失严重的类型安全检查。
 
二、返回值:
    规定
    (1)C++的函数除了void类型的,一定都要有返回值,而且函数不能省略返回值的类型。
    (2)函数的名字与返回值类型在语义上不可以冲突。
     说明:
    违反走这条规定的典型代表是getchar函数。如:

点击(此处)折叠或打开

  1. char c;
  2. c = getchar();
  3. if(EOF == c)
  4. {
  5.     DoSmoething...
  6. }
在这里的c不能理解为char类型的数据(它是int类型的),但是用户的感觉很有可能是返回char类型数据。
 
    建议:
    (1)适当增加返回值,如为了增加灵活性。如:

点击(此处)折叠或打开

  1. char str[20];
  2. int lenght = strlen(strcpy(str,"HelloBreak"))
    (2)有些时候使用返回应用汇提高程序的效率,但是有些时候使用却会带来严重的逻辑错误。
如:

点击(此处)折叠或打开

  1. String operate+(const String &s1,const &s2)
  2. {
  3.     String temp;
  4.     delete temp.data;
  5.     temp.data = new char[strlen(s1.data) + strlen(s2.data) + 1];
  6.     strcpy(temp.data,s1.data);
  7.     strcpy(temp.data,s2.data);
  8.     return temp;
  9. }
    对于相加函数一定要用值传递的方式返回,如果使用应用方式返回,由于temp在函数调用结束的时候已经自动销毁,将会导致应用无效。

 
 
 
 
 
 
 
阅读(4159) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~