软件编码规范.docx

上传人:b****4 文档编号:6882195 上传时间:2023-05-10 格式:DOCX 页数:87 大小:151.47KB
下载 相关 举报
软件编码规范.docx_第1页
第1页 / 共87页
软件编码规范.docx_第2页
第2页 / 共87页
软件编码规范.docx_第3页
第3页 / 共87页
软件编码规范.docx_第4页
第4页 / 共87页
软件编码规范.docx_第5页
第5页 / 共87页
软件编码规范.docx_第6页
第6页 / 共87页
软件编码规范.docx_第7页
第7页 / 共87页
软件编码规范.docx_第8页
第8页 / 共87页
软件编码规范.docx_第9页
第9页 / 共87页
软件编码规范.docx_第10页
第10页 / 共87页
软件编码规范.docx_第11页
第11页 / 共87页
软件编码规范.docx_第12页
第12页 / 共87页
软件编码规范.docx_第13页
第13页 / 共87页
软件编码规范.docx_第14页
第14页 / 共87页
软件编码规范.docx_第15页
第15页 / 共87页
软件编码规范.docx_第16页
第16页 / 共87页
软件编码规范.docx_第17页
第17页 / 共87页
软件编码规范.docx_第18页
第18页 / 共87页
软件编码规范.docx_第19页
第19页 / 共87页
软件编码规范.docx_第20页
第20页 / 共87页
亲,该文档总共87页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

软件编码规范.docx

《软件编码规范.docx》由会员分享,可在线阅读,更多相关《软件编码规范.docx(87页珍藏版)》请在冰点文库上搜索。

软件编码规范.docx

软件编码规范

 

 

软件编码规范

 

 

文件状态:

[√]草稿

[]正式发布

[]正在修改

文件编号:

RDC-DED-SCS-SPC-00

当前版本:

作者:

审核人:

完成日期:

 

中国人民银行清算总中心

支付系统开发中心

 

文档修订记录

版本编号

变化状态

简要说明

日期

变更人

批准日期

批准人

注:

变化状态:

A—增加,M—修改,D—删除

前言

程序编码是一种艺术,既灵活又严谨,充满了创造性与奇思妙想。

然而应用软件设计是一项团结协作工程,而非程序员展示个人艺术的舞台,大型应用软件项目更是由很多程序员组成的大型开发团队协同完成的。

每个程序员都有自己的编码经验与风格,如果缺乏统一的编程规范,则可能导致软件产品最终程序代码风格迥异,可读性与可维护性均较差,不仅给程序代码的理解带来障碍,也增加维护阶段的工作量。

此外,经验证明不规范的编码行为往往还会导致程序出现更多的隐含错误。

为规范编码行为,增强程序代码的可读性、可维护性,提高编码质量与效率,保障应用软件产品整体品质与可持续开发性,特制定本规范。

本规范分C/C++编码规范、Java编码规范、PB编码规范三篇,分别从代码组织、命名、注释、编码风格、编译等方面加以阐述。

规范文本分为规则与建议两种,其中规则是强制执行的条款,建议则由程序员根据实际情况灵活掌握。

C/C++编码规范

代码组织

规则1:

使用不同的文件分别放置模块的约束与实现。

C++程序的约束文件使用.hpp做扩展名,实现文件使用.cpp做扩展名;C程序的约束文件使用.h做扩展名,实现文件使用.c做扩展名。

规则2:

一个模块可以包含一个类或功能上紧密联系的多个类。

禁止将功能关联松散的多个类,放置到一个模块中。

规则3:

模块约束应仅包含模块对外提供的功能,禁止将模块内部使用的功能声明在模块约束中。

下例中IsChineseChar()是内部使用的函数,不提供给外部应用使用,因此不能在中增加声明。

例:

BOOLIsChineseString(constchar*sInStr);

例:

staticBOOLIsChineseChar(constchar*s)

{

……;

}

BOOLIsChineseString(constchar*sInStr)

{

for(intii=0;ii

{

if(!

IsChineseChar(sInStr+ii))

{

returnFALSE;

}

}

returnTRUE;

}

规则4:

简单应用应创建下列目录结构,模块程序代码应分别放置到src/include目录与src/source目录,编译文件放置到src/source目录,编译后的可执行文件放置到rel/bin目录,静态库或动态库放置到rel/lib目录(应用使用的外部库及头文件放置在rel同级的lib与lib/include目录)。

规则5:

复杂应用应分子系统创建目录结构,模块程序代码应分别放置到src/module/include目录与src/module/source目录,应用编译文件放置到src目录,编译后的可执行文件放置到rel/bin目录,静态库或动态库放置到rel/lib目录。

(应用使用的外部库及头文件放置在rel同级的lib与lib/include目录)

规则6:

各子系统可以创建独立的编译文件并放置到src/module/source目录,编译后的可执行文件放置到rel/bin/module目录或rel/bin,静态库或动态库放置到rel/lib/module或rel/lib目录。

此时,应创建一个编译全部子系统的编译文件或脚本放置到src目录。

命名

规则7:

命名应遵循下列原则:

●应简单清晰通俗;

●应使用英文命名,禁止使用中文命名;

●应尽量选择通用词汇;

●应使用完整单词或词组,避免使用简称;

●应准确表达其含义;

●避免同时使用易混淆的字母与数字,如1与l,0与o;

●禁止使用只靠大小写区分的多个名称;

●多单词组成的名称,单词的首字母应大写,如FileName。

规则8:

名称太长超过15字符时应使用简称。

简称应遵循:

●应使用标准的或常用的简写,如Temp(tmp),Length(len);

●应用范围内简写应一致且规范,避免各处简写各不相同;

●简写可以使用单词的前一个或多个字母,如Channel(Chan)、Connect(Conn);也可以使用去掉所有的不在词头的元音字母,如screen(scrn),primtive(prmv);

●多个单词组成的名称,使用有意义的单词或去掉无用的后缀并简称,如CountofFailure(FailCnt),PagingRequest(PagReq)。

一.1文件命名

规则9:

文件命名应使用模块名的小写字母形式。

禁止使用汉字或大、小写字母混用作为代码文件名。

一.2变量命名

规则10:

变量命名主要采用匈牙利命名法,格式为[作用域范围前缀_][前缀]基本类型+名称。

其中,作用域范围前缀、前缀以小写字母表示且可选,基本类型以小写字母表示且必选。

常用前缀符

前缀符

含义

例子

g_

全局变量

g_stSystem,g_cMacType,g_strSysName

s_

静态变量

s_nCurCnt,s_strStaticName,s_pSysTime

m_

类数据成员

m_nBankType,m_sWrkBuffer,m_strMyName

h

句柄类变量

hnFileHandle,hnSocket,hpProcHandle

p

指针类变量

psReadBuff,pstrRetStr,ppTarget

a

数组类变量

anPorts,asSendBuffers,apWrkBuffs

常用基本类型符

前缀符

含义

例子

b

bool

bOK,bQuit,bFind

c、ch

char

cFlag,cBankType,chSubSystemType

s

char[]

sSysName,sStaticName,sTimeStr

str

CString、String

strSysName,strStaticName,strTimeStr

by

unsignchar[]

byMacStr,bySendBuffer,bySrcBuffer

n、i

int

nCnt,nPort,nRetCode

l

long

lFileSize,lOffset,lCount

d

double

dAmount,dSumVal,dWrkVal

f

float

fAmount,fSumVal,fWrkVal

ui/ul

unsignedint/long

uiCnt,uiFileSize,ulRetCount

w

WORD

与unsignedint等价的32位整数

dw

DOUBLEWORD

与unsignedlong等价的64位整数

em

枚举型变量

emDays,emColors,emSet

st

结构型编码

stSystem,stCtrlData,stSet

规则11:

禁止使用单字母作为变量名。

但下列常用单字母变量除外:

常用单字母变量

变量

类型

说明

i,j,k,m,n

int

循环变量

c

char

单字符变量

s

char[]

字符数组变量

x,y

int

位置变量

p

char*

指针变量

一.3常量与宏命名

规则12:

常量与宏应使用全大写名称,多词组名称使用_分隔各单词,并使用断行注释说明其含义如:

constintMAX_BUFF_SIZE=1024

规则13:

规则14:

规则15:

建议1:

规则16:

2007-03-052007-03-072007-03-052007-03-07

规则17:

规则18:

.Fail...}

*...

*nRetCode=(&stSet,SIGHUP);

*if(nRetCode<0){...Fail...}

*@endcode

*/

intAddToSet(sigset_t*stSet,intnSignal,intnOtherSignal=0,...);

建议2:

重要的或复杂的函数,应提供算法说明或使用范例。

如:

例:

/**

*@brief根据行号与密码生成报尾校验码作为身份认证串。

*@param[in]sBankCode行号;

*@param[in]sPassword密码。

*@return身份认证串。

*@par算法介绍:

*-#计算sBankCode+sPassword的MD5数字摘要,输出32位字符;

*-#取32位字符的0,5,10,15,16,21,26,31位作16位字符串的偶数位;

*-#取"AUTHBEPS"各位作16位字符串的奇数位;

*-#加密这16位的字符串,得到32位的字符串作为认证串。

*/

CStringBuildAuthStr(LPCSTRsBankCode,LPCSTRsPassword);

一.3.1数据成员注释

规则19:

类的每个数据成员均使用断行注释。

注释格式如下:

例:

classCMTMsg

{

private:

BOOLm_bBodyInFile;

规则20:

规则21:

1M


*为了突破计算机最大整数的限制,可以采取两种做法,一是扩大基数,二是增加字长。

*根据此原理,本类使用65536作为基数,每个整数的最大位数10(unsignedintarray[10]),

*因此可以最大整数是65536的10次方,约。

通过变更基数或位数,本类理论上可以处理的任意整数。

*/

●需要生成圆点列表时使用-,需要生成编号列表时使用-#。

●需要特别说明一段文字,可以使用@code/@endcode。

如:

*@par计算公式:

*@code

*最大长度=MQCMT消息长度-sizeof(CMTMsgHeader)-sizeof(CMTMsgTail)-sizeof(MQMsg)+1

*=MQCMT最大消息长度-175

*@endcode

●为使doxygen正确生成函数或方法的连接,注释中的函数名或方法名前后应留一个空格。

如该函数或方法没有重载,则不必使用参数列表,如GetTag()。

如该函数或方法重载,则应必须使用参数(类型)列表,如GetTag(LPCSTR,AMOUNT&,BOOL,int,int)。

一.4语句块注释

规则22:

程序代码主要流程、重要算法以及逻辑性较强的代码和有特殊设计意图的代码(如没有break的case块、空循环体、空语句块)等位置,应添加语句块注释。

通过语句块注释,应能反映程序功能的概貌,注释量不应少于该模块概要设计的流程描述量。

规则23:

语句块注释应遵循下列原则:

●应使用断行注释,即

算MD5指纹

CStringstrMD5=((BYTE*)(0),());

取八位数字指纹

char*p=(0);

charsTmpStr[17];

intii=0;

memset(sTmpStr,0,sizeof(sTmpStr));

for(ii=0;ii<8;++ii)sTmpStr[2*ii]=p[4*ii+ii%4];

合固定串

p="AUTHBEPS";

for(ii=0;ii<8;++ii)sTmpStr[2*ii+1]=p[ii];

例:

特殊设计意图

BigInt:

:

~BigInt()

{

建议3:

建议4:

2005-04-13

2005-09-02

2005-09-02CBuffedFilereader;

if(!

(m_strFileName,FALSE,FALSE))

{

CStringstr;

("打开报文体文件[%s]失败!

",(0));

THROW_OUT(E_NEEDBUSIDATA,str);

}

}

return0;

2005-09-02}

编码风格

一.5排版风格

一.5.1缩进与对齐

规则24:

程序代码排版应采用缩进风格编写程序,每层缩进一个制表位(TAB)或四个空格。

应用程序全部代码应保持一致,要么使用TAB,要么使用四个空格,不应混用。

规则25:

左花括号({)单独占一行且与右花括号(})对齐。

例:

if(!

IsQuit()){

exit(0);

}

应书写为:

if(!

IsQuit())

{

exit(0);

}

建议5:

每行只定义一个变量或包含一个语句。

例:

intnRetCode,nMaxLen;

应书写为:

intnRetCode;

intnMaxLen;

规则26:

超长的语句(>80字符)或表达式应分成多行书写。

语句应在逗号分隔符处划分新行;表达式应在低优先级操作符处划分新行,操作符放在新行之首。

划分出的新行要进行适当的缩进,使排版整齐,语句易读。

例:

if(!

IsNumberString||strlen!

=12||strcmp,==0)

应书写为:

If(!

IsNumberString

||strlen!

=12

||strcmp,==0)

THROW_OUT(E_INVALIDLIST,StrPrint("票交机构行别非数字或长度非3位!

[%s]",.GetBuffer(0));

应书写为:

THROW_OUT(E_INVALIDLIST,

StrPrint("票交机构行别非数字或长度非3位!

[%s]",

.GetBuffer(0));

建议6:

对结构的多个数据成员赋值时,将等号对齐。

例:

=0;

=0;

=300;

=200;

应书写为:

=0;

=0;

=300;

=200;

建议7:

定义多个宏或初始化多个变量时,将值对齐。

例:

#defineMBT_PREFIX"{"

建议8:

建议9:

规则27:

建议10:

建议11:

规则28:

规则29:

建议12:

规则30:

规则31:

GetName(strOrgName);

if(str=="uname")

{

pOldSet->m_nName=str;

}

应书写为:

CStringstr=(strOrgName);

if(str=="uname")

{

pOldSet->m_nName=str;

}

一.5.2括号使用

规则32:

复杂的表达式应使用括号以避免二义性,不应依赖运算符优先级。

如:

if((i>0)||(i<=-12))、(p++)+1。

规则33:

位运算时应使用括号,如:

i=(nSumVal<<4)。

规则34:

return与throw非函数,不应使用括号。

如:

returnnRetCode。

一.6头文件

规则35:

头文件应使用防止重复包含宏括整个头文件部分。

宏名应为__模块名_HPP__或__模块名_H__。

注意:

#endif后必须保留一个空行,否则部分编译器会报警告信息。

规则36:

本模块需要的头文件以及外部函数,应全部列在本模块头文件的首部且紧临防重复包含宏,并按先系统级、公共级、应用级、本模块级的顺序摆放。

尽量不在实现文件中包含除本模块头文件外的其他头文件以及外部函数。

规则37:

头文件引用禁止含路径信息,无论是全路径还是相对路径。

规则38:

禁止在头文件中定义变量或常量。

例:

头文件

#ifndef__MODULE_NAME_HPP__

#define__MODULE_NAME_HPP__

#include<>

#include"/PUBLIB/src/include/"

#include"../include/"

intg_nUserCode=0;

#endif

例:

实现文件

#include<>

#include""

#include"../include/"

externlongGetFileSize(LPCSTRsFileName);

应书写为:

#ifndef__MODULE_NAME_HPP__

#define__MODULE_NAME_HPP__

#include<>

#include<>

#include""

#include""

#include""

externlongGetFileSize(LPCSTRsFileName);

externintg_nUserCode;

#endif

应书写为:

#include""

intg_nUserCode=0;

一.7宏定义

建议13:

灵活使用编译宏解决平台或版本的兼容性问题。

例:

.cpp

#ifdefWIN32

.)

{

charszTmp[4096];

memset(szTmp,0,sizeof(szTmp));

va_listargList;

va_start(argList,lpText);

_vsprintf(szTmp,lpText,argList);

va_end(argList);

fprintf(stderr,"[%s]%s:

%s\n",StrCurrentTime("YYYY-MM-DDHH:

MM:

SS").GetBuffer(0),lpName,szTmp);

}

#else

.)

{

charszTmp[4096];

memset(szTmp,0,sizeof(szTmp));

va_listargList;

va_start(argList,lpText);

vsprintf(szTmp,lpText,argList);

va_end(argList);

fprintf(stderr,"[%s]%s:

%s\n",StrCurrentTime("YYYY-MM-DDHH:

MM:

SS").GetBuffer(0),lpName,szTmp);

}

#endif

应修改为:

.hpp

#ifdefWIN32

#definevsprintf_vsprintf

#endif

.cpp

voidprintTrace(LPCSTRlpName,LPCSTRlpText,...)

{

charszTmp[4096];

memset(szTmp,0,sizeof(szTmp));

va_listargList;

va_start(argList,lpText);

vsprintf(szTmp,lpText,argList);

va_end(argList);

fprintf(stderr,"[%s]%s:

%s\n",StrCurrentTime("YYYY-MM-DDHH:

MM:

SS").GetBuffer(0),lpName,szTmp);

}

规则39:

宏表达式的变量应使用括号括,使用宏时应避免传递表达式给宏变量。

例:

#defineMAX(a,b)(a>b)?

a:

b

应书写为:

#defineMAX(a,b)(((a)>(b))?

(a):

(b))

调用:

intnMax=MAX(i++,b++);

应书写为:

intnTmpi=i++;

intnTmpb=b++;

intnMax=MAX(nTmpi,nTmpb);

规则40:

单条语句构成的宏不应使用分号作为宏结束;多条语句构成宏时,应使用花括号括宏体。

例:

#defineThrowExceptionExt(sFileName,nErrCode,sExtMsg)\

ThrowFileExceptionExt(__FILE__,__LINE__,sFileName,nErrCode,sExtMsg);

returnnErrCode

#defineRETCODE(n)returnn;

应书写成:

#defineThrowExceptionExt(sFileName,nErrCode,sExtMsg)\

{\

ThrowFileExceptionExt(__FILE__,__LINE__,sFileName,nErrCode,sExtMsg);\

returnnErrCode;\

}

#defineRETCODE(n)returnn

规则41:

构成宏体的语句必须完成,禁止包含语句块的部分。

例:

#defineCLEAR_ALL(n)for(intii=0;ii

CLEAR_ALL(strlen(str))

{

str[ii]=0;

}

#defineCLEAR_ALL(n)\

{\

for(intii=0;ii<(n);ii++)\

{\

str[ii]=0;\

}\

}

以上两例应书写为:

#defineCLEAR_ALL(str,n)\

{\

for(intii=0;ii<(n);ii++)\

{\

str[ii]=0;\

}\

}

/*即使这样,代码依然是不安全的。

应避免在宏中定义变量*/

规则42:

禁止使用宏替换关键字,如下列为不良写法。

#defineMYENUMenum

MYENUMerr

{

E_DATE=1,

E_TIME=2

}

建议14:

使用enum或constint或inline函数代替宏。

例:

#defineMAX_FRAME_SIZE1024

#defineERR_DATE1

#defineERR_TIME2

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2