C语言编码规范1..pdf
- 文档编号:18940714
- 上传时间:2024-03-14
- 格式:PDF
- 页数:59
- 大小:7.24MB
C语言编码规范1..pdf
《C语言编码规范1..pdf》由会员分享,可在线阅读,更多相关《C语言编码规范1..pdf(59页珍藏版)》请在冰点文库上搜索。
编号:
HX/C语言编码规范项目编号:
部n:
安全产品部________________________拟制:
2009年3月28日审核:
年月日批准:
年月日发放编号:
__________________________________受控状态:
非受控武汉虹旭信息技术有限责任公司修改记录修改号修改/生效日期修改页次修改理由03.28.2009文档新建03.28.2009修改号编写审核批准批准日期目录修改记录.1目录.2C语言编码规范.41总则.41.1目的.41.2适用范围.41.3术语定义.42程序的布局.42.1文件头说明.52.2头文件说明.62.2.1条件编译.62.2.2头文件内容.62.3头文件布局不例.72.4源文件布局示例.93命名规则.113.1匈牙利记名法.113.1.1基本命名规则.113.1.2细则.113.2休斯编码规范.143.2.1基本命名规则.143.2.2细则.144函数.164.1函数的设计.164.1.1规则.164.1.2建议.174.2函数参数.184.2.1规则.184.2.2建议.194.3函数体.214.3.1规则.214.3.2建议.224.4函数返回值.254.4.1规则.254.4.2建议.255变量.265.1规则.265.2建议.266结构.276.1规则.276.2建议.287注释.297.1规则.297.2建议.328排版.338.1规则.338.2建议.379可读性.3810数据类型.3911编译、测试、发布.4011.1规则.4011.2建议.4112断言.4212.1规则.4212.2建议.4313程序效率.4513.1规则.4513.2建议.4714内存操作.4914.1规则.4914.2建议.5115宏.5216其它.5316.1规则.5316.2建议.5517修改代码注意事项.5618结语.57C语言编码规范1总则1.1目的为了提高源程序的质量和可维护性,提高产品质量,我们有必要对产品源程序的编写风格做出统一的规范。
1.2适用范围本规范适用安全产品部生产的所有源程序。
对于外购的协议栈等其他源代码,修改时应遵循其自身的风格。
本规范的大部分是独立于具体语言的编程规则的总的原则,考虑到本部门主要使用的编程语言为标准c,所以部分规则专门针对标准c。
1.3术语定义本规范的示例都以c语言为背景,采用以下的术语描述:
规则:
编程时强制必须遵守的原则。
建议:
编程时必须加以考虑的原则。
说明:
对此规则或建议进行必要的解释。
示例:
对此规则或建议从正、反两个方面给出例子。
2程序的布局程序员经常忽略程序的布局,不重视程序的布局,实际上,程序的布局非常重要,首先它可以增加程序代码的可读性,并且能够减少编译错误,因此,在我们的开发过程中,应该首先考虑的问题就是程序的布局。
建议2:
程序建议按照以下顺序编写:
说明:
子系统公共头文件中包括子系统各模块需要用到的基础的系统头文件、平台头文件、调试用到的头文件等。
头文件编写顺序文件头包含头文件(可选)测试开关宏定义类型定义(可选)常量定义其他宏定义联合、枚举等定义结构体定义其他定义(可选)源文件编写顺序包含头文件子系统公共头文件系统头文件接口头文件其他头文件本模块头文件全局变量全局外部变量程序内部静态变量函数原型外部函数原型内部函数原型主程序及内部函数2.1文件头说明不管是什么文件,包括.C,.CPP,.H,.uc等文件都应该有文件头,文件头必须列出:
版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。
如下所示:
/*Copyright(C),2004-2009,HongxuTech.Co.,Ltd.*Filename:
/文件名*Modulename:
模块名称*Author/Date:
/作者及完成日期*Version:
/版本*Description:
/用于详细说明此程序文件完成的主要功能,与其他模块或函数的接口,输出值、取值范围、含义及参数间的控制、顺序、独立或依赖等关系*Others:
/其它内容的说明-History-*Modifier/Date:
修订人及修订日期*ModifyReason:
修订原因*Modification:
修订的内容和位置的筒耍说明*Modifier/Date:
修订人及修订日期*ModifyReason:
修订原因*Modification:
修订的内容和位置的简要说明2.2头文件说明2.2.1条件编译在编译一个文件的时候,常会多次包含同一个文件,为了防止重复定义,应该采用条件编译,这里以demo,h为例说明:
#ifndef_DEMO_H#define_DEMO_H#endif符号常数的名称由前两个下划线以及文件名再加上_H组成(如上图例),文件名中所有字母皆应大写。
2.2.2头文件内容源程序文件(C,CPP,ASM)中若包含头文件,则首先应包含系统提供的头文件,再包含自定义的头文件。
原则上每一个软件模块至少定义一个头文件,引用这些头文件时使用相对路径。
2.3头文件布局示例/*Copyright(C),2004-2009,HongxuTech.Co.,Ltd.*Filename:
demo.h*Modulename:
demo*Author/Date:
tom/2009/03/28*Version:
1.0*Description:
示例头文件*Others:
*Modifier/Date:
tom/2009/03/28*ModifyReason:
creat*Modification:
*/#ifndefDEMO_H#define_DEMO_H/如果这是子系统头文件的话可在此包含子系统各模块公用的头文件不是的话建议不在此包含其他头文件*/*公共头文件*/#include#include#include#include/*调度系统头文件*/#includecps.h/*调试打印头文件*/#includendebug.hn#includentrace.h/*模式匹配头文件*/#includenmatching.hn#includeurule_matching.hn/*测试开关宏定义*/#defineTEMPORARY_TEST1/*类型定义*/typedefunsignedcharBITS;typedefunsignedlongDWORD;typedefunsignedshortWORD;typedefunsignedcharBYTE;typedefunsignedcharBOOLEAN;#defineFLOATfloat#defineINT8char#defineINT16short#defineINT32int#defineUINT8unsignedchar#defineUINT16unsignedshort#defineUINT32unsignedint#defineUINT64unsignedlonglong#defineVOIDvoid#defineSTATICstatic#defineEXTERNextern/*常量定义*/#define_LINUX_1#defineTRUE1#defineFALSE0#defineTEST_STRINGjustfortest”/*其他宏定义*/#defineMEMBER_OFFSET(structure,member)(int)&(structure*)0)-member)/*联合、枚举等定义*/typedefenum(FullFlag_UnFull=0,FullFlag_FullzFullFlag_Type;/*结构体定义*/*结构体定义建议采用统一的字节对齐方式*/typedefstruct_ccToDRStat_UINT8useFlag;INT32connectFd;UINT32boardip;UINT32dataflow;UINT8flowError;UINT8timeOfFlowError;UINT8todySendFlowError;PACKEDccToDrStat_t;/*其他定义*/#endif2.4源文件布局示例/*Copyright(C),2004-2009,HongxuTech.Co.,Ltd.*Filename:
demo.c*Modulename:
demo*Author/Date:
tom/2009/03/28*Version:
1.0*Description:
示例源文件*Others:
.History.*Modifier/Date:
tom/2009/03/28*ModifyReason:
creat*Modification:
*/#ifdefHAVE_DEM0/*条件编译,开关一般放在make“le中*/*子系统公共头文件*/#includendemo_common.hn/*系统头文件*/#ifdef_LINUX_#includenpthread.hn#endif/*接口头文件*/#includendeino_interface.hn/*本模块头文件*/#includedemo.h”/*外部全局变量*/externUINT32g_demo_num;/*内部静态变量*/UINT16g_local_globle;/*外部函数*/externvoidipConversion(UINT8*deviceNamezINT32ip);externvoidfreeDrHttpWapData(dr_http_data_t*httpwapData);/*内部函数*/*主流程函数*/voidstartDrCcThread(void*);staticBOOLEANdrRcvMsg(INT32Fd);/*其他功能函数*/staticUINT32drObtainlp();/*Others:
*Function:
DrRecvMsgCtrl*Description:
收消息线程调度入口函数*Input:
state,当前线程模块的工作状态*event,消息类新pid,当前线程模块的线程id*data,接收到的消息指针*Output:
N/A*Return:
N/AHistory-*No.:
*Modifier/Date:
*ModifyReason:
*Modification:
0tom/2009/03/28creat*/voidDrRecvMsgCtrl(intstate,intevent,intpid,void*data.r#endif3命名规则根据开发平台的不同,在进行编码时,可以采用两套编码规范中的一种:
休斯编码规范、匈牙利记名法。
但是针对同一个产品只能够使用同一种编码规范。
另外如果开发的源代码是与商业代码或者操作系统源码紧耦合的,可以遵循该商业代码或者操作系统源码的命名规则。
以下分别对两种规范的命名规则进行基本的说明。
3.1匈牙利记名法3.1.1基本命名规则以下的编码规范以匈牙利记名法为基准进行说明,休斯编码规范与其有不同之处时将用红色字特别说明。
以下为基本的命名规则:
规则名字以小写字母的前缀开始,后面带若干英语单词或单词的缩写,每个单词的第一个字母为大写,其余为小写,如iArraylndex;规则3-1-2:
单词必须是有意义的,拒绝毫无意义的词如xxx,YYY2等;规则3-1-3:
名字的长度不宜过长,也不宜过短,一般为1016个字母为宜;规则3-1-4:
单词的字母数在5,6个以上时,可采用缩写,缩写的原则是保留第一个字母,然后省略中间的元音字母及某些无需发音的辅音字母如r等。
如将current缩写为crnt,将response缩写为rsp,将control缩写为Ctrl等。
3.1.2细则3.1.2.1函数命名规则规则3-1-5:
函数名采用大小写隔开”方式。
规则3-1-6:
函数命名形式为:
模块名+有意义的名字(或缩写)(注:
最好为动宾结构或状态/事件格式)。
即函数名需具备自我解释的功能。
规则3-1-7:
函数名字符串首字符不大写,其中如有缩写,仅大写缩写的首字符。
规则3-1-8:
对提供给大部分模块用的一些公用函数,不在以上规定中,可全部用大写。
示例:
gtpProcessMsgFromSgsn(.);gtpBuildCreatePdpContext();3.1.2.2变量命名规则规则3-1-9:
变量的命名规范采用“大写隔开”的方式,不要使用大写隔开与下划线混排的方式。
规则3-1-10:
变量名字符串首字符不大写,其中如有缩写,仅大写缩写的首字符。
示例:
UINT32teidu;UINT32packFiltld;规则3-1-11:
对于变量命名,禁止取单个字符(如i、j、k.),但i、j、k作局部循环变量是允许的。
示例:
INT16count表示带符号短整型的计数器变量,该变量是局部变量。
规则3-1-12:
局部变量(包括函数参数)的前缀按照变量的类型来定。
常用变量类型的前缀定义如下表所示:
类型前缀指针前缀BITSbtBOOLblcharcpcBYTEbPbWORDwpwDWORDdwpdwINTnpnVOIDVpvENUMenpenSTRUCTtptLONG1pl举例如下:
BOOLblRst;charclnput;BYTEbState,pbState;WORDwEvent,pwEvent;DWORDdwTimerld;mFuncRet_TtFuncRet,ptFuncRet;规则3-1-13:
为保证可移植性,使用经过封装的基本数据类型。
数组类型前缀+a,如ba句柄h文件指针fp说明:
基本类型如下表类型说明UINT8,UINT16,UINT32无符号8位,16位,32位整型INT8,INT16,INT32带符号8位,16位,32位整型示例:
/*defineacountervariblerangesbetween0and255*/UINT8count;规则3-1-14:
全局变量采用“模块名缩写+有意义的名字(或缩写)”。
3.1.2.3结构,宏命名规则规则3-1-15:
自定义类型命名规则如下表:
构造类型命名方式举例结构体有意义的名字(或缩写)+_tpack_filt_t联合体有意义的名字(或缩写)+_ucall_app_u枚举类有意义的名字(或缩写)+_eform_e示例:
/*thekeywordstructmustfollowsacustomized*/typedefstruct_packFilt_t/*namewiththeprefix_*/UINT32teidu;UINT32packFiltld;struct_packFilt_t*pNext;struct_packFilt_t*pPre;packFilt_t;packFilt_tpackFilt;packFilt_t*pPackFilt;3.2休斯编码规范3.2.1基本命名规则以下的编码规范以匈牙利记名法为基准进行说明,休斯编码规范与其有不同之处时将用红色字特别说明。
以下为基本的命名规则:
规则3-2-1:
名字以小写以及下划线隔开的方式,如i_array_index;规则3-2-2:
单词必须是有意义的,拒绝毫无意义的词如xxx,YYY2等;规则3-2-3:
名字的长度不宜过长,也不宜过短,一般为1016个字母为宜;规则3-2-4:
单词的字母数在5,6个以上时,可采用缩写,缩写的原则是保留第一个字母,然后省略中间的元音字母及某些无需发音的辅音字母如r等。
如将current缩写为crnt,将response缩写为rsp,将control缩写为Ctrl等。
3.2.2细则3.2.2.1函数命名规则规则3-2-5:
函数名采用“大小写隔开”方式。
规则3-2-6:
函数命名形式为:
模块名+有意义的名字(或缩写)(注:
最好为动宾结构或状态/事件格式)。
规则3-2-7:
函数名字符串首字符不大写,其中如有缩写,仅大写缩写的首字符。
规则3-2-8:
对提供给大部分模块用的一些公用函数,不在以上规定中,可全部用大写。
示例:
gtpProcessMsgFromSgsn(.);gtpBuildCreatePdpContext(.);3.2.2.2变量命名规则规则3-2-9:
变量的命名规范采用小写加下划线的方式。
举例:
U8pack_filt_id规则3-2-10:
变量名字符串首字符不大写,其中如有缩写,仅大写缩写的首字符。
示例:
U32teidu;U32packFiltld;规则3-2-11:
对于变量命名,禁止取单个字符(如i、j、k.),但i、j、k作局部循环变量是允许的。
示例:
INT16count表示带符号短整型的计数器变量,该变量是局部变量。
规则3-2-12:
局部变量(包括函数参数)的前缀按照变量的类型来定。
常用变量类型的前缀定义如下表所示:
举例如下:
BOOLbIRst;charclnput;BYTEbState,pbState;WORDwEvent,pwEvent;DWORDdwTimerld;mFuncRet_TtFuncRet,ptFuncRet;类型前缀指针前缀BITSbtBOOLblcharcpcBYTEbPbWORDwpwDWORDdwpdwINTnpnVOIDVPVENUMenpenSTRUCTtptLONG1pl数组类型前缀+a,如ba句柄h文件指针fp规则3-2-13:
为保证可移植性,使用经过封装的基本数据类型。
说明:
基本类型如下表类型说明U8,U16,U32无符号8位,16位,32位整型INT8,INT16,INT32带符号8位,16位,32位整型示例:
/*defineacountervariblerangesbetween0and255*/U8count;规则3-2-14:
全局变量采用“模块名缩写+有意义的名字(或缩写)示例:
INT32g_modulename_mailnum;3.2.2.3结构,宏命名规则规则3-2-15:
自定义类型命名采用下划线分割单词。
规则为:
有意义的名字(或缩写)+_t/*thekeywordstructmustfollowsacustomized7typedefstructj3ack_filt_t(/*namewiththeprefix_7UINT32teidu;UINT32pack_filt_id;struct_pack_filt_t*p_next;struct_pack_filt_t*p_pre;pack_filt_t;pack_filt_tpack_filt;pack_filt_t*pj3ack_filt;4函数4.1函数的设计4.1.1规则规则4-1-1:
一个函数仅完成一件功能。
规则4-1-2:
明确函数功能,精确(而不是近似)地实现函数设计。
规则4-1-3:
不要设计多用途面面俱到的函数。
说明:
多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。
规则4-1-4:
设计高扇入、合理扇出(小于7)的函数。
说明:
扇出是指一个函数直接调用(控制)其它函数的数目,而扇入是指有多少上级函数调用它。
扇出过大,表明函数过分复杂,需要控制和协调过多的下级函数;而扇出过小,如总是1,表明函数的调用层次可能过多,这样不利程序阅读和函数结构的分析,并且程序运行时会对系统资源如堆栈空间等造成压力。
函数较合理的扇出(调度函数除外)通常是3-5。
扇出太大,一般是由于缺乏中间层次,可适当增加中间层次的函数。
扇出太小,可把下级函数进一步分解多个函数,或合并到上级函数中。
当然分解或合并函数时,不能改变要实现的功能,也不能违背函数间的独立性。
扇入越大,表明使用此函数的上级函数越多,这样的函数使用效率高,但不能违背函数间的独立性而单纯地追求高扇入。
公共模块中的函数及底层函数应该有较高的扇入。
较良好的软件结构通常是顶层函数的扇出较高,中层函数的扇出较少,而底层函数则扇入到公共模块中。
4.1.2建议建议4-1-1:
函数的规模尽量限制在300行以内。
说明:
不包括注释和空格行。
建议4-1-2:
为简单功能编写函数。
说明:
虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。
示例:
如下语句的功能不很明显。
value=(ab)?
a:
b;改为如下就很清晰了。
INT32max(INT32a,INT32b)return(ab)?
a:
b);value=max(a,b);或改为如下。
#defineMAX(a,b)(a)(b)?
(a):
(b)value=MAX(a,b);建议4-1-3:
改进模块中函数的结构,降低函数间的耦合度,并提高函数的独立性以及代码可读性、效率和可维护性。
优化函数结构时,要遵守以下原则:
(1)不能影响模块功能的实现。
(2)仔细考查模块或函数出错处理及模块的性能要求并进行完善。
(3)通过分解或合并函数来改进软件结构。
(4)考查函数的规模,过大的要进行分解。
(5)降低函数间接口的复杂度。
(6)不同层次的函数调用要有较合理的扇入、扇出。
(7)函数功能应可预测。
(8)提高函数内聚。
(单一功能的函数内聚最高)说明:
对初步划分后的函数结构应进行改进、优化,使之更为合理。
4.2函数参数4.2.1规则规则4-2-1:
函数参数不应过多,不得超过8个,否则应当考虑函数功能的压缩。
说明:
目的减少函数间接口的复杂度。
规则4-2-2:
接口函数本身要对接口函数参数的合法性进行检查。
说明:
对于模块间接口函数的参数的合法性检查这一问题,往往有两个极端现象,即:
要么是调用者和被调用者对参数均不作合法性检查,结果就遗漏了合法性检查这一必要的处理过程,造成问题隐患;要么就是调用者和被调用者均对参数进行合法性检查,这种情况虽不会造成问题,但产生了冗余代码,降低了效率。
我们规定,对接口函数入11参数的介法性检育及错识保护由函数自身完成。
规则4-2-3:
防止将函数的参数作为工作变量。
说明:
将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。
对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
小例:
以下函数的实现不太好。
voidsumData(INT32num,INT32INT32count;*pSum=0;*pData,INT32*pSum)for(count=0;countnum;(count+)*pSum+=pDatacount;/pSum成了工作变量,不太好。
若改为如下,则更好些。
voidsumData(INT32num,INT32(INT32count;INT32sumTemp;sumTemp=0;*pData,INT32*pSum)for(count=0;cou
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 编码 规范