2、.183.附录:通用类型的公共定义.23北京世纪百合技术有限公司软件编程规范第4页共24页引言1.1目的本规范的目的在于增加源代码的可读性,减少程序员对代码理解上的偏差,使程序员能够编写出可靠的代码,降低代码维护成本。1.2范围本规范内容涉及范围包括:文件、版面、注释、标识符、变量和结构、函数、宏以及可理解性等。本规范适用于公司开发的所有软件产品。在新软件的编码过程中本规范必须执行。规范2.1文件2.1.1头文件的名称一律为小写,格式为“子系统名_文件名.h”。例如:ipf_protocol.h等。头文件的格式如下:注释头,格式参见软件编程规范;头文件预编译开关开始,格式
7、pyright(c)LilyOfTheCenturyTechnologyCo.,LTD.ALLRIGHTSRESERVEDDescription:定义配置数据结构*/#ifndef_ISDN_A_H#define_ISDN_A_Htypedefstruct,ISDN_CONFIG;ISDN_CONFIGg_stlsdnConfig;#endif结构变量g_stIsdnConfig不能在头文件中定义,只能在源文件中定义。可以在相应的源文件定义后,头文件作如下改动:ISDN_CONFIGg_stIsdnConfig;改为externISDN_CONF
9、规范第8页共24页2.2版面风格2.2.1程序块采用缩进风格编写,缩进使用TAB符号,TAB符号规定为4个空格。变量说明之后必须加空行。说明:由开发工具自动生成的代码例外。示例:如下例子不符合规范。voidisdn_lnitConfig(void)_WORDwConfigNumner;;/programcode应如下书写voidisdn_lnitConfig(void)_WORDwConfigNumner;;/programcode2.2.2不允许把多个短语句写在一行中,一行只写一条语句。示例:如下例子不符合规范。wLength=wWidth=
10、0;或wLength=0,wWidth=0;应如下书写wLength=0;wWidth=0;禁止如下写法:inti=j=0;或inti=0,j=0;应该写作:inti=0;intj=0;或inti,j;i=0;j=0;do、while、switch、case、default、if、else、for等语句自占一行,且if、else语句在同一列。示例1:如下例子不符合规范。do.;/programcodewhile(pstUser!=NULL);应如下书写:do北京世纪百合技术有限公司软件编程规范第9页共24页;/pr
11、ogramcodewhile(pstUser!=NULL);示例2:如下例子不符合规范while(pstUser!=NULL);/programcode应如下书写:while(pstUser!=NULL);/programcode示例3:如下例子不符合规范switch(dwCounter)case1:dwCounter+;;/programcodebreak;default:break;应如下书写:switch(dwCounter)case1:dwCounter+;;/programcodebreak;default:brea
12、k;示例4:如下例子不符合规范if(pstUser=NULL)return;else;/programcode应如下书写:if(pstUser=NULL)return;else;/programcode示例5:如下例子不符合规范for(i=0;i10;i+);/programcode应如下书写:for(i=0;i4)&OxFO)2.3.3函数的命名为:前缀+下划线+字符串。其中前缀为全小写的子系统名称,字符串由一个或多个单词组成,每个单词首字母大写,其他字母小写。示例:voidMsgCreate(void);voidicmp_PktRecv(v
13、oid);调试用的编译开关是开头为下划线的全大写字符串,具体格式是:下划线+DEBUG+子系统名称+下划线+名称。示例:_DEBUG_IPF_IP_PACKET、_DEBUG_TCP_OPTION等。结构联合类型命名规则为:子系统名称+下划线+结构名称、子系统名称+下划线+联合名称,其中所有字母大写。示例:typedefstructIP_TRACEROUTE;typedefunionICMP_PKT;2.3.6全局变量命名的具体格式是:前缀+下划线+子系统名+下划线+字符串,其中前缀为小写的“g”,子系统名称全部小写,字符串由一个或多个单词组成,每个单词首字母大写,其他字母小写。示例
14、:gcmp_TraceRouteQueue、g_ospf_InterfList等。2.3.7消息宏定义的采用一下格式:前缀+下划线+字符串+下划线+后缀。其中前缀采用小写的“mm”,字符串标记消息宏的具体含义,由一个或多个单词组成,每个单词首字母大写,其他字母小写,后缀为XXXtoYYY,表示消息的传送方向,XXX表示源子系统名,丫丫丫为目的子系统名,全部用大写字母表示。示例:mm_AddRoute_BGPtoRTMGT表示从BGP协议发送到路由管理实体的增加一条路由的消息,mm_ShowIpRoute_CLItoRTMGT表示从CLI发送到路由管理子系统的要求显示路由表的消息。2.
15、4函数与宏2.4.1对函数的返回值要仔细、全面地处理。说明:对提供返回值的函数,尤其是接口函数,其返回值必须检查。示例:以下函数是不规范的北京世纪百合技术有限公司软件编程规范第15页共24页voidisdn_SendMessage(void)_;/programcodeMsgPost(.);/发送消息应该改作voidisdn_SendMessage(void)_INT32iPost;;/programcodeiPost=MsgPost(.);/发送消息if(iPost=OK);/处理代码else;/处理代码2.4.2接口函数的输入参数(尤其是指针和数组
16、下标)、非输入参数的合法性必须检查。说明:函数的输入主要有两种:一种是参数输入;另一种是非参数输入,包括全局变量、数据文件等,这些参数都需要作检查。示例:下函数的实现不符合规范。RESULTisdn_Receive(NI_CELL*pstCell,SK_BUF*pstSkBuf);/接收数据代码returnOK;应改作以下写法。RESULTisdn_Receive(NI_CELL*pstCell,SK_BUF*pstSkBuf)if(pstCell=NULL)|(pstSkBuf=NULL)returnFALSE;/接收数据代码returnOK;北京世纪
17、百合技术有限公司软件编程规范第16页共24页2.4.3禁止把函数的参数作为工作变量。说明:需要做改变的参数,应该先用局部变量代之,最后再将该局部变量的内容赋给该参数。示例:下函数的实现不符合规范。BOOLEANisdn_SumData(WORDwNumber,WORD*pwData,WORD*pwSum)_WORDwCount;if(pwData=NULL)|(pwSum=NULL)returnFALSE;*pwSum=0;for(wCount=0;wCountwNumber;wCount+)*pwSum+=pwDatawCou
18、nt;/pwSum成了工作变量,不规范returnTRUE;应改作以下写法。BOOLEANisdn_SumData(WORDwNumber,WORD*pwData,WORD*pwSum)_WORDwCount;WORDwSumTemp;if(pwData=NULL)|(pwSum=NULL)returnFALSE;wSumTemp=0;for(wCount=0;wCountba:b#defineMAx(a,b)(aba:b)#defineMAX(a,b)(a)(b)(a):(b)正确的定义
19、应为:#defineMAX(a,b)(a)(b)(a):(b)2.4.7将宏所定义的多条表达式放在大括号中。示例:下面的定义不规范#defineISDN_INIT_VALUE(a,b)a=0;b=0;正确的用法应为:#defineISDN_INIT_VALUE(a,b)a=0;b=0;2.4.8使用宏时,不允许参数发生变化。示例:如下用法导致错误。#defineMAX(a,b)(a)(b)(a):(b)iResult=MAX(iRx+,iTx);将被预处理器解释为iResult=(iRx+)(iTx)(
20、iRx+):(iTx);此时如果输入iRx=6;iTx=5;代码执行结果iResult=7,此时iRx为8应该改作如下用法:iResult=MAX(iRx,iTx);iRx+;voido北京世纪百合技术有限公司软件编程规范第18页共24页2.5代码的可靠性2.5.1系统运行之初,要初始化所有本系统的全局变量,禁止未经初始化的全局变量被引用。说明:使用未初始化的数据,容易使系统进入混乱状态。示例:以下的全局变量如果没有在系统运行时初始化,在被函数使用时会出错ISDN_CELL*g_pstlsdnCellISDN_MAX_CELL_NUM;voidisdn_Sh
21、owChannel(WORDwSlot,WORDwPort)ISDN_CELL*pstIsdnCell=0;inti;for(i=0;iwSlot=wSlot)&(pstIsdnCell-wPort=wPort)break;;/otherprogramcode2.5.2申请内存之后,应该立即检查指针值是否为NULL?(防止使用指针值为NULL的内存)说明:申请内存时,如果申请失败,应该避免使用该指针。必须使用if(p=NULL)或if(p!=NULL)进行防错处理。2.5.3禁止将未被初始化的内存作为零值使用。北京世纪百合技术有限公司软
22、件编程规范第19页共24页说明:创建的数组或动态申请的内存,其初始值是不确定的,不能当作零处理。示例:以下代码是不规范的。voidisdn_Checkle(BYTE*pbyle,WORDwleLen)WORDwTempLen;/wTempLen未初始化,其初始值不一定为0while(wTempLenwIeLen).;/otherprogramcodewTempLen+=2;应作如下改写:voidisdn_Checkle(BYTE*pbyIe,WORDwIeLen)WORDwTempLen;wTempLen=0;while(wTempLe
23、nMAX_LENGTH)returnLENGTH_ERROR;/忘了释放pbyBuf;/otherprogramcode应改为如下。intExampleFunction(BYTEbyLen)BYTE*pbyBuf;pbyBuf=(BYTE*)malloc(MAX_LENGTH);;/programcode,includecheckpBufifornotNULLif(byLenMAX_LENGTH)free(pBuf);/退出之前释放pbyBufreturnLENGTH_ERROR;;/otherprogramcode2.5.12在s
24、witch的处理程序块中,必须有default语句;并且每个case语句都要有对应的break。说明:如果一个case下的处理语句需要调用下一个case的处理语句,可以将下一个case的处理语句copy过来。示例:以下写法是不规范的switch(wEvent)case1:isdn_SendEvent(wEvent);case2:wEvent+;break;default:北京世纪百合技术有限公司软件编程规范第22页共24页break;应该改为:switch(wEvent)case1:isdn_SendEvent(wEvent);wEvent+;break;case2:wEvent+;break;default:break;2.5.13不要滥用goto语句。说明:goto语句会破坏程序的结构性,除非确实需要,不要使用goto语句。2.5.14留心程序机器码大小(如指令空间大小、数据空间大小、堆栈空间大小等)是否超出系统有关限制。2.5.15使用显式的数据类型转换,避免让编译器进行隐式的数据类型转换。说明:使用显示的数据转换一方面增加可读性,有利于代码的维护;另一方面避免隐式的数据类型转换引起的编译告警。示例:以下的书写不符合规范NI_CELL*isdn_Load(void)NI_CELL*pstNiCell