第一章 文件结构
一、版权和版本信息
版权和版本信息位于文件的开头。主要内容包括:
(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_”,防止数据成员与函数成员混淆或者同名。
- void Object::SetValue(int width,int height)
- {
- m_width = width;
- m_height = height;
- }
(3)函数名使用大写字母开头的单词组合而成。如:void Draw(void);
(4)变量和参数用小写字母开头的单词组合而成,而且后面的单词开头需要大写。如:int drawMode;
(5)常量用全大写字母表示,用下划线分割单词。如:
- const int MAX = 100;
- const int MAX_LENGTH = 100;
(6)静态变量之前加“s_”如:
- void Init(void)
- {
- static int s_initValue;//静态变量
- }
(7)全局变量尽量少用,如果必须要使用全局变量则在变量前面加“g_”。其中g 表示global。如:
- int g_howManyPeiple; //全局变量
- int g_howMuchMoney; //全局变量
第四章 表达式和基本语句
一、运算符的优先级
(1)如果在一行代码中的优先级比较多,用括号确定表达式的操作顺序
二、复合表达式
(1)不要太复杂的复合表达式。
(2)不要有多重用途的复合表达式。例如:
说明:该表达式既求a值,又求d值。正确的做法是拆分成两个独立的语句:
(3)不要把程序中的表达式与“真正的数学表达式混淆”例如:
- if(a < b < c)
- {
- ... //dosomething
- }
说明:上面的表达式并不表示if((a
三、if语句
规则:
(1)BOOL变量与零值比较时不能直接与1、0比较。应该如下表示:
- bool flag;
- if(flag)
- {
- //表示flag为真
- }
- if(!flag)
- {
- //flag表示为假
- }
(2)整型与零值比较时用 “==”和“!=”判断即可。
(3)浮点变量与零值比较时应该考虑到精度限制,将“零值”放在一个范围之内。如:
- if((x>=-EPSINON) && (x<=EPSINON))
(4)指针与零值比较时应该将指针变量与NULL用“==”“!=”比较。
建议:
(1)指针或者变量与一个常量进行比较的时候将常量放在“==”、“!=”的前面。防止由于被赋值而造成持续逻辑的错误。
四、循环语句的效率
建议:
(1)在多重循环中将长循环放在循环的额内层,短循环放在循环的外层。以减少CPU跨切循环的次数。
(2)如果循环体内有逻辑判断,而且循环的次数比较多的时候,可以将逻辑判断的部分放在循环外面,这样就不会打断循环的“流水线”作业。
五、for循环的循环控制变量
规则:
(1)不可以在循环体内部改变控制变量,防止循环失去控制。
(2)循环控制变量的区间属于半开半闭区间,而不是全闭合区间。如:
- for(int i=0;i<N;i++)
- {
- DoSomething();
- }
第五章 常量
一、常量定义的时候建议使用const而非#define。
使用const而非#define的原因:
(1)const常量有数据类型,但是#define没有。使用const的话,可以在编译的过程中即对数据类型进行安全检查。
(2)使用集成化的工具可以对const常量进行调试,但是不能对#define进行调试。
二、常量定义规则
(1)需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的开头。可以把不同模块的常量集中放在一个头文件中。
(2)如果某一常量与其它常量直接相关应该在定义的时候就体现出来。如:
- const int RADIUS = 100;
- const int DIAMETER = RADIUS * 2;
第六章 函数
一、函数参数的规则:
(1)无论是在定义还是在实现中,函数的参数都要写全。尤其是在声明的时候也要写全。如果没有参数,应该写void。
(2)参数名称要有意义,参数的顺序按照目的参数在前面,源参数在后面的原则。
(3)如果参数是指针,而且仅起到输入的作用。应该在类型的前面加上const。以防止指针在函数体内被修改。
(4)如果输入参数以值传递的方式传递对象,则采用const &的方式传递,这样可以省去临时构造对象和析构对象的过程所消耗掉的时间。提高效率。
(5)尽量不要使用参数个数不确定的参数,这样会使编译器在编译的时候丧失严重的类型安全检查。
二、返回值:
规定
(1)C++的函数除了void类型的,一定都要有返回值,而且函数不能省略返回值的类型。
(2)函数的名字与返回值类型在语义上不可以冲突。
说明:
违反走这条规定的典型代表是getchar函数。如:
- char c;
- c = getchar();
- if(EOF == c)
- {
- DoSmoething...
- }
在这里的c不能理解为char类型的数据(它是int类型的),但是用户的感觉很有可能是返回char类型数据。
建议:
(1)适当增加返回值,如为了增加灵活性。如:
- char str[20];
- int lenght = strlen(strcpy(str,"HelloBreak"))
(2)有些时候使用返回应用汇提高程序的效率,但是有些时候使用却会带来严重的逻辑错误。
如:
- String operate+(const String &s1,const &s2)
- {
- String temp;
- delete temp.data;
- temp.data = new char[strlen(s1.data) + strlen(s2.data) + 1];
- strcpy(temp.data,s1.data);
- strcpy(temp.data,s2.data);
- return temp;
- }
对于相加函数一定要用值传递的方式返回,如果使用应用方式返回,由于temp在函数调用结束的时候已经自动销毁,将会导致应用无效。