对于不一样的编程语言来讲,具体的编码规范能够有很大的不一样,可是其宗旨都是一致的,就是保证代码在高质量完成需求的同时具有良好的可读性、可维护性。例如咱们能够规定某个项目的C语言程序要遵循这样的规定:变量的命名,头文件的书写和#include
等等。html
下面是一些广为采用的编码规范:java
GNU Coding Standards程序员
Guidelines for the Use of the C Language in Vehicle Based Software编程
C++ Coding Guidelines数组
SUN Code Conventions for Java多线程
如下是一些介绍编码、编码规范的书籍:编程语言
C++编码规范,陈世忠,人民邮电出版社,2002编辑器
高质量程序设计指南:C++/C语言,林锐等,电子工业出版社,2003ide
注:如下只是根据课题组已有的经验给出的总结,并不是对全部场景均适用。函数
对于高质量的工程,通常会作到:
代码简洁精炼,美观,可读性好,高效率,高复用,可移植性好,高内聚,低耦合,没有冗余,不符合这些原则,必须特别说明。
规范性,代码有规可循。特殊排版、特殊语法、特殊指令,必须特别说明。
1、文件排版方面
1.包含头文件
1.1 先系统头文件,后用户头文件。
1.2 系统头文件,稳定的目录结构,应采用包含子路径方式。
1.3 自定义头文件,不稳定目录结构,应在dsp中指定包含路径。
1.4 系统头文件应用:#include <xxx.h>
1.5 自定义同文件应用:#include "xxx.h"
1.6 只引用须要的头文件。
2.h和cpp文件
2.1 头文件命名为*.h
,内联文件命名为*.inl
;C++文件命名为*.cpp
2.2 文件名用大小写混合,或者小写混合。例如DiyMainview.cpp
,infoview.cpp
。不要用无心义的名称:例如XImage.cpp
;SView.cpp
;xlog.cpp
;
2.3 头文件除了特殊状况,应使用#ifdef
控制块。
2.4 头文件#endif
应采用行尾注释。
2.5 头文件,首先是包含代码块,其次是宏定义代码块,而后是全局变量,全局常量,类型定义,类定义,内联部分。
2.6 CPP文件,包含指令,宏定义,全局变量,函数定义。
3.文件结构
3.1 文件应包含文件头注释和内容。
3.2 函数体类体之间原则上用2个空行,特殊状况下可用一个或者不须要空行。
4.空行
4.1 文件头、控制块,#include
部分、宏定义部分、class
部分、全局常量部分、全局变量部分、函数和函数之间,用两个空行。
2、注释方面
1.文件头注释
1.1 做者,文件名称,文件说明,生成日期(可选)
2.函数注释
2.1 关键函数必须写上注释,说明函数的用途。
2.2 特别函数参数,须要说明参数的目的,由谁负责释放等等。
2.3 除了特别状况,注释写在代码以前,不要放到代码行以后。
2.4 对每一个#else
或#endif
给出行末注释。
2.5 关键代码注释,包括但不限于:赋值,函数调用,表达式,分支等等。
2.6 善未实现完整的代码,或者须要进一步优化的代码,应加上 // TODO ...
2.7 调试的代码,加上注释 // only for DEBUG
2.8 须要引发关注的代码,加上注释 // NOTE ...
2.9 对于较大的代码块结尾,如for,while,do
等,可加上 // end for|while|do
3、命名方面
1.原则
1.1 同一性:在编写一个子模块或派生类的时候,要遵循其基类或总体模块的命名风格,保持命名风格在整个模块中的同一性。
1.2 标识符组成:标识符采用英文单词或其组合,应当直观且能够拼读,可望文知意,用词应当准确,避免用拼音命名。
1.3 最小化长度 && 最大化信息量原则:在保持一个标识符意思明确的同时,应当尽可能缩短其长度。
1.4 避免过于类似:不要出现仅靠大小写区分的类似的标识符,例如"i"
与"I"
,"function"
与"Function"
等等。
1.5 避免在不一样级别的做用域中重名:程序中不要出现名字彻底相同的局部变量和全局变量,尽管二者的做用域不一样而不会发生语法错误,但容易令人误解。
1.6 正确命名具备互斥意义的标识符:用正确的反义词组命名具备互斥意义的标识符,如:"nMinValue"
和 "nMaxValue"
,"GetName()"
和"SetName()"
….
1.7 避免名字中出现数字编号:尽可能避免名字中出现数字编号,如Value1,Value2
等,除非逻辑上的确须要编号。这是为了防止程序员偷懒,不愿为命名动脑筋而致使产生无心义的名字(由于用数字编号最省事)。
2.T,C,M,R类
2.1 T类表示简单数据类型,不对资源拥有控制权,在析构过程当中没有释放资源动做。
2.2 C表示从CBase继承的类。该类不能从栈上定义变量,只能从堆上建立。
2.3 M表示接口类。
2.4 R是资源类,一般是系统固有类型。除了特殊状况,不该在开发代码中出现R类型。
3.函数名
3.1 M类的函数名称应采用HandleXXX
命名,例如:HandleTimerEvent
;不推荐采用java风格,例如 handleTimerEvent
;除了标准c风格代码,不推荐用下划线,例如,handle_event
。
3.2 Leave函数,用后缀L。
3.3 Leave函数,且进清除栈,用后缀LC。
3.4 Leave函数,且删除对象,用后缀LD。
4.函数参数
4.1 函数参数用a做为前缀。
4.2 避免出现和匈牙利混合的命名规则如apBuffer
名称。用aBuffer
便可。
4.3 函数参数比较多时,应考虑用结构代替。
4.4 若是不能避免函数参数比较多,应在排版上可考虑每一个参数占用一行,参数名竖向对齐。
5.成员变量
5.1 成员变量用m最为前缀。
5.2 避免出现和匈牙利混合的命名规则如mpBuffer
名称。用mBuffer
便可。
6.局部变量
6.1 循环变量和简单变量采用简单小写字符串便可。例如,int i
;
6.2 指针变量用p
打头,例如void* pBuffer;
7.全局变量
7.1 全局变量用g_
最为前缀。
8.类名
8.1 类和对象名应是名词。
8.2 实现行为的类成员函数名应是动词。
8.3 类的存取和查询成员函数名应是名词或形容词。
9.风格兼容性
9.1 对于移植的或者开源的代码,能够沿用原有风格,不用C++的命名规范。
4、代码风格方面
1.Tab和空格
1.1 每一行开始处的缩进只能用Tab,不能用空格,输入内容以后统一用空格。除了最开始的缩进控制用Tab,其余部分为了对齐,须要使用空格进行缩进。这样能够避免在不一样的编辑器下显示不对齐的状况。
1.2 在代码行的结尾部分不能出现多余的空格。
1.3 不要在"::","->","."
先后加空格。
1.4 不要在",",";"
以前加空格。
2.类型定义和{
2.1 类,结构,枚举,联合:大括号另起一行
3.函数
3.1 函数体的{须要新起一行,在{以前不能有缩进。
3.2 除了特别状况,函数体内不能出现两个空行。
3.3 除了特别状况,函数体内不能宏定义指令。
3.4 在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。
3.5 在头文件定义的inline
函数,函数之间能够不用空行,推荐用一个空行。
4.代码块
4.1 "if"、"for"、"while"、"do"、"try"、"catch"
等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加 "{ }"
。这样能够防止书写和修改代码时出现失误。
4.2 "if"、"for"、"while"、"do"、"try"、"catch"
的括号和表达式,括号可紧挨关键字,这样强调的是表达式。
5.else
5.1 if语句若是有else语句,用 } else { 编写为一行,不推荐用 3 行代码的方式。
6.代码行
6.1 一行代码只作一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,而且方便于写注释。
6.2 多行变量定义,为了追求代码排版美观,可将变量竖向对齐。
6.3 代码行最大长度宜控制在必定个字符之内,能在当前屏幕内所有可见为宜。
7.switch语句
7.1 case关键字应和switch对齐。
7.2 case子语句若是有变量,应用{}包含起来。
7.3 若是有并列的相似的简单case语句,可考虑将case代码块写为一行代码。
7.4 简单的case之间可不用空行,复杂的case之间应考虑用空行分割开。
7.5 case字语句的大括号另起一行,不要和case写到一行。
7.6 为全部switch语句提供default分支。
7.7 若某个case不须要break必定要加注释声明。
8.循环
8.1 空循环可用 for( ;; )
或者 while( 1 )
或者 while( true )
9.类
9.1 类继承应采用每一个基类占据一行的方式。
9.2 单继承可将基类放在类定义的同一行。若是用多行,则应用Tab缩进。
9.3 多继承在基类比较多的状况下,应将基类分行,并采用Tab缩进对齐。
9.4 重载基类虚函数,应在该组虚函数前写注释 // implement XXX
9.5 友元声明放到类的末尾。
10.宏
10.1 不要用分号结束宏定义。
10.2 函数宏的每一个参数都要括起来。
10.3 不带参数的宏函数也要定义成函数形式。
11.goto
11.1 尽可能不要用goto。
5、类型
*
和&
紧跟类型。typedef
简化程序中的复杂语法。typedef enum { EIdle, EActive } TState;
union
,若是必定要用,则采用简单数据类型成员。enum
取代(一组相关的)常量。6、表达式
if( p )
if( ! p )
7、函数
1.引用
1.1 引用类型做为返回值:函数必须返回一个存在的对象。
1.2 引用类型做为参数:调用者必须传递一个存在的对象。
2.常量成员函数
2.1 表示该函数只读取对象的内容,不会对对象进行修改。
3.返回值
3.1 除开void
函数,构造函数,析构函数,其它函数必需要有返回值。
3.2 当函数返回引用或指针时,用文字描述其有效期。
4.内联函数
4.1 内联函数应将函数体放到类体外。
4.2 只有简单的函数才有必要设计为内联函数,复杂业务逻辑的函数不要这么作。
4.3 虚函数不要设计为内联函数。
5.函数参数
5.1 只读取该参数的内容,不对其内容作修改,用常量引用。
5.2 修改参数内容,或须要经过参数返回,用很是量应用。
5.3 简单数据类型用传值方式。
5.4 复杂数据类型用引用或指针方式。
8、类
1.构造函数
1.1 构造函数的初始化列表,应和类的顺序一致。
1.2 初始化列表中的每一个项,应独占一行。
1.3 避免出现用一个成员初始化另外一个成员。
1.4 构造函数应初始化全部成员,尤为是指针。
1.5 不要在构造函数和析构函数中抛出异常。
2.纯虚函数
2.1 M类的虚函数应设计为纯虚函数。
3.构造和析构函数
3.1 若是类能够继承,则应将类析构函数设计为虚函数。
3.2 若是类不容许继承,则应将类析构函数设计为非虚函数。
3.3 若是类不能被复制,则应将拷贝构造函数和赋值运算符设计为私有的。
3.4 若是为类设计了构造函数,则应有析构函数。
4.成员变量
4.1 尽可能避免使用mutable
和Volatile
。
4.2 尽可能避免使用公有成员变量。
5.成员函数
5.1 努力使类的接口少而完备。
5.2 尽可能使用常成员函数代替很是成员函数,const
函数
5.3 除非特别理由,毫不要从新定义(继承来的)非虚函数。(这样是覆盖,基类的某些属性无初始化)
6.继承
6.1 继承必须知足IS-A的关系,HAS-A应采用包含。
6.2 虚函数不要采用默认参数。
6.3 除非特别须要,应避免设计大而全的虚函数,虚函数功能要单一。
6.4 除非特别须要,避免将基类强制转换成派生类。
7.友元
7.1 尽可能避免使用友元函数和友元类。
9、错误处理
new
操做符。delete
操做符。new
和delete
,new[]
和delete[]
成对使用。do-while(0)
宏:目的是将一组语句变成一个语句,避免被其余if等中断。10、性能
#include
指令。Class M;
++i
代替i++
。即用前缀代替后缀运算。for
循环以前,先写计算估值表达式。11、兼容性
#include
的文件名视为大小写敏感。来源:51CTO