首页 软件编程规范

软件编程规范

举报
开通vip

软件编程规范Q/ZX 04.302.1–2003 Q/ZX 深圳市中兴通讯股份有限公司企业标准 (设计技术标准) Q/ZX 04.302.1–2003 2003-01-04 发布 2003-01-06实施 深圳市中兴通讯股份有限公司 发 布 目 次 II前言 11 范围 12 术语和定义 13 基本原则 24 布局 24.1 文件布局 54.2 基本格式 64.3 对齐 84.4 空行空格 104.5 断行 11...

软件编程规范
Q/ZX 04.302.1–2003 Q/ZX 深圳市中兴通讯股份有限公司企业 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 (设计技术标准) Q/ZX 04.302.1–2003 2003-01-04 发布 2003-01-06实施 深圳市中兴通讯股份有限公司 发 布 目 次 II前言 11 范围 12 术语和定义 13 基本原则 24 布局 24.1 文件布局 54.2 基本格式 64.3 对齐 84.4 空行空格 104.5 断行 115 注释 166 命名规则 217 变量、常量与类型 217.1 变量与常量 247.2 类型 298 表达式与语句 359 函数与过程 359.1 参数 369.2 返回值 379.3 内部实现 409.4 函数调用 4210 可靠性 4210.1 内存使用 4410.2 指针使用 4610.3 类和函数 5011 可测试性 5312 断言与错误处理 58附录A (资料性附录) 编程模版 66附录B (资料性附录) 规范检查表 71参考文献 前 言 编写本标准的目的是为了统一公司软件编程风格,提高软件源程序的可读性、可靠性和可重用性,提高软件源程序的质量和可维护性,减少软件维护成本,最终提高软件产品生产力。 本规范是针对C/C++语言的编程规范,其它不同编程语言可以参照此规范执行。本规范适用于公司所有产品的软件源程序,同时考虑到不同产品和项目的实际开发特性,本规范分成规则性和建议性两种:对于规则性规范,要求所有软件开发人员严格执行;对于建议性规范,各项目编程人员可以根据实际情况选择执行。本规范的示例都以C/C++语言描述。 本规范的内容包括:基本原则、布局、注释、命名规则、变量常量与类型、表达式与语句、函数与过程、可靠性、可测性、断言与错误处理等。规范最后给出了标准模版供软件人员参考。 本规范由软件编程规范C/C++小组编写,主要成员如下: 技术中心研究部:李军、刘继兴 技术中心成都所:左雪梅 本部事业部:李晖 网络事业部:田小渝、许生海、徐火顺、黄志强 CDMA事业部:程远忠、吴应祥 移动事业部:吴从海、王宏伟 软件编程规范有系列标准,包括:C/C++规范、GUI规范、Delphi规范、Java规范。 本标准的附录A、附录B是资料性附录。 自本标准实施之日起,以后新编写的和修改的代码均应执行本标准。 本标准由深圳市中兴通讯股份有限公司技术中心研究部提出,技术中心技术管理部归口。 本标准起草部门:技术中心研究部。 本标准主要起草人:软件编程规范小组。 本标准于2003年1月首次发布。 1 范围 本标准规定了C/C++语言的编程规范。 本标准适用于公司内使用C/C++语言编码的所有软件。本规范自生效之日起,对以后新编写的和修改的代码有约束力。 2 术语和定义 下列术语和定义适用于本标准。 2.1 原则 编程时应该坚持的指导思想。 2.2 规则 编程时必须遵守的约定。 2.3 建议 编程时必须加以考虑的约定。 2.4 说明 对此规则或建议的必要的解释。 2.5 正例 对此规则或建议给出的正确例子。 2.6 反例 对此规则或建议给出的反面例子。 3 基本原则 【原则1-1】首先是为人编写程序,其次才是计算机。 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发、测试、生产、用户使用、版本升级和后期维护等长期过程,只有易读、易维护的软件代码才具有生命力。 【原则1-2】保持代码的简明清晰,避免过分的编程技巧。 说明:简单是最美。保持代码的简单化是软件工程化的基本要求。不要过分追求技巧,否则会降低程序的可读性。 【原则1-3】所有的代码尽量遵循ANSI C标准。 说明:所有的代码尽可能遵循ANSI C标准,尽可能不使用ANSI C未定义的或编译器扩展的功能。 【原则1-4】编程时首先达到正确性,其次考虑效率。 说明:编程首先考虑的是满足正确性、健壮性、可维护性、可移植性等质量因素,最后才考虑程序的效率和资源占用。 【原则1-5】避免或少用全局变量。 说明:过多地使用全局变量,会导致模块间的紧耦合,违反模块化的要求。 【原则1-6】尽量避免使用GOTO语句。 【原则1-7】尽可能重用、修正老的代码。 说明:尽量选择可借用的代码,对其修改优化以达到自身要求。 【原则1-8】 尽量减少同样的错误出现的次数。 说明:事实上,我们无法做到完全消除错误,但通过不懈的努力,可以减少同样的错误出现的次数。 4 布局 程序布局的目的是显示出程序良好的逻辑结构,提高程序的准确性、连续性、可读性、可维护性。更重要的是,统一的程序布局和编程风格,有助于提高整个项目的开发质量,提高开发效率,降低开发成本。同时,对于普通程序员来说,养成良好的编程习惯有助于提高自己的编程水平,提高编程效率。因此,统一的、良好的程序布局和编程风格不仅仅是个人主观美学上的或是形式上的问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 ,而且会涉及到产品质量,涉及到个人编程能力的提高,必须引起大家重视。 4.1 文件布局 【规则2-1-1】遵循统一的布局顺序来书写头文件。 说明:以下内容如果某些节不需要,可以忽略。但是其它节要保持该次序。 头文件布局: 文件头(参见第三章“注释”) #ifndef 文件名_H(全大写) #define 文件名_H 其它条件编译选项 #include(依次为标准库头文件、非标准库头文件) 常量定义 全局宏 全局数据类型 类定义 模板(template)(包括C++中的类模板和函数模板) 全局函数原型 #endif 【规则2-1-2】遵循统一的布局顺序来书写实现文件。 说明:以下内容如果某些节不需要,可以忽略。但是其它节要保持该次序。 实现文件布局: 文件头(参见第三章“注释”) #include(依次为标准库头文件、非标准库头文件) 常量定义 文件内部使用的宏 文件内部使用的数据类型 全局变量 本地变量(即静态全局变量) 局部函数原型 类的实现 全局函数 局部函数 【规则2-1-3】使用注释块分离上面定义的节。 正例: / *********************************************************** * 数据类型定义 * *********************************************************** / typedef unsigned char BOOLEAN; /************************************************************* * 函数原型 * ************************************************************/ int DoSomething(void); 【规则2-1-4】头文件必须要避免重复包含。 说明:可以通过宏定义来避免重复包含。 正例: #ifndef MODULE_H #define MODULE_H [文件体] #endif 【规则2-1-5】包含标准库头文件用尖括号 < >,包含非标准库头文件用双引号 “ ”。 正例: #include #include “heads.h” 【规则2-1-6】遵循统一的顺序书写类的定义及实现。 说明: 类的定义(在定义文件中)按如下顺序书写: 公有属性 公有函数 保护属性 保护函数 私有属性 私有函数 类的实现(在实现文件中)按如下顺序书写: 构造函数 析构函数 公有函数 保护函数 私有函数 4.2 基本格式 【规则2-2-1】程序中一行的代码和注释不能超过80列。 说明:包括空格在内不超过80列。 【规则2-2-2】if、else、else if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加 { }。 说明:这样可以防止书写失误,也易于阅读。 正例: if (varible1 < varible2) { varible1 = varible2; } 反例:下面的代码执行语句紧跟if的条件之后,而且没有加{},违反规则。 if (varible1 < varible2) varible1 = varible2; 【规则2-2-3】定义指针类型的变量,*应放在变量前。 正例: float *pfBuffer; 反例: float* pfBuffer; 〖建议2-2-1〗源程序中关系较为紧密的代码应尽可能相邻。 说明:这样便于程序阅读和查找。 正例: iLength = 10; iWidth = 5; // 矩形的长与宽关系较密切,放在一起。 StrCaption = “Test”; 反例: iLength = 10; strCaption = “Test”; iWidth = 5; 4.3 对齐 【规则2-3-1】 禁止使用TAB键,必须使用空格进行缩进。缩进为4个空格。 说明:消除不同编辑器对TAB处理的差异,有的代码编辑器可以设置用空格代替TAB键。 【规则2-3-2】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。{ }之内的代码块使用缩进规则对齐。 说明:这样使代码便于阅读,并且方便注释。 do while语句和结构的类型化时可以例外,while条件和结构名可与 } 在同一行。 正例: void Function(int iVar) { // 独占一行并与引用语句左对齐。 while (condition) { DoSomething(); // 与{ }缩进4格 } } 反例: void Function(int iVar){ while (condition){ DoSomething(); }} 【规则2-3-3】声明类的时候,public、protected、private关键字与分界符{} 对齐,这些部分的内容要进行缩进。 正例: class CCount { public: // 与 { 对齐 CCount (void); // 要进行缩进 ~ CCount (void); int GetCount(void); void SetCount(int iCount); private: int m_iCount; } 【规则2-3-4】结构型的数组、多维的数组如果在定义时初始化,按照数组的矩阵结构分行书写。 正例: int aiNumbers[4][3] = { 1, 1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64 } 【规则2-3-5】相关的赋值语句等号对齐。 正例: tPDBRes.wHead = 0; tPDBRes.wTail = wMaxNumOfPDB - 1; tPDBRes.wFree = wMaxNumOfPDB; tPDBRes.wAddress = wPDBAddr; tPDBRes.wSize = wPDBSize; 〖建议2-3-1〗在switch语句中,每一个case分支和default要用{ }括起来,{ }中的内容需要缩进。 说明:使程序可读性更好。 正例: switch (iCode) { case 1: { DoSomething(); // 缩进4格 break; } case 2: { // 每一个case分支和default要用{}括起来 DoOtherThing(); break; } … // 其它case分支 default: { DoNothing(); break; } } 4.4 空行空格 【规则2-4-1】不同逻辑程序块之间要使用空行分隔。 说明:空行起着分隔程序段落的作用。适当的空行可以使程序的布局更加清晰。 正例: void Foo::Hey(void) { [Hey实现代码] } // 空一行 void Foo::Ack(void) { [Ack实现代码] } 反例: void Foo::Hey(void) { [Hey实现代码] } void Foo::Ack(void) { [Ack实现代码] } // 两个函数的实现是两个逻辑程序块,应该用空行加以分隔。 【规则2-4-2】一元操作符如“!”、“~”、“++”、“--”、“*”、“&”(地址运算符)等前后不加空格。“[]”、“.”、“->”这类操作符前后不加空格。 正例: !bValue ~iValue ++iCount *strSource &fSum aiNumber[i] = 5; tBox.dWidth tBox->dWidth 【规则2-4-3】多元运算符和它们的操作数之间至少需要一个空格。 正例: fValue = fOldValue; fTotal + fValue iNumber += 2; 【规则2-4-4】关键字之后要留空格。 说明:if、for、while等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。 【规则2-4-5】函数名之后不要留空格。 说明:函数名后紧跟左括号‘(’,以与关键字区别。 【规则2-4-6】‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。‘,’之后要留空格。‘;’不是行结束符号时其后要留空格。 正例: 例子中的 凵 代表空格。 for凵(i凵=凵0;凵i凵<凵MAX_BSC_NUM;凵i++) { DoSomething(iWidth,凵iHeight); } 【规则2-4-7】注释符与注释内容之间要用一个空格进行分隔。 正例: /* 注释内容 */ // 注释内容 反例: /*注释内容*/ //注释内容 4.5 断行 【规则2-5-1】长表达式(超过80列)要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐。 说明:条件表达式的续行在第一个条件处对齐。 for循环语句的续行在初始化条件语句处对齐。 函数调用和函数声明的续行在第一个参数处对齐。 赋值语句的续行应在赋值号处对齐。 正例: if ((iFormat == CH_A_Format_M) && (iOfficeType == CH_BSC_M)) // 条件表达式的续行在第一个条件处对齐 { DoSomething(); } for (long_initialization_statement; long_condiction_statement; // for循环语句续行在初始化条件语句处对齐 long_update_statement) { DoSomething(); } // 函数声明的续行在第一个参数处对齐 BYTE ReportStatusCheckPara(HWND hWnd, BYTE ucCallNo, BYTE ucStatusReportNo); // 赋值语句的续行应在赋值号处对齐 fTotalBill = fTotalBill + faCustomerPurchases[iID] + fSalesTax(faCustomerPurchases[iID]); 【规则2-5-2】函数声明时,类型与名称不允许分行书写。 正例: extern double FAR CalcArea(double dWidth, double dHeight); 反例: extern double FAR CalcArea(double dWidth, double dHeight); 5 注 释 注释有助于理解代码,有效的注释是指在代码的功能、意图层次上进行注释,提供有用、额外的信息,而不是代码表面意义的简单重复。 【规则3-1】C语言的注释符为“/* … */”。C++语言中,多行注释采用“/* … */”,单行注释采用“// …”。 【规则3-2】一般情况下,源程序有效注释量必须在20%以上。 说明:注释的原则是有助于对程序的阅读理解,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。有效的注释是指在代码的功能、意图层次上进行注释,提供有用、额外的信息。 【规则3-3】注释使用中文。 说明:对于特殊要求的可以使用英文注释,如工具不支持中文或国际化版本时。 【规则3-4】文件头部必须进行注释,包括:.h文件、.c文件、.cpp文件、.inc文件、.def文件、编译说明文件.cfg等。 说明:注释必须列出:版权信息、文件标识、内容摘要、版本号、作者、完成日期、修改信息等。 正例: 下面是文件头部的中文注释: /********************************************************************* * 版权所有 (C)2001, 深圳市中兴通讯股份有限公司。 * * 文件名称: // 文件名 * 文件标识: // 见配置管理 计划 项目进度计划表范例计划下载计划下载计划下载课程教学计划下载 书 * 内容摘要: // 简要描述本文件的内容,包括主要模块、函数及其功能的说明 * 其它说明: // 其它内容的说明 * 当前版本: // 输入当前版本 * 作 者: // 输入作者名字及单位 * 完成日期: // 输入完成日期,例:2000年2月25日 * * 修改记录1:// 修改历史记录,包括修改日期、修改者及修改内容 * 修改日期: * 版 本 号: * 修 改 人: * 修改内容: * 修改记录2:… **********************************************************************/ 下面是文件头部的英文注释: /*********************************************************************** * Copyright (C) 2001, ZTE Corporation. * * File Name: // 文件名 (注释对齐) * File Mark: // 见配置管理计划书 * Description: // 简要描述本文件的内容,完成的主要功能 * Others: // 其它内容的说明 * Version: // 输入当前版本 * Author: // 输入作者名字及单位 * Date: // 输入完成日期,例:2001-12-12 * * History 1: // 修改历史记录,包括修改日期、修改者及修改内容 * Date: * Version: * Author: * Modification: * History 2: … **********************************************************************/ 【规则3-5】函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、访问和修改的表、修改信息等。 说明:注释必须列出:函数名称、功能描述、输入参数、输出参数、返 回 值、修改信息等。 正例: 下面是函数头部的中文注释: /********************************************************************** * 函数名称: // 函数名称 * 功能描述: // 函数功能、性能等的描述 * 访问的表: //(可选)被访问的表,此项仅对于有数据库操作的程序 * 修改的表: //(可选)被修改的表,此项仅对于有数据库操作的程序 * 输入参数: // 输入参数说明,包括每个参数的作用、取值说明及参数间关系 * 输出参数: // 对输出参数的说明。 * 返 回 值: // 函数返回值的说明 * 其它说明: // 其它说明 * 修改日期 版本号 修改人 修改内容 * ----------------------------------------------- * 2002/08/01 V1.0 XXXX XXXX ***********************************************************************/ 下面是函数头部的英文注释: /********************************************************************** * Function: // 函数名称(注释对齐) * Description: // 函数功能、性能等的描述 * Table Accessed: //(可选)被访问的表,此项仅对于有数据库操作的程序 * Table Updated: //(可选)被修改的表,此项仅对于有数据库操作的程序 * Input: // 输入参数说明,包括每个参数的作用、取值说明以及参数间关系 * Output: // 对输出参数的说明 * Return: // 函数返回值的说明 * Others: // 其它说明 * Modify Date Version Author Modification * ----------------------------------------------- * 2002/08/01 V1.0 XXXX XXXX **********************************************************************/ 【规则3-6】包含在{ }中代码块的结束处应加注释,便于阅读。特别是多分支、多重嵌套的条件语句或循环语句。 说明:此时注释可以用英文,方便查找对应的语句。 正例: void Main() { if (…) { … while (…) { … } /* end of while (…) */ // 指明该条while语句结束 … } /* end of if (…) */ // 指明是哪条语句结束 } /* end of void main()*/ // 指明函数的结束 【规则3-7】保证代码和注释的一致性。修改代码同时修改相应的注释,不再有用的注释要删除。 【规则3-8】注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。 说明:在使用缩写时或之前,应对缩写进行必要的说明。 正例: 如下书写比较结构清晰 /* 获得子系统索引 */ iSubSysIndex = aData[iIndex].iSysIndex; /* 代码段1注释 */ [ 代码段1 ] /* 代码段2注释 */ [ 代码段2 ] 反例1: 如下例子注释与描述的代码相隔太远。 /* 获得子系统索引 */ iSubSysIndex = aData[iIndex].iSysIndex; 反例2: 如下例子注释不应放在所描述的代码下面。 iSubSysIndex = aData[iIndex].iSysIndex; /* 获得子系统索引 */ 反例3: 如下例子,显得代码与注释过于紧凑。 /* 代码段1注释 */ [ 代码段1 ] /* 代码段2注释 */ [ 代码段2 ] 【规则3-9】全局变量要有详细的注释,包括对其功能、取值范围、访问信息及访问时注意事项等的说明。 正例: /* * 变量作用:(错误状态码) * 变量范围:例如0 - SUCCESS 1 - Table error * 访问说明:(访问的函数以及方法) */ BYTE g_ucTranErrorCode; 【规则3-10】注释与所描述内容进行同样的缩排。 说明:可使程序排版整齐,并方便注释的阅读与理解。 正例: 如下注释结构比较清晰 int DoSomething(void) { /* 代码段1注释 */ [ 代码段1 ] /* 代码段2注释 */ [ 代码段2 ] } 反例: 如下例子,排版不整齐,阅读不方便; int DoSomething(void) { /* 代码段1注释 */ [ 代码段1 ] /* 代码段2注释 */ [ 代码段2 ] } 【规则3-11】对分支语句(条件分支、循环语句等)必须编写注释。 说明:这些语句往往是程序实现某一特殊功能的关键,对于维护人员来说,良好的注释有助于更好的理解程序,有时甚至优于看设计文档。 〖建议3-1〗通过对函数或过程、变量、结构等正确的命名以及合理地组织代码结构,使代码成为自注释的。 说明:清晰准确的函数、变量命名,可增加代码的可读性,减少不必要的注释。 〖建议3-2〗尽量避免在注释中使用缩写,特别是不常用缩写。 说明:在使用缩写时,应对缩写进行必要的说明。 6 命名规则 好的命名规则能极大地增加可读性和可维护性。同时,对于一个有上百个人共同完成的大项目来说,统一命名约定也是一项必不可少的内容。本章对程序中的所有标识符(包括变量名、常量名、函数名、类名、结构名、宏定义等)的命名做出约定。 【规则4-1】标识符要采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名。 说明:标识符应当直观且可以拼读,可望文知义,避免使人产生误解。程序中的英文单词一般不要太复杂,用词应当准确。 【规则4-2】标识符只能由26个英文字母,10个数字,及下划线的一个子集来组成,并严格禁止使用连续的下划线,下划线也不能出现在标识符头或结尾(预编译开关除外)。 说明:这样做的目的是为了使程序易读。因为 variable_name 和 variable__name 很难区分,下划线符号‘_’若出现在标识符头或结尾,容易与不带下划线‘_’的标识符混淆。 【规则4-3】标识符的命名应当符合“min-length && max-information”原则。 说明:较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。协议中的单词的缩写与协议保持一致。对于某个系统使用的专用缩写应该在某处做统一说明。 正例:如下单词的缩写能够被大家认可: temp 可缩写为 tmp ; flag 可缩写为 flg ; statistic 可缩写为 stat ; increment 可缩写为 inc ; message 可缩写为 msg ; 规定的常用缩写如下: 常用词 缩写 Argument Arg Buffer Buf Clear Clr Clock Clk Compare Cmp Configuration Cfg Context Ctx Delay Dly Device Dev Disable Dis Display Disp Enable En Error Err Function Fnct Hexadecimal Hex High Priority Task HPT I/O System IOS Initialize Init Mailbox Mbox Manager Mgr Maximum Max Message Msg Minimum Min Multiplex Mux Operating System OS Overflow Ovf Parameter Param Pointer Ptr Previous Prev Priority Prio Read Rd Ready Rdy Register Reg Schedule Sched Semaphore Sem Stack Stk Synchronize Sync Timer Tmr Trigger Trig Write Wr 【规则4-4】程序中不要出现仅靠大小写区分的相似的标识符。 【规则4-5】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。 说明:下面是一些在软件中常用的反义词组。 add/remove ; begin/end ; create/destroy ; insert/delete ; first/last ; get/release ; increment/decrement ; put/get ; add/delete ; lock/unlock ; open/close ; min/max ; old/new ; start/stop ; next/previous ; source/target ; show/hide ; send/receive ;source/destination ; cut/paste ; up/down 【规则4-6】宏、常量名都要使用大写字母, 用下划线 ‘_’ 分割单词。预编译开关的定义使用下划线 ‘_’ 开始。 正例:如 DISP_BUF_SIZE、MIN_VALUE、MAX_VALUE 等等。 【规则4-7】变量名长度应小于31个字符,以保持与ANSI C标准一致。不得取单个字符(如i、j、k等)作为变量名,但是局部循环变量除外。 说明:变量,尤其是局部变量,如果用单个字符表示,很容易出错(如l误写成1),而编译时又检查不出,则有可能增加排错时间。过长的变量名会增加工作量,会使程序的逻辑流程变得模糊,给修改带来困难,所以应当选择精炼、意义明确的名字,才能简化程序语句,改善对程序功能的理解。 【规则4-8】程序中局部变量不要与全局变量重名。 说明:尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。 【规则4-9】使用一致的前缀来区分变量的作用域。 说明:变量活动范围前缀规范如下: g_ : 全局变量 s_ : 模块内静态变量 空 : 局部变量不加范围前缀 【规则4-10】使用一致的小写类型指示符作为前缀来区分变量的类型。 说明:常用变量类型前缀列表如下: i : int f : float d : double c : char uc : unsigned char 或 BYTE l : long p : pointer b : BOOL h : HANDLE w : unsigned short 或 WORD dw : DWORD或 unsigned long a : 数组,array of TYPE str : 字符串 t : 结构类型 以上前缀可以进一步组合,在进行组合时,数组和指针类型的前缀指示符必须放在变量类型前缀的首位。 【规则4-11】完整的变量名应由前缀+变量名主体组成,变量名的主体应当使用“名词”或者“形容词+名词”,且首字母必须大写。 说明:各种前缀字符可能组合使用,在这种情况下,各前缀顺序为:变量作用域前缀、变量类型前缀。 正例: float g_fValue; //类型为浮点数的全局变量 char *pcOldChar; //类型为字符指针的局部变量 【规则4-12】函数名用大写字母开头的单词组合而成,且应当使用“动词”或者“动词+名词”(动宾词组)。 说明:函数名力求清晰、明了,通过函数名就能够判断函数的主要功能。函数名中不同意义字段之间不要用下划线连接,而要把每个字段的首字母大写以示区分。函数命名采用大小写字母结合的形式,但专有名词不受限制。 【规则4-13】结构名、联合名、枚举名由前缀T_ 开头。 【规则4-14】事件名由前缀EV_ 开头。 【规则4-15】类名采用大小写结合的方法。在构成类名的单词之间不用下划线,类名在开头加上C,类的成员变量统一在前面加m_ 前缀。 说明:C++Builder中的类名在开头加T。 正例: void Object::SetValue(int iWidth, int iHeight) { m_iWidth = iWidth; m_iHeight = iHeight; } 〖建议4-1〗尽量避免名字中出现数字编号,如Value1、Value2等,除非逻辑上的确需要编号。 〖建议4-2〗标识符前最好不加项目、产品、部门的标识。 说明:这样做的目的是为了代码的可重用性。 7 变量、常量与类型 变量、常量和数据类型是程序编写的基础,它们的正确使用直接关系到程序设计的成败,变量包括全局变量、局部变量和静态变量,常量包括数据常量和指针常量,类型包括系统的数据类型和自定义数据类型。本章主要说明变量、常量与类型使用时必须遵循的规则和一些需注意的建议,关于它们的命名,参见命名规则。 7.1 变量与常量 【规则5-1-1】定义全局变量时必须仔细分析,明确其含义、作用、取值范围及与其它全局变量间的关系。 说明:全局变量关系到程序的结构框架,对于全局变量的理解关系到对整个程序能否正确理解,所以在对全局变量声明的同时,应对其含义、作用及取值范围进行详细地注释说明,若有必要还应说明与其它变量的关系。 【规则5-1-2】明确全局变量与操作此全局变量的函数或过程的关系。 说明:全局变量与函数的关系包括:创建、修改及访问。明确过程操作变量的关系后,将有利于程序的进一步优化、单元测试、系统联调以及代码维护等。这种关系的说明可在注释或文档中描述。 【规则5-1-3】一个变量有且只有一个功能,不能把一个变量用作多种用途。 说明:一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同。 正例: WORD DelRelTimeQue(T_TCB *ptTcb ) { WORD wValue; WORD wLocate; wLocate = 3; wValue = DeleteFromQue(wLocate); return wValue; } 反例: WORD DelRelTimeQue(T_TCB *ptTcb) { WORD wLocate; wLocate = 3; wLocate = DeleteFromQue(wLocate); // wLocate 具有两种功能。 return wLocate; } 【规则5-1-4】循环语句与判断语句中,不允许对其它变量进行计算与赋值。 说明:循环语句只完成循环控制功能,if语句只完成逻辑判断功能,不能完成计算赋值功能。 正例: do { [处理语句] cInput = GetChar(); } while (cInput == 0);  反例: do { [处理语句] } while (cInput = GetChar()); 【规则5-1-5】宏定义中如果包含表达式或变量,表达式和变量必须用小括号括起来。 说明:在宏定义中,对表达式和变量使用括号,可以避免可能发生的计算错误。 正例: #define HANDLE(A, B) (( A ) / ( B )) 反例: #define HANDLE(A, B) (A / B) 【规则5-1-6】使用宏定义多行语句时, 必须使用 { } 把这些语句括起来。 说明:在宏定义中,对多行语句使用大括号,可以避免可能发生的错误。 〖建议5-1-1〗尽量构造仅有一个模块或函数可以修改、创建的全局变量,而其余有关模块或函数只能访问。 说明:减少全局变量操作引起的错误。 正例:在源文件中,可按如下注释形式说明。 T_Student *g_ptStudent; 变量 关系 函数 g_pStudent 创建 SystemInit(void) 修改 无 访问 StatScore(const T_Student *ptStudent) PrintRec(const T_Student *ptStudent) 〖建议5-1-2〗对于全局变量通过统一的函数访问。 说明:可以避免访问全局变量时引起的错误。 正例: T_Student g_tStudent; T_Student GetStudentValue(void) { T_Student tStudentValue; [获取g_tStudent的访问权] tStudentValue = g_tStudent; [释放g_tStudent的访问权] return tStudentValue; } BYTE SetStudentValue(const T_Student *ptStudentValue) { BYTE ucIfSuccess; ucIfSuccess = 0; [获取g_tStudent的访问权] g_tStudent = *ptStudentValue ; [释放g_tStudent的访问权] return ucIfSuccess; } 〖建议5-1-3〗尽量使用const说明常量数据,对于宏定义的常数,必须指出其类型。 正例: const int MAX_COUNT = 1000; #define MAX_COUNT (int)1000 反例: #define MAX_COUNT 1000 〖建议5-1-4〗最好不要在语句块内声明局部变量。 7.2 类型 【规则5-2-1】结构和联合必须被类型化。 正例: typedef struct { char acName[NAME_SIZE]; WORD wScore; } T_Student; T_Student *ptStudent; 反例: struct student { char acName[NAME_SIZE]; WORD wScore; } *ptStudent; 〖建议5-2-1〗使用严格形式定义的、可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量。 说明:使用统一的自定义数据类型,有利于程序的移植。 自定义数据类型 类型说明 类型定义(以Win32为例) VOID 空类型 void BOOLEAN 逻辑类型 (TRUE或FALSE) unsigned char BYTE/ UCHAR 无符号 8 位整数 unsigned char CHAR 有符号 8 位整数 signed char WORD16/ WORD 无符号 16 位整数 unsigned short SWORD16/SHORT 有符号 16 位整数 signed short WORD32/DWORD 无符号 32 位整数 unsigned int SWORD32/INT/LONG 有符号 32 位整数 signed int FP32/FLOAT 32 位单精度符点数 float FP64/DOUBLE 64 位双精度符点数 double 〖建议5-2-2〗结构是针对一种事务的抽象,功能要单一,不要设计面面俱到的数据结构。 说明:设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。 正例: typedef struct TeacherStruct { BYTE aucName[8]; BYTE ucSex; }T_Teacher; typedef struct StudentStruct { BYTE ucName[8]; BYTE ucAge; BYTE ucSex; WORD wTeacherInd; }T_Student; 反例: 如下结构不太清晰、合理。 typedef struct StudentStruct { BYTE aucName[8]; BYTE ucAge; BYTE ucSex; BYTE aucTeacherName[8]; BYTE ucTeacherSex; }T_Student; 〖建议5-2-3〗不同结构间的关系要尽量简单,若两个结构间关系较复杂、密切,那么应合为一个结构。 说明:两个结构关系复杂时,它们可能反映的是一个事物的不同属性。 由于两个结构都是描述同一事物的,那么不如合成一个结构。 正例: typedef struct PersonStruct { BYTE aucName[8]; BYTE aucAddr[40]; BYTE ucSex; BYTE aucCity[15]; BYTE ucTel; }T_Person; 反例:如下两个结构的构造不合理。 typedef struct PersonOneStruct { BYTE aucName[8]; BYTE aucAddr[40]; BYTE ucSex; BYTE ucCity[15]; }T_PersonOne; typedef struct PersonTwoStruct { BYTE aucName[8]; BYTE aucAddr[40]; BYTE ucTel; }T_PersonTwo; 〖建议5-2-4〗结构中元素的个数应适中。若结构中元素个数过多可考虑依据某种原则把元素组成不同的子结构,以减少原结构中元素的个数。 说明:增加结构的可理解性、可操作性和可维护性。 正例:假如认为如上的_PERSON结构元素过多,那么可如下对之划分。 typedef struct PersonBaseInfoStruct { BYTE aucName[8]; BYTE ucAge; BYTE ucSex; }T_PersonBaseInfo; typedef struct PersonAddressStruct { BYTE aucAddr[40]; BYTE aucCity[15]; BYTE ucTel; } T_PersonAddress; typedef struct PersonStruct { T_PersonBaseInfo tPersonBase; T_PersonAddress tPersonAddr; } T_Person; 〖建议5-2-5〗仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用现象,对于结构中未用的位明确地给予保留。 说明:合理排列结构中元素顺序,可节省空间并增加可理解性。 正例:如下形式,不仅可节省字节空间,可读性也变好了。 typedef struct ExampleStruct { BYTE ucValid: 1; BYTE ucSetFlg: 1; BYTE ucOther: 6; // 保留位 T_Person tPerson; }T_Example; 反例:如下结构中的位域排列,将占较大空间,可读性也稍差。 typedef struct ExampleStruct { BYTE ucValid: 1; T_Person tPerson; BYTE ucSetFlg: 1; } T_Example; 〖建议5
本文档为【软件编程规范】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_873275
暂无简介~
格式:doc
大小:731KB
软件:Word
页数:86
分类:互联网
上传时间:2012-07-21
浏览量:119