C、C++语言代码编写规范_第1页
C、C++语言代码编写规范_第2页
C、C++语言代码编写规范_第3页
C、C++语言代码编写规范_第4页
C、C++语言代码编写规范_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Q/ 许继集团有限公司发布-实施-发布C/C+语言代码编写规范(征求意见稿)Q/XJ Q/XJ许继集团有限公司企业标准IQ/XJ 目 次前 言III1 范围12 规范性引用文件13 术语和定义14 文件结构14.1 概述14.2 版权和版本的声明14.3 头文件的结构24.4 定义文件的结构25 程序的版式35.1 空行35.2 代码行45.3 代码行内的空格55.4 对齐55.5 长行拆分65.6 注释86 命名规则136.1 共性规则136.2 一般命名规则147 其它规则157.1 布尔变量与零值比较157.2 整型变量与零值比较167.3 浮点变量与零值比较167.4 指针变量与零值比较16附录A (资料性附录) 良好的C/C+编程风格;17A.1 良好的注释技巧17A.2 表达式和基本语句18A.3 变量、结构与数据类型20A.4 常量25A.5 函数26A.6 宏30A.7 程序效率31A.8 可测性35A.9 质量保证38A.10 代码编辑、编译、审查43I前 言本标准的附录A为资料性附录。本标准由许继电气股份有限公司提出。本标准由许昌继电器研究所归口。本标准起草单位:许继保护及自动化事业部、科研处、北京许继电气有限公司、珠海许继电气有限公司、深圳市许继昌达电网控制设备有限公司。本标准主要起草人:张新昌、包伟、杨智德、李江林、李旺、王若醒、刘彬、王伟东。IIC/C+语言编程规范1 范围本标准规定了软件编程中程序文件的结构和编程风格方面的一些规则。本标准适用于C/C+编程。2 规范性引用文件下列文件中的条款通过本标准的引用而成为本标准的条款。凡是注日期的引用文件,其随后所有的修改单(不包括勘误的内容)或修订版均不适用于本标准,然而,鼓励根据本标准达成协议的各方研究是否可使用这些文件的最新版本。凡是不注日期的引用文件,其最新版本适用于本标准。GB/T 5271.1-2000 信息技术 词汇 第1部分:基本术语GB/T 5271.7-1986 数据处理词汇 07部分:计算机程序设计GB/T 5271.15-1986 数据处理词汇 15部分:程序设计语言3 术语和定义GB/T 5271.1-2000、GB/T 5271.7-1986和GB/T 5271.15-1986确立的术语和定义适用于本标准。4 文件结构4.1 概述每个C/C+程序应至少包括两类文件。一个文件用于保存程序的声明,称为头文件。另一个文件用于保存程序的实现,称为定义文件。C/C+程序的头文件以“.h”为后缀,C程序的定义文件以“.c”为后缀,C+程序的定义文件通常以“.cpp”为后缀(也有一些系统以“.cc”或“.cxx”为后缀)。4.2 版权和版本的声明/* Copyright (c) 2001,许继集团有限公司* All rights reserved.* * 文件名称:filename.h* 摘 要:简要描述本文件的内容* 版本号:1.2 作者:作者(修改者) 完成日期:2003年7月20日* * 版本号:1.1 作者:作者(修改者) 完成日期:2003年5月20日* 版本号:1.0 作者:作者(修改者) 完成日期:2003年2月20日*/图1 版权和版本的声明版权和版本的声明位于头文件和定义文件的开头(见图1),主要内容有: 版权信息; 文件名称,摘要; 当前版本号,作者/修改者,完成日期; 版本历史信息。4.3 头文件的结构4.3.1 概述头文件由三部分内容组成: 头文件的版权和版本声明(见图1); 预处理块; 函数和类结构声明等。若头文件名称为 graphics.h,头文件的结构见图2。/ 版权和版本声明见图1#ifndefGRAPHICS_H/ 防止graphics.h被重复引用#defineGRAPHICS_H#include / 引用标准库的头文件#include “myheader.h” / 引用非标准库的头文件void Function1();/ 全局函数声明class Box / 类结构声明; / 其它#endif图2 C/C+头文件的结构4.3.2 为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。4.3.3 用 #include 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。4.3.4 用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。4.3.5 头文件中宜只存放“声明”而不存放“定义”。4.3.6 不提倡使用全局变量,不宜在头文件中出现extern int value 这类声明。4.4 定义文件的结构定义文件有三部分内容: 定义文件的版权和版本声明(见图1); 对一些头文件的引用; 程序的实现体(包括数据和代码)。若定义文件的名称为 graphics.cpp,定义文件的结构见图3。/ 版权和版本声明见图1#include “graphics.h”/ 引用头文件/ 全局函数的实现体void Function1()/ 类成员函数的实现体void Box:Draw()图3 C/C+定义文件的结构5 程序的版式5.1 空行5.1.1 在变量声明之后、每个类声明之后和每个函数定义结束之后应加空行(见图4(左)。5.1.2 在一个函数体内,逻辑上密切相关的语句之间应不加空行,其它地方应加空行分隔(见图4(右) 。/ 空行void Function1() / 空行void Function2() / 空行void Function3() / 空行while (condition)statement1;/ 空行if (condition) statement2;elsestatement3;/ 空行statement4; 图4 函数之间的空行(左),函数内部的空行(右)5.2 代码行5.2.1 一行代码宜只做一件事情,如只定义一个变量,或只写一条语句(见图5)。5.2.2 if、for、while、do等语句应自占一行,执行语句不应紧跟其后。不论执行语句有多少都应加(见图5)。int width;/ 宽度int height;/ 高度int depth;/ 深度int width, height, depth; / 宽度高度深度x = a + b;y = c + d;z = e + f;X a + b; y = c + d; z = e + f;if (width height) dosomething();if (width = 2000) / 良好的风格if(year=2000) / 不良的风格if (a=b) & (c=b&c=d) / 不良的风格for (i=0; i10; i+) / 良好的风格for(i=0;i10;i+) / 不良的风格for (i = 0; I 10; i +) / 过多的空格x = a b ? a : b; / 良好的风格x=aFunction(); / 不应写成 b - Function();图6 代码行内的空格5.3.1 关键字之后应留空格。如if、for、while等关键字之后应留一个空格再跟左括号(,以突出关键字。5.3.2 函数名之后应不留空格,紧跟左括号(,以与关键字区别。5.3.3 (后面应不留空格,)、,、;前面应不留空格。5.3.4 ,之后应留空格,如Function(x, y, z)。若;不是一行的结束符号,其后应留空格,如for (initialization; condition; update)。5.3.5 赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=” “=”、“=”、“+”、“*”、“%”、“&”、“|”、“”等操作符前后应不加空格。注: 对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格,如for (i=0; i10; i+)和if (a=b) & (c= very_longer_variable12)& (very_longer_variable3 = very_longer_variable14)& (very_longer_variable5 ),后不应加空格。注: 采用这种松散方式编写代码的目的是使代码更加清晰。由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如果语句已足够清晰则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格,因为在C/C+语言中括号已经是最清晰的标志了。在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。给操作符留空格时不要连续留两个以上空格。5.6 注释5.6.1 概述注释分为序言性注释和功能性注释: 序言性注释通常置于每一个程序模块的开头部分,给出程序的整体说明,对于理解程序具有引导作用; 功能性注释嵌在源程序体中,用以描述其后的语句或程序段在做什么工作。5.6.2 注释行的数量不得少于整个源程序的1/10。5.6.3 单行注释原则上不得超过可视窗口宽度。5.6.4 若代码本来就是清楚的,则不必加注释。示例 : i+; / i 加 1,多余的注释5.6.5 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释应删除。在存档的某一版本的源代码中不得存在由于调试而留下的大篇注释。5.6.6 注释应当准确、易懂,防止注释有二义性。5.6.7 尽量避免在注释中使用缩写,特别是不常用缩写。5.6.8 注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。(见图11)5.6.9 在同一函数或模块中的注释应尽量对齐,如下例所示:示例 :BOOL bReturnCache;/是否将Cache中的内容返回客户端HANDLE FileToWrite;/用来写数据的文件DWORD BytesWritten;/写入的数据长度/* get replicate sub system index and net indicator */repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;例1:/* get replicate sub system index and net indicator */repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;例2:repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;/* get replicate sub system index and net indicator */图11 风格良好的注释(左),与风格不良的注释(右)5.6.10 当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读(见图12)。/* 函数介绍:* 输入参数:* 输出参数:* 返回值 :*/void Function(float x, float y, float z) if () while () / end of while / end of if图12 程序的注释5.6.11 注释与所描述内容进行同样的缩排。注: 可使程序排版整齐,并方便注释的阅读与理解。示例 : 如下例子,排版不整齐,阅读不方便。void example_fun( void )/* code one comments */ CodeBlock One /* code two comments */ CodeBlock Two应改为如下布局。void example_fun( void ) /* code one comments */ CodeBlock One /* code two comments */ CodeBlock Two5.6.12 将注释与其上面的代码用空行隔开。示例 : 如下例子,显得代码过于紧凑。/* code one comments */program code one/* code two comments */program code two应如下书写/* code one comments */program code one/* code two comments */program code two5.6.13 函数注释(序言性注释)5.6.13.1 单元文件宜不超过1000行(包括注释), 复杂的组件单元可以不受此限制.5.6.13.2 每个函数或过程代码必须有注释文字, 每个函数体中,每一小功能段都应有注释。5.6.13.3 函数定义之前必须有对整个函数的描述,注释格式如下/*【函数名称】 (必需)【函数功能】 (必需)【参数】 (若有参数则必需注明)【全局变量】 (可选) 【返回值】 (若有返回值则必需注明)【备注】 (可选)【开发者及日期】 (若与头文件注释中的开发者为不同的人,则必需注明)【版本】 (若与头文件注释中的版本不同,则必需注明)【更改记录】 (若有修改,则必需注明)最后修改修改日期更改原因概要版本 【使用情况】 (可选)*/ 注释内容说明:函数名称:应包括函数名及参数;参数:在本项中标明是输入参数(用in表示)还是输出参数(用out表示);全局变量:该函数访问的全局变量和成员全局变量;版本:如1.0;更改记录:每次改动时增加一行注释,说明更改标识,更改日期,人,版本,更改原因概要;使用情况:即函数的调用情况,被调用的次数;示例 :/*【函数名称】int My_GetLastModifedTime(CString strFileName,char*FileTime,long *cl)【函数功能】寻找目标文件,从中读取Last-Modified:信息、Contene-Length信息【参数】FileNamein指向目标文件(从URL而来,需要转换,与目标文件一一对应)FileTimeout获取的Last-Modified:信息clout获取的Contene-Length信息【返回值】1文件存在,并从中取得Last-Modified:信息-1else【备注】使用了StrStrI函数,所以必须include shlwapi.h文件,且在编译的link项中包括shlwapi.li文件【开发者及日期】周慈 2000-02-05【版本】1.0【修改历史】最后修改XXX2000-03-26修改打开文件的模式,从OPEN_ALWAYS改为OPEN_EXISTING2000-03-28返回的时间字符串,最后一位不需要n,而且清除后面的所有空格版本1.2【使用情况】仅在ProxyThread函数中被调用一次*/5.6.14 程序注释(功能性注释)5.6.14.1 变量对所有有特定含义的变量命名,若其不能充分自注释,则必须注释变量意义;全局变量必须有较详细的注释,包括:功能、取值范围、存取关系、哪些函数或过程存取它以及注意事项等。示例 :/* active statistic task number */#define MAX_ACT_TASK_NUMBER 1000#define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number*/ 5.6.14.2 数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。示例 : 可按如下形式说明枚举/数据/联合结构。/* sccp interface with sccp user primitive message name */enum SCCP_USER_PRIMITIVE N_UNITDATA_IND, /* sccp notify sccp user unit data come */ N_NOTICE_IND, /* sccp notify user the No.7 network can not*/ /* transmission this message */ N_UNITDATA_REQ, /* sccp users unit data transmission*/ /* request */; 5.6.14.3 判断注释应说明被检查对象的意义。5.6.14.4 分支 对变量的定义和分支语句(条件分支、循环语句等)必须编写注释。注: 这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好的理解程序,有时甚至优于看设计文档。5.6.14.5 case语句对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。注: 这样比较清楚程序编写者的意图,有效防止无故遗漏break语句。示例 :(注意斜体部分):case CMD_UP: ProcessUp(); break;case CMD_DOWN: ProcessDown(); break;case CMD_FWD: ProcessFwd(); if (.) . break;else ProcessCFW_B(); / now jump into case CMD_Acase CMD_A: ProcessA(); break;case CMD_B: ProcessB(); break;case CMD_C: ProcessC(); break;case CMD_D: ProcessD(); break;.5.6.14.6 调用函数注释应说明该函数完成的处理。6 命名规则6.1 共性规则6.1.1 标识符应当直观且可以拼读,可望文知意,不必进行“解码”。标识符最好采用英文单词或其组合。 6.1.2 标识符的长度应当符合“min-length & max-information”原则。6.1.3 命名规则尽量与所采用的操作系统或开发工具的风格保持一致。6.1.4 程序中不应出现仅靠大小写区分的相似的标识符。示例 :int x, X;/ 变量x 与 X 容易混淆void foo(int x);/ 函数foo 与FOO容易混淆void FOO(float x);6.1.5 程序中不应出现标识符完全相同的局部变量和全局变量。6.1.6 变量的名字应当使用“名词”或者“形容词名词”。示例 :float value;float oldValue;float newValue;6.1.7 全局函数的名字宜使用“动词”或者“动词名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。示例 :DrawBox();/ 全局函数box-Draw();/ 类的成员函数6.1.8 宜用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。示例 :intminValue;intmaxValue;intSetValue();intGetValue();下面是一些在软件中常用的反义词组。add / remove begin / end create / destroy insert / delete first / last get / releaseincrement / decrement put / getadd / delete lock / unlock open / closemin / max old / new start / stopnext / previous source / target show / hidesend / receive source / destinationcut / paste up / down6.1.9 尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号。6.1.10 在同一软件产品内,应规划好接口部分标识符(变量、结构、函数及常量)的命名,防止编译、链接时产生冲突。注: 对接口部分的标识符应该有更严格限制,防止冲突。如可规定接口部分的变量与常量之前加上“模块”标识等。6.2 一般命名规则6.2.1 类名和函数名、结构名、typedef的名用大写字母开头的单词组合而成。示例 :class Node;/ 类名class LeafNode;/ 类名void Draw(void);/ 函数名void SetValue(int value);/ 函数名typedef struct STUDENT;/typedef6.2.2 变量和参数应用小写字母开头的单词组合而成。示例 :BOOL flag;int drawMode;6.2.3 常量应全用大写的字母,并用下划线分割单词。示例 :const int MAX = 100;const int MAX_LENGTH = 100;6.2.4 静态变量应加前缀s_(表示static)。示例 :void Init() static int s_initValue;/ 静态变量 6.2.5 若必须使用全局变量,则全局变量应加前缀g_(表示global)。示例 :int g_howManyPeople;/ 全局变量int g_howMuchMoney;/ 全局变量6.2.6 类的数据成员应加前缀m_(表示member),以避免数据成员与成员函数的参数同名。示例 :void Object:SetValue(int width, int height) m_width = width;m_height = height;6.2.7 为了防止某一软件库中的一些标识符和其它软件库中的冲突,可为各种标识符加上能反映软件性质的前缀。例如三维图形标准OpenGL的所有库函数均以gl开头,所有常量(或宏定义)均以GL开头。6.2.8 变量名应以小写字母打头,各英文描述单词的首字母分别大写,其他字母一律小写。全局变量用g_,文件级的用m_, 函数内的用nCount,局部变量不加(见表1)。表1 变量命名示例变量类型前缀示例(仅以全局变量为例) 全局变量 文件级变量 函数级变量布尔型g_bm_bbCountg_bFind整 型g_nm_nnCountg_nCount字符串g_strm_strstrCountg_strError对 象(类、结构等)g_objm_objobjCountg_objFont浮点型g_dblm_dbldblCountg_dblOffset指 针g_pm_ppCountg_pMainFrame6.2.9 不应使用以下划线“_”打头或结尾的标识符。示例 : _bFind 是不允许出现的变量;6.2.10 一个以小写字母开头的名字应当用下划线“_”将其和前缀隔离。示例 : m_b_find;6.2.11 名中含多于一个单词时,应将几个单词写到一起,每个随后的单词大写开头。示例 :m_nLastCount 中应大写L和C;6.2.12 名字不能太长,必要时可使用缩写名字,缩写规则应统一。示例 : m_nRemoteSendDataNumber 名字太长,应定义为m_nRSDNum7 其它规则7.1 布尔变量与零值比较不应将布尔变量直接与TRUE、FALSE或者1、0进行比较。注: 根据布尔类型的语义,零值为“假”(记为FALSE),任何非零值都是“真”(记为TRUE)。TRUE的值究竟是什么并没有统一的标准。例如Visual C+ 将TRUE定义为1,而Visual Basic则将TRUE定义为-1。示例 :若布尔变量名字为flag,它与零值比较的标准if语句如下:if (flag)/ 表示flag为真if (!flag)/ 表示flag为假其它的用法都属于不良风格,例如:if (flag = TRUE)if (flag = 1 )if (flag = FALSE) if (flag = 0)7.2 整型变量与零值比较应将整型变量用“=”或“!=”直接与0比较。示例 :若整型变量的名字为value,它与零值比较的标准if语句如下:if (value = 0) if (value != 0)不可模仿布尔变量的风格而写成if (value)/ 会让人误解 value是布尔变量if (!value) 7.3 浮点变量与零值比较不应将浮点变量用“=”或“!=”与任何数字比较。注: 无论是float还是double类型的变量,都有精度限制。所以应避免将浮点变量用“=”或“!=”与数字比较,应设法转化成“=”或“=-EPSINON) & (x=EPSINON)其中EPSINON是允许的误差(即精度)。7.4 指针变量与零值比较应将指针变量用“=”或“!=”与NULL比较。注: 指针变量的零值是“空”(记为NULL)。尽管NULL的值与0相同,但是两者意义不同。示例 :若指针变量的名字为p,它与零值比较的标准if语句如下:if (p = NULL)/ p与NULL显式比较,强调p是指针变量if (p != NULL)不应写成if (p = 0) / 容易让人误解p是整型变量if (p != 0) 或者if (p)/ 容易让人误解p是布尔变量if (!p)47附录A (资料性附录)良好的C/C+编程风格;A.1 良好的注释技巧A.1.1 避免在一行代码或表达式的中间插入注释。注: 除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差。A.1.2 通过对函数或过程、变量、结构等正确的命名以及合理地组织代码的结构,使代码成为自注释的。注: 清晰准确的函数、变量等的命名,可增加代码可读性,并减少不必要的注释。A.1.3 在代码的功能、意图层次上进行注释,提供有用、额外的信息。注: 注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,因此要防止没必要的重复注释。示例 :如下注释意义不大。/* if receive_flag is TRUE */if (receive_flag)而如下的注释则给出了额外有用的信息。 /* if mtp receive a message from links */if (receive_flag)A.1.4 在程序块的结束行右方加注释标记,以表明某程序块的结束。注: 当代码段较长,特别是多重嵌套时,这样做可以使代码更清晰,更便于阅读。示例 :参见如下例子。if (.)/ program codewhile (index MAX_INDEX)/ program code /* end of while (index .从左至右! + - (类型) sizeof+ - * &从右至左* / %从左至右+ -从左至右从左至右 =从左至右= !=从左至右&从左至右从左至右|从左至右&从左至右|从右至左?:从右至左= += -= *= /= %= &= =|= =从左至右A.2.1.1 若代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的优先级。A.2.2 复合表达式A.2.2.1 不应编写太复杂的复合表达式。示例 :i = a = b & c d & c + f = g + h ;/ 复合表达式过于复杂A.2.2.2 不应有多用途的复合表达式。示例 :d = (a = b + c) + r ; 该表达式既求a值又求d值。应该拆分为两个独立的语句:a = b + c;d = a + r;A.2.2.3 不要把程序中的复合表达式与“真正的数学表达式”混淆。示例 :if (a b c)/ a b c是数学表达式而不是程序表达式并不表示if (ab) & (bc)而是成了令人费解的if ( (ab)c )A.2.3 循环语句的效率A.2.3.1 在多重循环中,若有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。for (row=0; row100; row+)for ( col=0; col5; col+ )sum = sum + arowcol;for (col=0; col5; col+ )for (row=0; row100; row+) sum = sum + arowcol;图A.1低效率:长循环在最外层(左),高效率:长循环在最内层(右)A.2.3.2 若循环体内存在逻辑

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论