程序员必不可少,学习计算机语言设计不得不知道的一些规范
C/C++语言编码规范
上海涌能能源科技发展有限公司
程序员必不可少,学习计算机语言设计不得不知道的一些规范
文档修订记录
文档审批信息
程序员必不可少,学习计算机语言设计不得不知道的一些规范
目 录
1. 目的.......................................................................................................................................................... 4 2. 适用范围 .................................................................................................................................................. 4 3. 定义.......................................................................................................................................................... 4 4. 职责.......................................................................................................................................................... 4 5. 流程图...................................................................................................................................................... 5 6. 内容和要求 .............................................................................................................................................. 5
6.1 基本原则 ........................................................................................................................................ 5 6.2 布局 ................................................................................................................................................ 6
6.2.1 文件布局 ............................................................................................................................. 6 6.2.2 基本格式 ...........................................................................................................................10 6.2.3 对齐...................................................................................................................................11 6.2.4 空行空格 ...........................................................................................................................13 6.2.5 断行...................................................................................................................................15 6.2.6 预处理指令 .......................................................................................................................16 6.3 注释 .............................................................................................................................................. 16 6.4 命名规则 ...................................................................................................................................... 21 6.5 变量、常量、宏与类型 .............................................................................................................. 26
6.5.1 变量与常量 ....................................................................................................................... 26 6.5.2 宏.......................................................................................................................................29 6.5.3 类型...................................................................................................................................30 6.6 表达式与语句 .............................................................................................................................. 33 6.7 函数与过程 .................................................................................................................................. 38
6.7.1 参数...................................................................................................................................38 6.7.2 返回值...............................................................................................................................39 6.7.3 内部实现 ...........................................................................................................................40 6.7.4 函数调用 ...........................................................................................................................42 6.8 可靠性 .......................................................................................................................................... 43
6.8.1 内存使用 ...........................................................................................................................43 6.8.2 指针使用 ...........................................................................................................................45 6.8.3 类和函数 ...........................................................................................................................46 6.9 可测试性 ...................................................................................................................................... 48 6.10 断言与错误处理 ........................................................................................................................ 49 7. 相关文件 ................................................................................................................................................ 51 8. 记录表单 ................................................................................................................................................ 51
程序员必不可少,学习计算机语言设计不得不知道的一些规范
1
1. 目的
1.1 编写本标准的目的是为了统一公司软件编程风格,提高软件源程序的可读性、可靠性和可重用性,提高软件源程序的质量和可维护性,减少软件维护成本,最终提高软件产品生产力。
1.2 本规范是针对C、C++语言的编程规范,其它不同编程语言可以参照此规范执行。本规范适用于公司所有产品的软件源程序,同时考虑到不同产品和项目的实际开发特性,本规范分成规则性和建议性两种:对于规则性规范,要求所有软件开发人员严格执行;对于建议性规范,各项目编程人员可以根据实际情况选择执行。本规范的示例都以C++语言描述。
1.3 本规范的内容包括:基本原则、布局、注释、命名规则、变量常量与类型、表达式与语句、函数与过程、可靠性、可测性、断言与错误处理等。
2
2. 适用范围
2.1 本标准规定了C++语言的编程规范,而不是编程的技巧。
2.2 本标准适用于公司内使用C++语言编码的所有软件。本规范自生效之日起,对以后新编写的和修改的代码有约束力。
3 3. 定义
下列术语和定义适用于本标准:
3.1 原则:编程时应该坚持的指导思想。 3.2 规则:编程时必须遵守的约定。 3.3 建议:编程时必须加以考虑的约定。 3.4 说明:对此规则或建议的必要的解释。 3.5 正例:对此规则或建议给出的正确例子。 3.6 反例:对此规则或建议给出的反面例子。
4
4. 职责
4.1 主任设计师负责此文件的制定和完善。
程序员必不可少,学习计算机语言设计不得不知道的一些规范
4.2 他设计师依照此文件执行C++语言编码。
5
无
5. 流程图
6
6. 内容和要求
6.1 基本原则
6.1.1 编写程序是为人阅读,其次才是计算机。
说明:该原则是软件开发的基本要点,软件生命周期贯穿于产品的开发、测试、生产、用户使用、版本升级和后期维护等长期过程,只有易读、易维护的软件代码才具有生命力。
6.1.2 保持代码的简明清晰,避免过分或刻意的追求编程技巧。
说明:简单是最美。保持代码的简单化是软件工程化的基本要求。不要过分追求技巧,否则会降低程序的可读性。
6.1.3 所有的代码尽量遵循ANSI 标准。
说明:所有的代码尽可能遵循ANSI 标准,尽可能不使用ANSI未定义的或编译器扩展的功能。
6.1.4 编程时首先以达到正确性为目的,其次再考虑效率。
说明:编程首先考虑的是满足正确性、健壮性、可维护性、可移植性等质量因素,最后才考虑程序的效率和资源占用。
6.1.5 避免或少用全局变量。
说明:过多地使用全局变量,会导致模块间的紧耦合,违反模块化的要求。
6.1.6 尽可能重用代码。
说明:尽量选择可借用的代码,对其修改、优化以达到自身使用要求。
6.1.7 团队合作。
说明:编程规范的使用要点在于提供一个开发团队共同遵守的样本,没有所谓对和错。团队所有成员可以把精力集中在实现内容而不是表现形式上。本文给
程序员必不可少,学习计算机语言设计不得不知道的一些规范
出了主要的风格规范,但个人的风格也很重要,如果你在一个文件中新加的代码和原有代码风格相去甚远的话,这就破坏了文件本身的整体美观也影响阅读,所以要尽量避免。
6.2 布局
程序布局的目的是展现程序良好的逻辑结构,以提高程序的准确性、连续性、可读性、可维护性。更重要的是,统一的程序布局和编程风格,有助于提高整个项目的开发质量,提高开发效率,降低开发成本。同时,对于程序员来说,养成良好的编程习惯有助于提高自己的编程水平,提高编程效率。
6.2.1 文件布局
【规则2-1-1】遵循统一的布局顺序来书写头文件
说明:以下内容如果某些节不需要,可以忽略。但是其它节要保持该次序。 头文件布局:
a) 文件头注释(参见 “注释”章节)
b) #ifndef 文件名_H(全大写)(用来避免重复包含)
#define 文件名_H c) 其它条件编译选项
d) #include(依次为标准库头文件、非标准库头文件) e) 与C++编译器适应extern “C”声明前缀 f) 全局宏 g) 常量定义 h) 全局数据类型 i) 类/结构的声明
j) 模板(template)(包括C++中的类模板和函数模板) k) 输出函数部分
l) 与C++编译器适应extern “C”声明前缀结束; m) 需要包含的内联函数定义文件
程序员必不可少,学习计算机语言设计不得不知道的一些规范
#endif
【规则2-1-2】遵循统一的布局顺序来书写实现文件
说明:一个定义文件实现一组功能相关的函数接口和子函数接口,不能同时实现不同头文件声明的函数接口,它主要包含如下几个部分:(规范不强求具体文件涵盖下面所有内容,对存在的内容则应按照以下顺序排放;和头文件相同的项目,要求同头文件构成部分相同)。
实现文件布局:
a) 文件头注释(参见 “注释”章节)
b) #include(依次为标准库头文件、非标准库头文件)将仅与实现相关的
类、函数及数据的头文件包含在实现文件里(而不是头文件中)是一个非常好的编程习惯。这样可以有效地屏蔽不应该暴露的实现细节,将实现改变对其它模块的影响降低到最少 。 c) 文件内部使用的宏 d) 常量定义
e) 文件内部使用的数据类型
f) 外部可以使用的全局数据定义部分 g) 本地变量(即静态全局变量)
h) 局部函数原型(文件范围内的函数原型声明) i) 类的实现 j) 全局函数 k) 局部函数
l) 实现文件的编码规则:
分割每个部分:在本地(静态)定义和外部定义间,以及不同接口或不同类的实现之间,应使用注释块(注释块见下面解释)相互分开。
【规则2-1-3】使用注释块分离上面定义的节 正例:
/
*********************************************************** * 数据类型定义 *
*********************************************************** /
typedef unsigned char BOOLEAN;
程序员必不可少,学习计算机语言设计不得不知道的一些规范
/*************************************************************
* 函数原型 *
************************************************************/
int HelloWorld(void);
【规则2-1-4】包含标准库头文件用尖括号 < >,包含非标准库头文件用双引号 “ ” 正例:
#include <stdio.h> #include “MMS.h”
【规则2-1-5】遵循统一的风格书写类(class)的定义及实现 说明:类定义文件中类容按如下顺序书写:
a) 注释头与类声明: 与文件一样,每个类应当有一个注释头用来说明该类
的各个方面。类声明换行紧跟在注释头后面,"class" 关键字由行首开始书写,后跟类名称。界定符 "{" 和 "};" 应独占一行,并与 "class" 关键字左对其。
b) 继承: 基类直接跟在类名称之后,不换行,访问说明符(public, private,
或protected)不可省略。如:
class CXXX : public CAAA, private CBBB {
// ... };
c) 初始化列表:应当尽可能通过构造函数的初始化列表来初始化成员和基
程序员必不可少,学习计算机语言设计不得不知道的一些规范
类。初始化列表至少独占一行,并且与构造函数的定义保持4 个空格的缩进。如:
CXXX::CXXXX(IN int nA, IN bool bB)
: m_nA(nA), m_bB(bB) {
// ... };
初始化列表的书写顺序应当与对象的构造顺序一致,即:先按照声明顺序写基类初始化,再按照声明顺序写成员初始化。
d) 嵌套的类声明:在相应的逻辑关系确实存在时,类声明可以嵌套。嵌套
类可以使用简单的单行注释头。 e) 公有属性 f) 公有函数 g) 保护属性 h) 保护函数 i) 私有属性 j) 私有函数
访问说明符(public, private, 或protected)应该独占一行,并与类声明中的‘class’关键字左对齐。 k) 类实现文件内容按如下顺序书写:
构造函数 析构函数 公有函数 保护函数 私有函数
【规则2-1-6】内联函数定义文件
在内联函数较多的情况下,为了避免头文件过长、版面混乱,可以将所有的内联函数定义移到一个单独的文件中去,然后再用#include指令将它包含到类声明的后面。这样的文件称为一个内联函数定义文件。
按照惯例,应该将这个文件命名为“filename.inl”,其中“filename”与
程序员必不可少,学习计算机语言设计不得不知道的一些规范
相应的头文件和实现文件相同。
内联函数定义文件由以下几部分组成:
文件头注释:每内联函数定义文件都应该由一个规范的文件头注释作为开始 内联函数定义:内联函数的实现体
6.2.2 基本格式
【规则2-2-1】程序中一行的代码和注释不能超过80列
说明:包括空格在内不超过80 列。
【规则2-2-2】if、else、else if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加 { }。
说明:这样易于阅读,也容易检查错误。 正例:
if (varible1 < varible2) {
varible1 = varible2; }
反例:下面的代码中执行语句紧跟在if条件之后,而且没有加{},违反规则。
if (varible1 < varible2) varible1 = varible2;
【规则2-2-3】定义指针类型的变量,*应放在变量前
正例:
float *pfBuffer;
反例:
float* pfBuffer;
〖建议2-2-1〗源程序中变量、函数等逻辑关系较为紧密的代码应尽可能相邻
说明:这样便于程序阅读和查找。 正例:
iLength iWidth
= 20;
= 8; // 矩形的长与宽关系较密切,放在一起。
StrCaption = “Rectangle”;
反例:
iLength = 20;
程序员必不可少,学习计算机语言设计不得不知道的一些规范
strCaption = “Rectangle”; iWidth = 8;
6.2.3 对齐
【规则2-3-1】 统一使用TAB键,不使用空格进行缩进,设置Tab健为4个空格。
【规则2-3-2】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。{ }之内的代码块使用缩进规则对齐。
说明:这样使代码便于阅读,并且方便注释。
do while语句和结构的类型化时可以例外,while条件和结构名可与 } 在同一行。 正例:
void Function(int iVar) {
while (condition) {
DoSomething(); // 与{ }缩进4 格 } }
// 独占一行并与引用语句左对齐。
反例:
void Function(int iVar){
while (condition){
DoSomething(); }}
【规则2-3-3】声明类的时候,public、protected、private关键字与分界符{} 对齐,这些部分的内容要进行缩进。
正例:
class CFood {
public:
// 与 { 对齐 // 要进行缩进
CFood (void); ~ CFood(void);
程序员必不可少,学习计算机语言设计不得不知道的一些规范
int GetCount(void);
void SetCount(int iCount); private:
int m_iCount; }
【规则2-3-4】结构型的数组、多维的数组如果在定义时初始化,按照数组的矩阵结构分行书写。
正例:
int aiNumbers[4][3] = {
1, 1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64 };
【规则2-3-5】相关的赋值语句等号对齐。
正例:
tPDBRes.wHead tPDBRes.wTail tPDBRes.wFree
= 0;
= wMaxNumOfPDB - 1; = wMaxNumOfPDB;
tPDBRes.wAddress = wPDBAddr; tPDBRes.wSize
= wPDBSize;
〖建议2-3-1〗在switch语句中,每一个case分支和default要用{ }括起来,{ }中的内容需要缩进。
说明:使程序可读性更好。 正例:
switch (iCode) {
case 1: {
DoSomething(); break; }
// 缩进4 格
程序员必不可少,学习计算机语言设计不得不知道的一些规范
case 2: { 起来
DoOtherThing(); break; } …
// 其它case 分支
// 每一个case 分支和default 要用{}括
default: {
DoNothing(); break; } }
6.2.4 空行空格
【规则2-4-1】不同逻辑程序块之间要使用空行分隔。
说明:空行起着分隔程序段落的作用,适当的空行可以使程序的布局更加清晰。
正例:
void AirPlane::Seat(void) {
[Seat 实现代码] }
// 空一行
void AirPlane::Schedule(void) {
[Schedule实现代码] }
反例:
void AirPlane:: Seat (void) {
程序员必不可少,学习计算机语言设计不得不知道的一些规范
[Seat 实现代码] }
void AirPlane:: Schedule (void) {
[Schedule 实现代码] }
【规则2-4-2】一元操作符如“!”、“~”、“++” 、“--”、“*”、“&”(地址运算符)等前后不加空格。“[]”、“.”、“->”这类操作符前后不加空格。
正例:
!bValue ~iValue ++iCount *strSource &fSum
aiNumber[i] = 5; tBox.dWidth tBox->dWidth
【规则2-4-3】多元运算符和它们的操作数之间至少需要一个空格。
正例:
fValue = fOldValue; fTotal + fValue iNumber += 2;
【规则2-4-4】函数名之后不要留空格。
说明:函数名后紧跟左括号 ( ,以与关键字区别。
【规则2-4-6】注释符与注释内容之间要用一个空格进行分隔。
正例:
/* 注释内容 */ // 注释内容
反例:
程序员必不可少,学习计算机语言设计不得不知道的一些规范
/*注释内容*/ //注释内容
6.2.5 断行
【规则2-5-1】长表达式(超过80 列)要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐。
说明: 条件表达式的续行在第一个条件处对齐。
for循环语句的续行在初始化条件语句处对齐。 函数调用和函数声明的续行在第一个参数处对齐。 赋值语句的续行应在赋值号处对齐。 正例:
if ((iFormat == CH_A_Format_M)
&& (iOfficeType == CH_BSC_M)) // 条件表达式的续行在第一个条件处对齐{
DoSomething(); }
for (long_initialization_statement;
long_condiction_statement;// for循环语句续行在初始化条件语句处对齐
long_update_statement) {
DoSomething(); }
// 函数声明的续行在第一个参数处对齐
BYTE ReportStatusCheckPara(HWND hWnd,
BYTE ucCallNo,
BYTE ucStatusReportNo);
// 赋值语句的续行应在赋值号处对齐
fTotalBill = fTotalBill + faCustomerPurchases[iID]
+ fSalesTax(faCustomerPurchases[iID]);
程序员必不可少,学习计算机语言设计不得不知道的一些规范
6.2.6 预处理指令
【规则2-6-1】预处理指令不要缩进,从行首开始。 即使预处理指令位于缩进代码块中,指令也应从行首开始。
6.3 注释
注释有助于理解代码,有效的注释是指在代码的功能、逻辑层次上进行注释,提供有用、额外的信息,而不是代码表面意义的简单重复。 【规则3-1】多行注释采用“/* … */”,单行注释采用“// …”。 【规则3-2】一般情况下,源程序有效注释量必须在30%以上
说明:注释的原则是有助于对程序的阅读理解,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。有效的注释是指在代码的功能、逻辑层次上进行注释,提供有用、额外的信息。 【规则3-3】注释使用中文。
说明:对于特殊要求的可以使用英文注释,如工具不支持中文或国际化版本时。
【规则3-4】文件头部必须进行注释,包括:.h 文件、.cpp 文件、.inc 文件、.def 文件、编译说明文件.cfg等。
说明:注释必须列出:版权信息、文件标识、内容摘要、版本号、作者、完成日期、修改信息等。
正例:
下面是文件头部的中文注释:
/*************************************************************
* 版权所有 (C)2010, 上海思源弘瑞自动化股份公司 * * 文件名称: // 文件名
* 内容摘要: // 简要描述本文件的内容,包括主要模块、函数及其功能的说明 * 其它说明: // 其它内容的说明 * 当前版本: // 输入当前版本 * 作 者: // 输入作者名字及单位
* 完成日期: // 输入完成日期,例:2010年5月15日*
* 修改记录1:// 修改历史记录,包括修改日期、修改者及修改内容 * 修改日期: