您好,欢迎访问三七文档
C/C++编程规范第1页1前言按照软件工程方法论,程序是软件设计的自然结果,程序的质量基本取决于设计本身的质量。但是,编写程序的好坏也在很大程度上决定着程序的质量。本编程规定是建立在ANSIC语言和StructuredProgramming规范的基础之上的,StructuredProgramming的目标是遵循“KISS”原则:KeepItSimple&Stupidfor:EASYTOREAD、EASYTODEBUG、EASYTOMAINTAIN。这里强调结构化的编程规范是因为目前公司自身和公司所面向的客户都在采用过程化的编程语言C/ESQLC,因此公司的绝大多数产品需要考虑对C/ESQLC的支持,这一点在今后很长的一段时间内都要坚持贯彻。1.1原则尽量使用标准的公用子程序执行既定的程序功能,禁止自行重复编写公司公用库函数中已有的处理或函数。程序的清晰首先在于逻辑的清晰,然后才是格式的清晰。应该利用适当的阶梯形式使程序的层次结构清晰明显。尽量采用简单的算法和数据结构,由于程序的复杂度往往直接依赖于算法和数据结构的复杂度,所以,在对程序的执行效率没有决定性影响的前提下,应尽量考虑选用简单的算法和数据结构。不要为了时空效率而牺牲清晰性。避免滥用语言特色----程序应简洁、易读、好懂。应尽可能的多加注释,以帮助理解每段程序的作用。不要用注解去精确地重复代码----使注释有价值。使用有意义的、简化的变量名及词语标号。严格控制非限制性转移语句“GOTO”的使用,除非:当不使用时将会模糊而不是澄清功能;在同一程序单元内正向转移。清晰随着简洁而来,不要简单认为起一个长的名字就能够增强程序的可读性,在很多时候更会起到误导和影响效率的作用。“好的程序犹如华美的诗句“,写出“诗句”一样的程序的捷径就是模仿,因此请严格按照规范和模版的要求编写您的每一行代码。1.2适用范围本规范适用于成都润信公司采用C/C++进行开发的所有软件产品和应用系统在各产品(应用系统)的开发过程中,如果出现与本规范相抵触(或需要对本规范进行扩展时),必须先编制出该产品(应用系统)的编程规范,并报质控部经理和产品研发部经理备案,经批准后方能执行。对于自动构造代码的某些辅助设计工具或者是集成开发环境(如ROSE和VisiualStdio),C/C++编程规范第2页可以不受本规范的限制,但其命名和自编代码部分必须依照本规范执行。1.3执行时间本规范自2002年1月1日起正式实施,凡在2002年1月1日后开始发起的项目都必须严格遵守本规范。1.4罚则凡是与本规范精神相抵触的编程规范,一律视为不合规范。检验人员有权要求作者按照规范要求重新编写,如果因重新编写导致项目延误或者其他的后果,责任由作者承担,在重新编写代码期间,原作者必须承担正常的工作分配。如果作者不服从重新编写的要求,公司有权对该作者处以行政上和经济上的处罚,情节严重者,视为严重违纪公司有权将其开除。本规范的解释权属于成都润信科技发展有限公司产品研发部。1.5引用资料《程序设计实践》BrianW.Kernighan和RobPike《UNIX下的编程规范》陈学聪1.6建议读物《程序设计实践》BrianW.Kernighan和RobPike《风格的要素》Struck和White《写可靠的代码》SteveMaguireC/C++编程规范第3页2风格2.1总的原则好的程序应该具备好的风格,一般而言,好的风格具备以下特征以缩行的形式显示程序结构使用表达式的自然形式采用扩号排除歧义分解复杂的表达式清晰、简洁使用一致的缩行和加扩号风格避免使用函数宏把数定义为常数而不是宏(避免预编译器的差异和处理错误)2.2以缩行的形式显示程序结构在程序中,如果本行与上一行在逻辑上有递进关系(如if、while等),则本行应比上行缩进一个TAB键位置,一般TAB键的宽度以4个空格自符为佳。花扩号应该出现在if的下一行而不是在同一行。以下为显示不明的缩进方式:if(FEB==lMonth){if(0==lYear%4)if(29lDay)llegal=FALSE;elseif(28lDay)lLegal=FALSE;}正确的缩进处理方式如下:if(FEB==lMonth){if(0==lYear%4){if(29lDay)llegal=FALSE;}else{if(28lDay)lLegal=FALSE;}}分支是程序设计中常常面临的问题,在采用if/else语句来处理分支时,经常会出现在缩进后留给编写代码的行宽不够,这时可以采用switch/case语句来处理分支,使用switch时必C/C++编程规范第4页须处理缺省的情况。switch(lFlag){case1:case2:...default:}2.3使用表达式的自然形式好的表达式书写你能大声念出来,含有否定运算条件的表达式比较难以理解,例如:if(!(0i)||!(0k){......}可以表述为下面的肯定句式更容易让人理解。if(0=i||0=k){......}此外,在刚才的程序片断中,都有意将常数放在了比较式的左边,这样写的出发点在于避免将逻辑判断语句误写为符值语句,这在“==”这种逻辑判断式中特别有意义,虽然将顺序导致可能会给程序员的习惯带来一定的问题,但坚持下来就会得到回报。2.4采用扩号排除歧义扩号表示分组,即使没有必要,有时候加上扩号也能把意图表现的更清楚,尤其是在混合使用相互无关的运算符时,多加几个扩号是个好主意,它可以很好的避免二义性。C语言及与之相关的语言都存在着险恶的运算优先级问题,很容易让人犯错误。例如:if((fp=fopen(“test.dat”,“r”))==NULL)对于C语言还不是很熟练、甚至是熟练但对算符优先顺序不是非常清楚的程序言而言,多加扩号是避免工作中出现焦头烂额查找错误的非常有效的手段。2.5分解复杂的表达式C和C++都有丰富的表示式结构和丰富的运算符,因此在这些语言中很容易将一大堆东西塞进一个结构中,下面的表达式虽然紧凑,但难以被理解:x+=(*xp=(2*k(n–m)?c[k+1]:d[k--]));将上述表达式分解后,要容易理解得多if(2*kn–m)*xp=c[k+1];else*xp=d[k—];*x+=*xp;C/C++编程规范第5页2.6清晰、简洁程序应报持清晰、简洁的风格,对于程序中确定无用的注释代码,应坚决予以删除,程序的版本管理和版本对照应基于工具而不是在程序中增加越来越多的垃圾来体现,今后所有的项目一律采用VSS来管理源代码。编程人员往往喜欢追求一种速度或者是复杂度的感觉,将代码写地非常复杂,将自己无穷尽的创造力用到了编写最简短的代码或者用在寻求得到结果的最巧妙的方法上,以此表示水平或者是功力,有时候这种技能是用错了地方或者说是根本不该用。程序之美出了正确的实现功能外,首推的就是清晰、易读,流水账这种在文学上被视为极度失败的叙事方式在软件编程过程中恰好是最美的一种叙述。要想到你作品的读者往往处于迫于时间的压力急于解决问题,而不是以欣赏的姿态在读,因此不要在程序中故弄玄虚。下面是一个难懂的表达式,在编写者言可能觉得很有深度:lValue=lValue(lCompare–((lCompare3)3));实际上也有更为简单的等价表达式:lValue=lValue(lCompare&0x7);2.7关于宏2.7.1避免使用函数宏函数宏本身与C++中的内联函数具有同样的作用,程序员往往采用它提高效率。其常见的严重问题在于:如果一个参数在定义中出现多次,它就可能被多次求值,从而产生难以捉摸的错误,下面的例子说明了这一问题:#defineisupper(c)(‘A’=(c)&&‘Z’=(c))while(isupper(c=getchar()))上述函数宏和语句运行的结果导致每次读入一个大于’A’的字符时将丢掉该字符,重新读入下一个字符。2.7.2给宏的体和参数都加上扩号如果一定要使用函数宏,需要特别小心,宏时通过文本替换方式实现的:定义体里的参数被调用的实际参数替换,得到的结果再作为文本替换原来的调用段,例如:#defineSQUARE(a)a*aSQUARE(2);等同于2*2SQUARE(3+2);等同于3+2*3+2;2.7.3把数定义为常数而不是宏C程序员的传统方式是用#define行来对付各种常数数值,C语言预处理程序是一个强有力的工具,但是它又有些鲁莽。使用宏进行编程是很危险的方式,因为宏会在背地里改变程序的词法结构。可以考虑采用枚举类型和const方式来申明常数。例如:emum{MINROW=1,C/C++编程规范第6页MAXROW=2};或者是:constintMINROW=1,MAXROW=2;2.8程序书写2.8.1变量定义C++允许在程序的处理过程中定义变量,而在传统的过程化处理语言(C)中,变量只有在函数的头部进行定义,你对下面这一段变量定义有何感想?longvl_Ret,vl_IasID,vl_Len,vl_Size,vl_Temp,i;longvl_pid;charvs_Date[9],vs_Time[7],vs_Dt[15],vs_Temp[129];charvs_WorkKey[33],vs_Hashasc[129],vs_MacData[129];charvs_AppID[20],vs_KeyVer[20];char*vs_InData,vs_SKey[2048],vs_pid[20];BYTEvs_Hash[41],vs_InKey[33];BYTE*vs_Data,vs_TempKey[33];structSessionKeyvt_SKey;structRunConfvt_RunConf;longvl_EncType,vl_Flag,vl_TransID,vl_SubTrans,vl_BranchID;longvl_HostID,vl_OpID,vl_KeyType;charvs_Domain[61],vs_Service[61];这是摘录的一段真实的程序,我怀疑看了变量定义后还能够继续看下去的人能够有多少,变量的定义应遵循以下原则:变量类型的排列从简单到复杂,在定义变量的过程中,应本着先定义简单变量、在定义复杂变量的原则进行,自上而下排列。相同的变量类型应放在一起。临时性得变量应尽可能考虑重用,不要动辙定义一堆的变量变量太多时(超过10个),应考虑加上注释,毕竟变量是程序中不可或缺的一部分。2.8.2断行你是否曾经写过类似于下面风格的代码:fprintf(fp,“%d%d%d%d%d%d”,lYear,lMonth,lDay,lHour,lMinutes,lSecond);上述的断行方式在公司里的很多程序中都出现过或者说是还在不断出现,我们在日常穿衣服时都注意避免头重脚轻的情况,为什么在写程序时就没有注意呢?下面的写法更值得推荐!fprintf(fp,“%d%d%d%d%d%d”,lYear,lMonth,lDay,lHour,lMinutes,lSecond);2.8.3空格在同一行语句中,分隔符后应增加一个空格,在变量与扩号“(”之间不要空格,例如:for(i=0;i10;i++)C/C++编程规范第7页{lID+=I*10;sprintf(lpszBuffer,“%ld”,lID);}2.9一致性和习惯的用法一致性带来的是更好的程序,如果程序中的格式很随意,例如对数组做循环,一会儿采用下标变量从下而上,一会儿又从上到下;这些变量会使人很难看清实际上到底怎么回事,而如果相同的处理每次出现都采用同样的风格,任何变化都预示着是经过了深思熟虑,要求读程序的人注意。2.9.1使用一致的加扩号和缩排风格缩排可以显示出程序的结构,什么样的缩排风格最好呢?是用两个空个还是TAB?花扩号放在if的同一行还是下一行?程序人员往往就这些问题发生争执,实际上这些特定风格远远没有一致地使用他们重要。此外,如果你工作在一个不是自己写地程序上,请注意保留程序原有的风格。
本文标题:C-CPP编程规范
链接地址:https://www.777doc.com/doc-3404773 .html