软件编码规范.docx
《软件编码规范.docx》由会员分享,可在线阅读,更多相关《软件编码规范.docx(87页珍藏版)》请在冰点文库上搜索。
软件编码规范
文件状态:
[√]草稿
[]正式发布
[]正在修改
文件编号:
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_strSysNames_静态变量s_nCurCnt,s_strStaticName,s_pSysTimem_类数据成员m_nBankType,m_sWrkBuffer,m_strMyNameh句柄类变量hnFileHandle,hnSocket,hpProcHandlep指针类变量psReadBuff,pstrRetStr,ppTargeta数组类变量anPorts,asSendBuffers,apWrkBuffs常用基本类型符前缀符含义例子bboolbOK,bQuit,bFindc、chcharcFlag,cBankType,chSubSystemTypeschar[]sSysName,sStaticName,sTimeStrstrCString、StringstrSysName,strStaticName,strTimeStrbyunsignchar[]byMacStr,bySendBuffer,bySrcBuffern、iintnCnt,nPort,nRetCodellonglFileSize,lOffset,lCountddoubledAmount,dSumVal,dWrkValffloatfAmount,fSumVal,fWrkValui/ulunsignedint/longuiCnt,uiFileSize,ulRetCountwWORD与unsignedint等价的32位整数dwDOUBLEWORD与unsignedlong等价的64位整数em枚举型变量emDays,emColors,emSetst结构型编码stSystem,stCtrlData,stSet规则11:禁止使用单字母作为变量名。但下列常用单字母变量除外:常用单字母变量变量类型说明i,j,k,m,nint循环变量cchar单字符变量schar[]字符数组变量x,yint位置变量pchar*指针变量一.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-132005-09-022005-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.cppvoidprintTrace(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:禁止使用宏替换关键字,如下列为不良写法。#defineMYENUMenumMYENUMerr{E_DATE=1,E_TIME=2}建议14:使用enum或constint或inline函数代替宏。例:#defineMAX_FRAME_SIZE1024#defineERR_DATE1#defineERR_TIME2
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
循环变量
c
单字符变量
字符数组变量
x,y
位置变量
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
●为使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;
(m_strFileName,FALSE,FALSE))
CStringstr;
("打开报文体文件[%s]失败!
",(0));
THROW_OUT(E_NEEDBUSIDATA,str);
return0;
2005-09-02}
编码风格
一.5排版风格
一.5.1缩进与对齐
规则24:
程序代码排版应采用缩进风格编写程序,每层缩进一个制表位(TAB)或四个空格。
应用程序全部代码应保持一致,要么使用TAB,要么使用四个空格,不应混用。
规则25:
左花括号({)单独占一行且与右花括号(})对齐。
IsQuit()){
exit(0);
应书写为:
IsQuit())
建议5:
每行只定义一个变量或包含一个语句。
intnRetCode,nMaxLen;
intnRetCode;
intnMaxLen;
规则26:
超长的语句(>80字符)或表达式应分成多行书写。
语句应在逗号分隔符处划分新行;表达式应在低优先级操作符处划分新行,操作符放在新行之首。
划分出的新行要进行适当的缩进,使排版整齐,语句易读。
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;
=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);
一.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""
externlongGetFileSize(LPCSTRsFileName);
externintg_nUserCode;
一.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
vsprintf(szTmp,lpText,argList);
应修改为:
.hpp
#definevsprintf_vsprintf
voidprintTrace(LPCSTRlpName,LPCSTRlpText,...)
规则39:
宏表达式的变量应使用括号括,使用宏时应避免传递表达式给宏变量。
#defineMAX(a,b)(a>b)?
a:
#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;
应书写成:
{\
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:禁止使用宏替换关键字,如下列为不良写法。#defineMYENUMenumMYENUMerr{E_DATE=1,E_TIME=2}建议14:使用enum或constint或inline函数代替宏。例:#defineMAX_FRAME_SIZE1024#defineERR_DATE1#defineERR_TIME2
CLEAR_ALL(strlen(str))
str[ii]=0;
#defineCLEAR_ALL(n)\
for(intii=0;ii<(n);ii++)\
str[ii]=0;\
}\
以上两例应书写为:
#defineCLEAR_ALL(str,n)\
/*即使这样,代码依然是不安全的。
应避免在宏中定义变量*/
规则42:
禁止使用宏替换关键字,如下列为不良写法。
#defineMYENUMenum
MYENUMerr
E_DATE=1,
E_TIME=2
建议14:
使用enum或constint或inline函数代替宏。
#defineMAX_FRAME_SIZE1024
#defineERR_DATE1
#defineERR_TIME2
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2