C&C++ 源代码书写规范-软件编写规范.docx

上传人:李司机 文档编号:1804667 上传时间:2022-12-19 格式:DOCX 页数:60 大小:283KB
返回 下载 相关 举报
C&C++ 源代码书写规范-软件编写规范.docx_第1页
第1页 / 共60页
C&C++ 源代码书写规范-软件编写规范.docx_第2页
第2页 / 共60页
C&C++ 源代码书写规范-软件编写规范.docx_第3页
第3页 / 共60页
C&C++ 源代码书写规范-软件编写规范.docx_第4页
第4页 / 共60页
C&C++ 源代码书写规范-软件编写规范.docx_第5页
第5页 / 共60页
点击查看更多>>
资源描述

《C&C++ 源代码书写规范-软件编写规范.docx》由会员分享,可在线阅读,更多相关《C&C++ 源代码书写规范-软件编写规范.docx(60页珍藏版)》请在三一办公上搜索。

1、版本号:TDCQC/C+源代码及其文档书写规范TDCQ公司20XX年05月目录1前言-1-2 DNC前缀和名空间-1-2.1 C代码使用DNC做前缀-1-2.2 C+代码使用DNC做名空间-1-3 C/C+源代码注释及书写规范-2-3.1 C/C+源代码注释-2-3.1.1 总体注释要求-3-3.1.2 说明性文件头部的注释-3-3.1.3 源文件头部的注释-4-3.1.4 函数头部的注释-5-3.1.5 对于if、whi1.e、do等其大括号内嵌代码块的注释-5-3.1.6 某个代码段的注释-6-3.1.7 注释的位置-6-3.1.8 对于所有物理含义的变量、常量及宏的注释-7-3.1.9

2、数据结构声明(包括数组、结构、类、枚举等)的注释-7-3.1.10 全局变量的注释-7-3.1.11 注释与所描述内容缩进的要求-8-3. 2C/C+源代码注释书写与帮助文档的自动生成-8-3.1.1 块注释-8-3.1.2 行注释-9-3.1.3 函数的摘要-9-3.1.4 函数的形参-9-3.1.5 函数的返回值-9-3.1.6 函数的注意事项(Remark)-10-3.1.7 补充说明-10-3.3C/C+代码书写规范-10-3.3.1 每行代码长度-10-3.3.2 口j丁JI可.-I1.-3.3.3 指针中*号的位置-11-3.3.4 全局函数的调用-12-3.3.5 关于if.e1

3、.seif.-12-3.3.6 与有关的规定-12-3.3.6.1 与有关代码的缩进格式-12-336.2的省略-12-3.3.7与空格有关的各项规定-13-3.3.7.1 对两目、三目运算符两边的空格的规定-13-3.3.7.2 3,7.2对for、Whi1.e、if等关键字之后空格的规定-13-3.3.7.3 对调用函数、宏时的空格规定-13-3.3.7.4 对类型强制转换时的空格规定-14-338代码缩进/对齐使用空格的规定-14-338.1 代码缩进一个4个空格-14-338.2 代码不缩进情况-14-3.3.9 与类相关的.h文件与.cpp文件-15-1.1.1 .1类的定义与实现-

4、15-1.1.2 类的合并-15-3.3.10 对变量的要求-15-3.3.10.1 对变量的要求-15-3.3.10.2 对变量类型的要求-16-3.3.11 对结构的要求-16-3.3.11.1 结构的功能要单一-16-3.3.11.2 不同结构间的关系要简单-17-3.3.12 函数的编写要求-18-3.3.12.1 函数编写的总体要求-18-3.3.12.2 函数名的要求-19-3.3.12.3 函数参数的要求-19-3.3.12.4 函数功能的要求-20-3.3.12.5 可重入函数编写-21-3.3.13 C/C+程序效率的要求-22-3.3.14 C/C+代码质量的要求-23-3

5、.3.14.1 代码质量保证优先原则-23-3.3.14.2 对内存及句柄操作的要求-23-3.3.14.3 其他要求-25-3.3.15 C/C+代码测试与维护-26-4C/C+源代码程序命名规范-27-4.1 总体命名要求-27-4.2 具体命名规范-28-4.2.1 工程名-28-4.2.2 文件名-28-4.2.3 函数名-28-4.2.4 变量名-28-4.2.5 类名-29-4.2.6 结构、宏、枚举及联合的名字-29-4.2.7 具有互斥意义的变量或相反动作的函数的命名-29-4.2.8 对命名中下划线的使用规定-30-5程序开发中相关文档撰写规定-30-5.1 程序设计与开发文

6、档-30-5.1.1 软件的开发背景-30-5.1.2 软件的结构设计-30-5.1.3 数据及资源文件说明-31-5.1.3.1 数据用途-31-5.1.3.2 数据格式-31-5.1.4 程序结构设计与开发-31-5.2 程序使用文档-31-5.2.1 软件系统的程序组成-31-5.2.2 开发环境要求、软件安装及环境配置-31-5.2.3 软件系统的使用方法-34-5.3 程序测试文档-36-5.3.1 测试环境-37-5.3.2 软件测试项目和功能-37-5.3.3 软件测试数据及格式-37-5.3.4 软件测试过程-37-5.4 软件程序调试文档-37-6程序及文档备份-39-6.1

7、 源程序及其文档备份-39-6.2 第三方软件(开发包或源码)及其文档备份-39-7词语缩写表-39-7.1 词语缩写的总体要求-39-7.2 通用词缩写表-39-7.3 专业词缩写表-44-8中心代码实例-46-8.1 *.h的编写实例-46-8.2 *.CPP的编写实例-49-1前言本规范规定了cc+源代码及其相应文档的书写规范。制定本规范的目的是统一北航数字导航中心研发部的cc语言源代码的书写风格、注释内容和相应文档的撰写,以便于代码的阅读、维护、管理、修订及使用。从制定完成即日起,程序员在编写C/C+代码的时候,需要严格遵守制定的C/C+源代码及其文档书写规范。此外,利用其他语言(如V

8、B、DeIPhi和MaUab等)编写的程序的程序员同样要遵守本规范。2DNC前缀和名空间21.C代码使用DNC做前缀C代码的接口函数一律使用DNCigita1.NavigationCenter,数字导航中心英文缩写)做前缀。例如C语言代码在函数前加DNC.前缀即可,例intDNC_FunName();(return0;)2C+代码使用DNC做名空间C+代码使用DNC做名空间。具体示例如下/*.h文件namespaceDNC(c1.assCDncDemopub1.ic:CDncDemoO;-CDncDemoO;;)/*.cpp文件namespaceDNC(CDncDemo:CDncDemo()(

9、)CDncDemo:-CDncDemoO()在使用CDncDemo的文件中加入:usingnamespaceDNC;/然后定义对象CDncDemodncobj;或者直接DNC:CDncDemodncobj;3C/C+源代码注释及书写规范C/C+源代码注释除非极其简单,否则对函数应有注释说明。内容包括:功能、入口/出口参数,必要时还可有备注或补充说明。推荐采取特定的格式(见第3.2条),以方便用软件自动生成帮助文档。3.1.1 总体注释要求 一般情况下,源程序有效注释量必须在20%以上; 注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁

10、; 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性,不再有用的注释要删除; 注释的内容要清楚、明了,含义准确,防止注释二义性,错误的注释不但无益反而有害; 除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差; 避免在注释中使用缩写,特别是非常用缩写,在使用缩写时或之前,应对缩写进行必要的说明; 注释格式尽量统一,建议使用/*管 建议多使用中文,除非能用非常流利准确的英文表达。3.1.2 说明性文件头部的注释说明性文件(如头文件.h文件、.cc+文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、

11、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。Copyright(C),2008-2022,DNCBUAAFi1.ename:/文件名Author:Version:Date:作者、版本及完成日期Others:Description:/用于详细说明此程序文件完成的主要功能,与其他模块或函数的接口,输出值、取值范围、含义及参数间的控/制、顺序、独立或依赖等关系其它内容的说明Function1.ist:/主要函数列表,每条记录应包括函数名及功能简要说明History:/修改历史记录列表

12、,每条修改记录应包括修改口期、修改者及修改内容简述1.Date:Author:Modification:2.3.1.3源文件头部的注释源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。示例:下面这段源文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。Copyright(C),2008-2022,DNCBUAAFi1.eName:test.cppAuthor:Version:Date:作者、版本及完成日期Description:/模块描述Version:版本信息Function1.ist:/主要函数及其功能1.His

13、tory:/历史修改记录David96/10/121.0bui1.dthismoud1.e说明:Description一项描述本文件的内容、功能、内部各部分之间的关系及本文件与其它文件关系等。History是修改历史记录列表,每条修改记录应包括修改日期、修改者及修改内容简述。3.1.4 函数头部的注释函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。示例:下面这段函数的注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。Function:函数名称Description:/函数功能、性能等的描述Ca1.1.s:/被本函数调用的函数清单Ca

14、1.1.edBy:/调用本函数的函数清单Tab1.eAccessed:/被访问的表(此项仅对于牵扯到数据库操作的程序)Tab1.eUpdated:/被修改的表(此项仅对于牵扯到数据库操作的程序)Input:/输入参数说明,包括每个参数的作/用、取值说明及参数间关系。Output:对输出参数的说明。Return:函数返回值的说明Others:其它说明3.1.5 对于if、whi1.e,do等其大括号内嵌代码块的注释比较长(需拖动滚动条来看)或者多层嵌套时,在结尾的“”后要加上其所对应的语句的注释说明。例1:if(.)(/programcodewhi1.e(indexMAXJNDEX)(/prog

15、ramcode*endofwhi1.e(indexMAX_INDEX)*/指明该条WhiIe语句结束*endofif(.)*/指明是哪条if语句结束例2:BOO1.DNC_SaveToFi1.e(constcharcszFi1.eName,BOO1.bCanRep1.ace*=TRUE*);3.1.6 某个代码段的注释描述某个代码段的注释,可以给注释描述的代码段外围加上,帮助阅读。例:/代码段实现功能或意图描述(代码段)3.1.7 注释的位置注释应与其描述的代码相近,对代码的注释应放在其上方或右方相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。示例:如下例子不符合规范。例1:*

16、getrep1.icatesubsystemindexandnetindicator*/repssn_ind=ssn_dataindex.repssn-index;repssn_ni=ssn_dataindex.ni;例2:repssn_ind=ssn_dataindex.repssn_index;repssn_ni=ssn_dataindex.ni;*getrep1.icatesubsystemindexandnetindicator*/应如下书写*getrep1.icatesubsystemindexandnetindicator*/repssn_ind=ssn_dataindex.rep

17、ssn-index;repssn_ni=ssn_dataindex.ni;1.1.1 于所有物理含义的变量、常量及宏的注释对于所有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其物理含义。变量、常量、宏的注释应放在其上方相邻位置或右方。*activestatistictasknumber*/#defineMAX_ACT_TASK_NUMBERIOOO#defineMAX_ACT_TASK_NUMBER1000*activestatistictasknumber*/1.1.9 数据结构声明(包括数组、结构、类、枚举等)的注释数据结构声明(包括数组、结构、类、枚举等

18、),如果其命名不是充分自注释的,必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。示例:可按如下形式说明枚举/数据/联合结构。*seepinterfacewithseepuserprimitivemessagename*/enumDNC_USER_PR1MITIVE(N_UNITDATAJND;*C1.nCnotifydncUSerunitdatacome*/N_NOTICE_IND;*dncnotifyusertheNo.7networkcannot*/*transmissionthismessage*/N_UNITDATA_REQ;*d

19、ncusersunitdatatransmissionrequest*/);1.1.10 全局变量的注释全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。示例:*TheErrorCodewhenDNCtrans1.ate*/*G1.oba1.Tit1.efai1.ure,asfo1.1.ows*/变量作用、含义*0-SUCCESS1-GTTab1.eerror*/*2GTerrorOthers-nouse*/变量取值范围*on1.yfunctionDNC-Trans1.ate()in*/*thismodua1.canmodifyit,andoth

20、er*/*modu1.ecanvisititthroughca1.1.*/*thefunctionDNC-GetGTTransErrorCodeO*/使用方法BYTEg_GTTranErrorCode;1.1.11 注释与所描述内容缩进的要求注释与所描述内容进行同样的缩排,做到程序排版整齐,并方便注释的阅读与理解。例如voidDNC-Examp1.eFun(void)(*codeonecomments*/CodeB1.ockOne*codetwocomments*/CodeB1.ockTwo)3.2 CC+源代码注释书写与帮助文档的自动生成本节规定的C/C+源代码注释书写规范主要是利用DOXy

21、gen工具自动生成帮助文档。对于那些不希望提取为帮助文档的注释,请参照本规范的3.1节。3.2.1 块注释格式开头:/*结尾:*/例:*.Thisisab1.ockcomment.*/3.2.2 行注释格式开头:/例:/Thisisa1.inecomment.323函数的摘要格式在函数声明主体开头的注释块中加上控制符:brief例:/*brief用于从输入流读取一个字符,不回显*/intgetch(void);3.2.4 函数的形参格式在函数声明主体开头的注释块中加上控制符:param例:/* parambuf1.缓冲区1* ParambUf2缓冲区2* paramcount字符的个数*/*

22、ntmemcmp(constvoid*buf1.,constvoid*buf2,size_tcount);3.2.5 函数的返回值格式在函数声明主体开头的注释块中加上控制符:return例1:/* return读取的字符*/intgetchar(void);例2:/* returnNone*/voidrewind(FI1.E*stream);3.2.6 函数的注意事项(Remark)格式在函数声明主体开头的注释块中加上控制符:remark例:/*remark拷贝StrSoUrCe至IJStrDeStination(包含StrSOUrCe中的0),要注意在拷贝的过程中并没有溢出检查*/char*

23、strcpy(char*strDestination,constchar*strSource);3.2.7 补充说明更多的格式请参考Doxygen文档,因为有些高级的选项比较繁琐。编写注释的目的是为了方便自动生成文档,而在此基础上又不能使程序员过于分散精力。DOXygen的文档自动生成功能非常强大,很多事情都不需要手工干预,我们只要用到最基本的几项功能也可以满足需求了。3.3 C/C+代码书写规范3.3.1 每行代码长度每行代码的长度推荐为80个ASCi1.字符,最长不得超过120;折行以对齐为准。例:HAND1.EDNC_OpenFi1.e(constcharcszFi1.eName,int

24、nMode);或者:BOO1.DNC_ReadFi1.e(HAND1.EhFi1.e,void*pvBuffer,intnReadSize,int*pnReadSize);3.3.2 合并行的问题循环、分支代码,判断条件与执行代码不得在同一行上。例:正确:if(n=-2)n=1.;e1.sen=2;不得写做:If(n=-2)n=1;e1.sen=2;333指针中*号的位置指针的定义,*号既可以紧接类型,也可以在变量名之前。例:可写做:int*pnsize;统一使用这种格式也可写做:int*pnsize;但不得写做:int*pnsize;3.3.4 全局函数的调用在类的成员函数内调用全局函数时,

25、在全局函数名前必须加上3.3.5 关于if.e1.seife1.seif必须写在一行。3.3.6 与有关的规定33.6.1与“”、“产有关代码的缩进格式在“厂之前不允许有除空格与Tab之外的其他任何字符;在它之后可有注释,但不允许有代码。与“”对应的“”必须在同一列上。例:正确:for(i=0;icb1.ine;i+)/printf(1.ine%d:H,i);printf(%sn,pFi1.e1.inesi);)不得写做:for(i=0;icb;i+)printf(1.ine%d:n,i);printf(%sn,pFi1.e1.inesi);)也不得写做:for(i=0;icb;i+)prin

26、tf(1.ine%d:,i);printf(,%sn,pFi1.e1.inesi);)33.6.2“、“”的省略在循环、分支之后若只有一行代码,在无歧义的情况下可省略例:if(n=-2)n=1.;e1.sen=2;3.3.7与空格有关的各项规定337.1对两目、三目运算符两边的空格的规定在所有两目、三目运算符的两边都必须有空格。在单目运算符两端不必空格。但在”等运算符前后,及(取地址)、(取值)等运算符之后不得有空格。例:正确:intn=O,nTemp;for(inti=nMin1.ine;i=nMax1.ine;i+)不得写做:intn=0,nTemp;for(inti=nMin1.ine;

27、iif等关键字之后空格的规定for、whi1.eif等关键字之后应有1个空格,再接例:正确:if(-2=n)不得写做:if(-2=n)33.7.3 对调用函数、宏时的空格规定调用函数、宏时,“(”前不得有空格。例:正确:prin1.f(,%dn,n1.ndex);不得写做:printf(%dnn1.ndex);33.7.4 对类型强制转换时的空格规定类型强制转换时,前后不得有空格例:可写做:(DNC-Fi1.e*)pFi1.e;也可写做:(DNc1.FiIe*)pFi1.e不得写做:(DNC.Fi1.e*)pFi1.e(DNC-Fi1.e*)pFi1.e33.7.5 码缩进/对齐使用空格的规定

28、为避免用不同的编辑器阅读程序时,因TAB键所设置的空格数目不同而造成程序布局不整齐,不要使用BC作为编辑器合版本,因为BC会自动将8个空格变为一个TAB键,因此使用BC合入的版本大多会将缩进变乱。33.7.5.1 码缩进一个4个空格(1)函数体相对函数名及例:intpower(intx)(return(x*x);)(2) if、e1.se、for、whi1.e、do等之后的代码一行之内写不下,折行之后的代码,应在合理的位置进行折行。若有+*/等运算符,则运算符应在上一行末尾,而不应在下一行的行首。33.8.2 代码不缩进情况switch之后的casedefau1.代码不缩进。例:switch(

29、n1.D)caseID_P1.AY:break;caseID_STOP:break;defau1.t:break;)33.8.3 类相关的.h文件与.cpp文件33.8.3.1 的定义与实现原则上,应该在一个单独的.h文件中定义一个类,在一个单独的.cpp文件中实现这个类。.h与.cpp文件的文件名必须与类名相同。33.9.2类的合并若几个类的规模都不大,关系又很密切,则可在一个.h文件中定义这些类,在一个.cpp文件中实现。对于附属于较大规模类的一个很小规模的类,可以写在那个大规模类的.h和.cpp里。33.8.4 对变量的要求33.8.4.1 对变量的要求 公共变量是增大模块间耦合的原因之

30、一,故应减少没必要的公共变量以降低模块间的耦合度; 在对变量声明的同时,应对其含义、作用及取值范围进行注释说明,同时若有必要还应说明与其它变量的关系; 对公共变量赋值时,若有必要应进行合法性检查,以提高代码的可靠性、稳定性; 防止局部变量与公共变量同名; 构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象; 严禁使用未经初始化的变量作为右值; 使用严格形式定义的、可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量; 明确过程操作变量的关系后,将有利于程序的进一步优化、单元测试、系统联调以及代码维护等

31、。这种关系的说明可在注释或文档中描述。示例:在源文件中,可按如下注释形式说明。RE1.ATIONSystem-InitInput-RecPrint-RecStat_ScoreStudentCreateModifyAccessAccessScoreCreateModifyAccessAccess,Modify注:RE1.ATION为操作关系;SyStemnit、Input_RecPrint_RecStat_Score为四个不同的函数;Student、Score为两个全局变量;Create表示创建,Modify表示修改,Access表示访问。其中,函数Input_RecStacScore都可修改变

32、量Score,故此变量将引起函数间较大的耦合,并可能增加代码测试、维护的难度。33.8.4.2 对变量类型的要求 留心具体语言及编译器处理不同数据类型的原则及有关细节,如在C语言中,static局部变量将在内存“数据区”中生成,而非static局部变量将在“堆栈”中生成。这些细节对程序质量的保证非常重要; 要注意数据类型的强制转换,当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患; 尽量减少没有必要的数据类型默认转换与强制转换; 合理地设计数据并使用自定义数据类型,避免数据间进行不必要的类型转换; 对编译系统默认的数据类型转换,也

33、要有充分的认识。33.8.5 对结构的要求33.8.5.1 结构的功能要单一设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。示例:如下结构不太清晰、合理。typedefstructSTUDENT.STRU(unsignedcharname8;*studentsname*/unsignedcharage;*studentsage*/unsignedcharsex;*studentssex,asfo1.1.ows*/*0-FEMA1.E;1-MA1.E*/unsignedchar

34、teacher-name8;*thestudentteachersname*/unisgnedcharteacher_sex;*histeachersex*/)STUDENT;若改为如下,可能更合理些。typedefstructTEACHER_STRU(unsignedcharname8;*teachername*/unisgnedcharsex;*teachersex,asfo1.1.ows*/*0-FEMA1.E;1-MA1.E*/TEACHER;typedefstructSTUDENT_STRU(unsignedcharname8;*studentsname*/unsignedchara

35、ge;*studentsage*/unsignedcharsex;*studentssex,asfo1.1.ows*/*0-FEMA1.E;1-MA1.E*/unsignedintteacherjnd;*histeacherindex*/STUDENT;33.8.5.2 不同结构间的关系要简单若两个结构间关系较复杂、密切,那么应合为一个结构。示例:如下两个结构的构造不合理。IypedefstructPERSON_ONE_STRU(unsignedcharname8;unsignedcharaddr40;unsignedcharsex;unsignedcharcity15;PERSON_ONE;

36、IypedefstructPERSON_TWO_STRU(unsignedcharname8;unsignedcharage;unsignedcharte1.;PERSON_TWO;由于两个结构都是描述同一事物的,那么不如合成一个结构。typedefstructPERSON_STRU(unsignedcharname8;unsignedcharage;unsignedcharsex;unsignedcharaddr401;unsignedcharcity1.5;unsignedcharte1.;PERSON;33.8.6 函数的编写要求33.8.6.1 函数编写的总体要求 明确函数功能,精确(

37、而不是近似)地实现函数设计; 函数的规模尽量限制在200行以内(不包括注释和空格行); 函数的返回值要清楚、明了,让使用者不容易忽视错误情况; 除非必要,最好不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方式作为返回值返回; 让函数在调用点显得易懂、容易理解,在调用函数填写参数时,应尽量减少没有必要的默认数据类型转换或强制数据类型转换。33.8.6.2 函数名的要求 函数名应准确描述函数的功能。 避免使用无意义或含义不清的动词为函数命名,如ProCeSs、hand1.e等为函数命名,因为这些动词并没有说明要具体做什么。 使用动宾词组为执行某操作的函数命名。如果是OoP方

38、法,可以只有动词(名词是对象本身)。示例:参照如下方式命名函数。voidDNC_PrintRecord(unsignedintrec_ind);intDNCJnputRecord(void);unsignedcharDNC_GetCurrentCo1.or(void);33.8.6.3 函数参数的要求 在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责。对于模块间接口函数的参数的合法性检查这一问题,往往有两个极端现象,即:要么是调用者和被调用者对参数均不作合法性检查,结果就遗漏了合法性检查这一必要的处理过程,造成问题隐患;要么就是

39、调用者和被调用者均对参数进行合法性检查,这种情况虽不会造成问题,但产生了冗余代码,降低了效率。 防止将函数的参数作为工作变量。将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。 避免设计多参数函数,不使用的参数从接口中去掉。示例:下函数的实现不太好。voidDNC_SumData(unsignedintnum,int*data,int*sum)unsignedintcount;*sum=0;for(count=0;countnum;count+)(*sum=datacount;/sum成了工作变量,不太好

40、。)若改为如下,则更好些。voidDNC_SumData(unsignedintnum,int*data,int*sum)(unsignedintcount;intsum_temp;sum_temp=0;for(count=0;countb)?a:b;改为如下就很清晰了。intmax(inta,intb)(return(ab)?a:b);)va1.ue=max(a,b); 不要设计多用途面面俱到的函数。多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。 函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出。3.3.12.5可重入函数编写编写可重入函数时,应注意局部

41、变量的使用(如编写C/C+语言的可重入函数时,应使用auto即缺省态局部变量或寄存器变量);编写C/C+语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)等手段对其加以保护;若对所使用的全局变量不加以保护,则此函数就不具有可重入性,即当多个进程调用此函数时,很有可能使有关全局变量变为不可知状态。示例:假设Exam是int型全局变量,函数Squre_Exam返回Exam平方值。那么如下函数不具有可重入性。unsignedintexamp1.e(intpara)(unsignedi

42、nttemp;Exam=para;/(*)temp=Square_Exam();returntemp;)此函数若被多个进程调用的话,其结果可能是未知的,因为当(*)语句刚执行完后,另外一个使用本函数的进程可能正好被激活,那么当新激活的进程执行到此函数时,将使EXam赋与另一个不同的Para值,所以当控制重新回到“temp=SquareExam(),JS,计算出的temp很可能不是预想中的结果。此函数应如下改进。unsignedintexamp1.e(intpara)unsignedinttemp;申请信号量操作若申请不到“信号量”,说明另外的进程正处于Exam=para;/给EXam赋值并计算

43、其平方过程中(即正在使用此temp=Square_Exam();/信号),本进程必须等待其释放信号后,才可继释放信号量操作1续执行。若申请到信号,则可继续执行,但其/它进程必须等待本进程释放信号量后,才能再使用本信号。returntemp;)3.3.13 C/C+程序效率的要求 编程时要经常注意代码的效率。代码效率分为全局效率、局部效率、时间效率及空间效率。全局效率是站在整个系统的角度上的系统效率;局部效率是站在模块或函数角度上的效率;时间效率是程序处理输入任务所需的时间长短;空间效率是程序所需内存空间,如机器代码空间大小、数据空间大小、栈空间大小等。 在保证软件系统的正确性、稳定性、可读性及可测性的前提下,提高代码效率。不能一味地追求代码效率,而对软件的正确性、稳定性、可读性及可测性造成影响。 局部效率应为全局效率服务,不能因为提高局部效率而对全局效率造成影响。 通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。这种方式是解决软件空间效率的根本办法。 仔细分析有关算法,并进行优化。 仔细考查、分析系统及模块处理输入(如事务、消息等)的方式,并加以改进。 对模块中函数的划分及组织方式

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号