软件开发规范在研究项目团队协作开发的情况下(这里的团队协作也适合于应用项目的开发),编程时应该强调的一个重要方面是程序的易读性,在保证软件速度等性能指标能满足用户需求的情况下,能让其他程序员容易读懂你所编写的程序。若研究项目小组的所有开发人员都遵循统一的、鲜明的一套编程风格,可以让协作者、后继者和自己一目了然,在很短的时间内看清楚程序结构,理解设计的思路,大大提高代码的可读性、可重用性、程序健壮性、可移植性、可维护性。制定本编程规范的目的是为了提高软件开发效率及所开发软件的可维护性,提高软件的质量。本规范由程序风格、命名规范、注释规范、程序健壮性、可移植性、错误处理以及软件的模块化规范等部分组成。本软件开发规范适合讨论C/C++程序设计。1文件结构每个C++/C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。C++/C程序的头文件以“.h”为后缀,C程序的定义文件以“.c”为后缀,C++程序的定义文件通常以“.cpp”为后缀(也有一些系统以“.cc”或“.cxx”为后缀)。1.1文件信息声明文件信息声明位于头文件和定义文件的开头(参见示例1-1),主要内容有:(1)版权信息;(2)文件名称,项目代码,摘要,参考文献;(3)当前版本号,作者/修改者,完成日期;(4)版本历史信息;(5)主要函数描述。//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Copyright(c)2004,DepartmentofMathematics,ZhejiangUniversity//Allrightsreserved.////Filename:filename.h//ProjectCode:Theprojectcodeaboutthisfile//Abstract:Describethecontentofthisfilesummarily//Reference:......////Version:1.1//Author:thenameofauthor(mender)//Accomplisheddate:September2,2004////Replacedversion:1.0//OriginalAuthor:thenameoforiginalauthor(mender)//Accomplisheddate:September10,2003////Mainfunctions://Function1ReturncodeFunctionname(ParameterExplain)//Function2ReturncodeFunctionname(ParameterExplain)//...//FunctionnReturncodeFunctionname(ParameterExplain)////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////示例1-1文件信息声明☆【规则1.1-1】文件信息声明以两行斜杠开始,以两行斜杠结束,每一行都以两个斜杠开始;☆【规则1.1-2】文件信息声明包含五个部分,各部分之间以一空行间隔;☆【规则1.1-3】在主要函数部分描述了文件所包含的主要函数的声明信息,如果是头文件,这一部分是可以省略的。1.2头文件的结构头文件由三部分内容组成:(1)头文件开头处的文件信息声明(参见示例1-1);(2)预处理块;(3)函数和类结构声明等。假设头文件名称为filesystem.h,头文件的结构参见示例1-2。☆【规则1.2-1】为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块;“#ifndef”或者“#define”后以TAB键代替SPACE键做空格;如果头文件名称是由多个单词组成,则各单词间以下划线“_”连接,例如有头文件名称为“filesystem.h”,则定义如下:“#ifndef_FILE_SYSTEM_H_”;☆【规则1.2-2】用#includefilename.h格式来引用标准库的头文件(编译器将从标准库目录开始搜索);☆【规则1.2-3】用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索);☆【建议1.2-1】头文件中只存放“声明”而不存放“定义”;☆【建议1.2-1】头文件中应包含所有定义文件所定义的函数声明,如果一个头文件对应多个定义文件,则不同定义文件内实现的函数要分开声明,并作注释以解释所声明的函数从属于那一个定义文件;☆【建议1.2-3】宏定义和函数声明分离,在两个头文件中定义,如果没有类成员函数,可以将类和结构的定义与函数声明分离,也就是说一个头文件专用于宏定义,一个头文件专用于类和结构的定义,一个头文件专用于函数声明;☆【建议1.2-4】在C++语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来书写上的方便,但却造成了风格不一致,弊大于利。建议将成员函数的定义与声明分开,不论该函数体有多么小。头文件的结构如下://文件信息声明见示例1-1,此处省略。#ifndef_FILE_SYSTEM_H_//avoidreferencingthefilefilesystem.hrepeat#define_FILE_SYSTEM_H_#includemath.h//referencestandardheadfile…#include“myheader.h”//referencenon-standardheadfile…voidFunction1(…);//globalfunctiondeclare…classCBox//classstructuredecalre{…};#endif示例1-2C++/C头文件的结构1.3定义文件的结构定义文件有三部分内容:(1)定义文件开头处的文件信息声明(参见示例1-1);(2)对一些头文件的引用;(3)程序的实现体(包括数据和代码)。假设定义文件的名称为filesystem.c,定义文件的结构参见示例1-3。//文件信息声明见示例1-1,此处省略。#include“filesystem.h”//referenceaheadfile…//globalfunctionrealizationvoidFunction1(…){…}//classmemberfunctionrealizationvoidCBox::Draw(…){…}示例1-3C++/C定义文件的结构1.4头文件的作用早期的编程语言如Basic、Fortran没有头文件的概念,C++/C语言的初学者虽然会用使用头文件,但常常不明其理。这里对头文件的作用略作解释:(1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码;(2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。1.5目录结构如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义文件分别保存于不同的目录,以便于维护。例如可将头文件保存于include目录,将定义文件保存于source目录(可以是多级目录)。如果某些头文件是私有的,它不会被用户的程序直接引用,则没有必要公开其“声明”。为了加强信息隐藏,这些私有的头文件可以和定义文件存放于同一个目录。2命名规则比较著名的命名规则当推“匈牙利”命名法,该命名规则的主要思想是“在变量和函数名中加入前缀以增进人们对程序的理解”。例如所有的字符变量均以ch为前缀,若是指针变量则追加前缀p。如果一个变量由ppch开头,则表明它是指向字符指针的指针。“匈牙利”法最大的缺点是烦琐,例如inti,j,k;floatx,y,z;倘若采用“匈牙利”命名规则,则应当写成intiI,iJ,ik;//前缀i表示int类型floatfX,fY,fZ;//前缀f表示float类型如此烦琐的程序会让绝大多数程序员无法忍受。总的说来,没有一种命名规则可以让所有的程序员赞同,且命名规则对软件产品而言并不是“成败悠关”的事,而且在不同的平台和不同的环境下编写的程序所应遵循的规则也不尽相同,所以我们只是追求制定一种令大多数项目成员满意的命名规则,并在项目中贯彻实施。2.1共性原则本节论述的共性规则是被大多数程序员采纳的,我们应当在遵循这些共性规则的前提下,再扩充特定的规则,如2.2节☆【规则2.1-1】标识符应当直观且可以拼读,可望文知意,不必进行“解码”;☆【规则2.1-2】标识符的长度应当符合“min-length&&max-information”原则;☆【规则2.1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持一致;☆【规则2.1-4】程序中不要出现仅靠大小写区分的相似的标识符。☆【规则2.1-5】程序中不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误,但会使人误解;☆【规则2.1-6】变量的名字应当使用“名词”或者“形容词+名词”;☆【规则2.1-7】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组);☆【规则2.1-8】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等;☆【建议2.1-1】尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号;注:2.1.1标识符最好采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名,程序中的英文单词一般不要太复杂,用词应当准确,例如不要把CurrentValue写成NowValue;2.1.2标示符的长度应当以最小的长度实现最多信息,一般来说,长名字能更好地表达含义,但并非长的变量名就一定要比短的变量名要好,此外单字符的名字也是有用的,常见的如i,j,k,m,n,x,y,z等,它们通常可用作函数内的局部变量;2.1.3不同的操作系统的程序设计风格是不一样的,例如Windows应用程序的标识符通常采用“大小写”混排的方式,如AddChild,而Unix应用程序的标识符通常采用“小写加下划线”的方式,如add_child,别把这两类风格混在一起使用;2.2Windows变量命名规则☆【规则2.2-1】变量的命名规则要求采用“匈牙利法则”,即开头字母用变量的类型,其余部分用变量的英文意思或其英文意思的缩写,尽量避免采用中文拼音,要求单词的第一个字母大写;即:变量名=变量类型+变量英文意思(或缩写)变量类型请参见附表1-变量类型表;☆【规则2.2-2】类名和函数名用大写字母开头的单词组合而成;对struct、union、class变量的命名要求定义的类型用大写,结构采用S开头,联合体采用U开头,类采用C开头;例如:structSPoint{intm_nX;intm_nY;};unionURecordLen{BYTEm_byRecordNum;BYTEm_byRecordLen;}classCNode{//类成员变量或成员函数};☆【规则2.2-3】指针变量命名的基本原则为:一重指针变量的基本原则为:变量名=“p”+变量类型前缀+命名对多重指针变量的基本原则为:二重指针:变量