《2022年C++编程规范 .pdf》由会员分享,可在线阅读,更多相关《2022年C++编程规范 .pdf(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、介绍1.1文档目的本编码规范针对C+语言。制定本规范的目的:提高代码的健壮性,使代码更安全、可靠提高代码的可读性,使代码易于查看和维护1.2动机为了对软件的开发进行适当的规范化,特制定本规范,其根本目的,是为了保证程序具有良好的、一致的结构,以期提高程序的可读性及可维护性,方便程序的测试、维护、升级等工作,同时,也促使大家养成书写规范代码的习惯。2一般性原则为了书写出清晰而易维护的代码,以下的一般性原则可以在所有的情况下应用到: 重用性 。软件工程师的一个目标就是通过重复使用代码来避免编写新的代码。因为重新使用已有的代码可以降低成本、增加代码的可靠性并提高它们的一致性。可维护性 。一段风格良好
2、的代码肯定具有很好的可读性。如果代码的维护者不明白你所书写的代码的含义,那么代码的维护就会成为一件十分困难而耗时的工作,所以在你编写代码的时候,一定要时刻的考虑到你所书写的代码别人是不是能够真正理解。模块化,封装和信息隐藏。如果一个模块的代码过长或者过于复杂,一定要考虑你的模块是不是需要重新组织一下,或者将一个模块分解成多个模块。不要对使用你代码的用户抱有太多的幻想。要让代码保护自己不被错误使用。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 21 页 - - - - -
3、 - - - - 书写注释 。注释可以帮助别人更好的理解你的代码,尽管这一条经常被软件开发人员忽视,但是对于代码的作者,使用者或者维护人员来说,代码注释在提高代码的可读性和可维护性方面是十分必要的。保持代码风格的一致性,无论是在文件级别,模块级别,还是工程级别,请保持代码风格的一致性。变量、函数、类和名字空间的命名要使用有意义的英文单词,且命名不要过长,简明易懂为佳,尽量不要使用缩写,更不要使用汉语拼音。3文件结构3.1一般性问题文件名使用字母、数字、下划线( 不推荐 ) 的组合来命名,但命名要有意义。所有的目录名,文件名一律用小写字母书写。一个文件中只能定义或者实现一个类,唯一的例外是小型的
4、帮助类或私有的内部类可以和它的主类定义在同一个文件中。文件中不允许包含废弃不用的源代码。3.2头文件为了防止头文件被重复引用,应当用 #ifndef/#define/#endif结构产生预处理块。用#include 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。用#include filename.h 格式来引用非标准库的头文件(编译器将从当前目录开始搜索, 若没有找到则从标准库目录搜索)。一般情况下 ,将构造函数和析构函数声明在类的开头位置。将从父类继承的函数放在不同的位置,并添加注释说明这些成员函数是从哪个类继承而来的声明写在头文件中,定义写在源文件中。名师资料总结 - - -
5、精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 21 页 - - - - - - - - - 避免 使用全局变量,尽量不要在头文件中出现象extern int value 这类声明。尽量用类中公共的静态成员函数取代全局函数。类中的访问控制符排列顺序为public、protected、private。用相同访问控制符修饰的方法和数据成员尽量写到一起。C+头文件的结构/- / / Copyright ? 2009, Software College of Hebei Normal Universit
6、y/ / File Name: filename.h / Description: / / / Author: / Date: / Version: /-#ifndef GRAPHICS_H / 防止 graphics.h被重复引用#define GRAPHICS_H #include / 引用标准库的头文件#include myheader.h / 引用非标准库的头文件class Common public: static void Function1(); / 全局函数声明; class Box / 类结构声明 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - -
7、- - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 21 页 - - - - - - - - - public: Box(); Box(); int getSize(void) const; string getName(void) const; protected: int calculateSide(void); private: int m_iSide; ; #endif 3.3源文件的结构。书写注释,源文件的注释是为这个模块的维护者书写的,源文件的注释应该满足以下条件:a注释要描述所有类级别的实现,详细描述复杂的和容易产生歧义的实现部分。b成员
8、函数的作用,目的以及返回值和参数都需要添加必要的注释部分。c注释的更改和更新要同步,对于核心代码使用块注释,不仅写明是什么,还要写清为什么,这样更便于日后维护。d避免使用尾注释,除非是对变量声明的注释。在同一个源文件中写一个类的实现部分。全局函数和成员函数的定义要和头文件中的声明顺序一致。声明函数时不要省略形参变量名,且同函数的参数名要和头文件中保持一致。C+源文件的结构/ 版权和版本声明见示例1-1 ,此处省略。#include graphics.h / 引用头文件名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理
9、- - - - - - - 第 4 页,共 21 页 - - - - - - - - - / 全局函数的实现体void Function1() / 类成员函数的实现体void Box:Draw() 3.4目录结构如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义文件分别保存在不同的目录,以便于维护。4命名和书写规范4.1标识符的命名规则不允许使用汉语拼音命名,更不要使用汉语,尽量英文来命名标识符,因为计算机语言的保留字都用英文命名,而且在国际化的组织中,英文一般作为主要的沟通语言。用描述性的文字来命名标识符,如果你不能为一个标识符命名,你一定要考虑这个标识符是否还有存在的必要。
10、尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号。类,结构的名字开头字母要大写名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 21 页 - - - - - - - - - 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。命名类时应使用名词,命名函数时使用动词或动宾短语或isXXX等。4.2类必须以大写开头,后面字母反映具体含义,例如:Student, Point。接口类必须以大写I开头,
11、代表 Interface。类中成员的声明顺序严格按照访问控制符public, protected 和 private的顺序。将数据成员放在类的private访问控制符下,非特殊情况,不允许在 protected和public的限定符下声明数据成员。尽量的用class声明一个类,而不是struct。将析构函数声明为虚函数,以保证父类可以正确释放子类的资源。尽可能减少友元friend的使用。尽可能的为类提供一个默认构造函数。用 inline函数代替宏定义。如果类 A 和类 B 毫不相关, 不可以为了使B 的功能更多些而让B 继承 A 的功能和属性。若在逻辑上B 是 A 的“一种”(a kind o
12、f ),则允许B 继承 A 的功能和属性。例如男人( Man )是人( Human )的一种,男孩(Boy )是男人的一种。那么类Man 可以从类 Human 派生,类Boy 可以从类 Man 派生。若在逻辑上A 是 B 的“一部分”(a part of ),则不允许B 从 A 派生,而是要用A和其它东西组合出B。采用以函数为中心的版式,将 public类型的函数写在前面,而将 private类型的数据写在后面,采用这种版式的程序员主张类的设计“以行为为中心”,重点关注的是类应该提供什么样的接口。以数据为中心版式以函数为中心的版式(推荐的版式 )名师资料总结 - - -精品资料欢迎下载 - -
13、 - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 21 页 - - - - - - - - - class A private: int i, j; float x, y; public: void Func1(void); void Func2(void); class A public: void Func1(void); void Func2(void); private: int i, j; float x, y; 4.3函数声明函数时, 参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字。避免函数有太多
14、的参数,参数个数尽量控制在5 个以内。如果参数太多,在使用时容易将参数类型或顺序搞错。尽量不要使用类型和数目不确定的参数。通过函数默认值减少函数重载的个数。函数参数以小写a 开头 ( 例如: aPara),表示这个变量是参数(argument)变量,从而使参数和临时变量,数据成员分开例子:/ testclass.h: /-/ Test class description. /- class TestClass public: int memberFunction( int aNumber ); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - -
15、 - - - 名师精心整理 - - - - - - - 第 7 页,共 21 页 - - - - - - - - - . / testclass.cpp: . / - / Implementation description. / - int TetrisClass:memberFunction( int aNumber ) . 如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针指向的对象在函数体内被意外修改。如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率。不要省略返回值的类型。函数名字与返回值类型
16、在语义上不可冲突。有时候函数原本不需要返回值,但为了增加灵活性如支持链式表达,可以附加返回值。在函数体的“入口处”,对参数的有效性进行检查,检查时提倡使用assert断言函数。函数名称涉及多个单词时,从第二个单词开始,首字母大写。如:getName()。4.4数据成员用 m_开头来命名数据成员,数据类型用首字母表示,const的数据成员也按下面的规则命名,例如 : 整型数据成员定义:int m_iValue; 短整型数据成员定义:short m_sValue; 长整型数据成员定义:long m_lValue; 字符型数据成员定义:char m_cValue; 单精度型数据成员定义:float
17、m_fValue; 双精度型数据成员定义:double m_dValue; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 21 页 - - - - - - - - - 字符串型数据成员定义:string m_strValue; 任意指针型数据成员定义:int *m_pValue; (p代表指针类型) 静态普通数据成员定义:static int s_iValue; static short s_sValue; static long s_lValue; static ch
18、ar s_cValue; static float s_fValue; static double s_dValue; static string s_strValue; 4.5指针和引用应当将修饰符 * 和紧靠变量名示例:char *name; int *x, y; / 此处 y 不会被误解为指针TestClass *pointer; / pointer to TestClass void Modify( Tint &aInteger ); / reference parameter used 4.6宏定义宏名全部使用大写,多个单词时,使用下划线隔开,如:NAME_SIZE。尽量避免使用对象
19、宏,替代时,一般用const常量替代对象宏,用内联函数或模板替代函数宏。4.7const常量在 C+ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。常量定义以大写字母K 开头,代码中的字符,大于0,小于 -1的整型变量及其他非整型变量一律用const常量定义例如:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 21 页 - - - - - - - - - const int KMagicNumber = 100; const string KU
20、serName = username; const常量定义在源文件中,尽量避免在头文件中定义const常量如果某一const常量与其它const常量密切相关,应在定义中包含这种关系,而不应给出一些孤立的值。例如:const float KRadius = 100; const float KDiameter = KRadius * 2; 4.8枚举变量枚举变量定义应该包含在特定的类中。枚举和它的成员的定义,应该采用有意义的命名方式,避免出现歧义。枚举成员以E 开头。枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数(
21、如PI=3.14159)。例子: class TestClass . enum TestType ETestEumFist, ETestEumSecond, . ; . ; 4.9全局变量尽量避免应用全局变量,如果有特殊情况必须定义的话,全局变量以小写g 开头名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 21 页 - - - - - - - - - 5表达式和基本语句5.1运算符的优先级一元运算符 + - * 的优先级高于对应的二元运算符。如果代码行中的运算符比较多,
22、用括号确定表达式的操作顺序,避免使用默认的优先级。例如:word = (high = b & c d & c + f = g + h ; / 复合表达式过于复杂不要有多用途的复合表达式。例如:d = (a = b + c) + r ; 该表达式既求a 值又求 d 值。应该拆分为两个独立的语句:a = b + c; d = a + r; 不要把程序中的复合表达式与“真正的数学表达式” 混淆。例如:if (a b c) / a b c是数学表达式而不是程序表达式并不表示if (ab) & (bc) 而是成了令人费解的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - -
23、- - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 21 页 - - - - - - - - - if ( (ab)=或=-EPSINON) & (x=EPSINON) 其中 EPSINON 是允许的误差(即精度)。应当将指针变量用=或 != 与 NULL 比较。指针变量的零值是“ 空” (记为 NULL)。尽管 NULL 的值与 0 相同,但是两者意义不同。假设指针变量的名字为p,它与零值比较的标准if语句如下: if (p = NULL) / p与 NULL 显式比较,强调p 是指针变量 if (p != NULL) 不要写成 if (p = 0)
24、/ 容易让人误解p 是整型变量 if (p != 0) 或者if (p) / 容易让人误解p 是布尔变量 if (!p) 5.4循环语句的效率在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数。低效率:长循环在最外层高效率:长循环在最内层for (row=0; row100; row+) for ( col=0; col5; col+ ) sum = sum + arowcol; for (col=0; col5; col+ ) for (row=0; row100; row+) sum = sum + arowcol; 名师资料总结
25、- - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 21 页 - - - - - - - - - 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。效率低但程序简洁效率高但程序不简洁for (i=0; iN; i+) if (condition) doSomething(); else doOtherthing(); if (condition) for (i=0; iN; i+) doSomething(); else for (i=0; iN; i+) doO
26、therthing(); 5.5for 语句的循环控制变量不可在 for 循环体内修改循环变量,防止for 循环失去控制。循环变量应定义在循环内,如for(int i = 0 ; i 80 字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。示例:if (very_longer_variable1 = very_longer_variable12) & (very_longer_variable3 = very_longer_variable14) & (very_longer_variable5 = very_l
27、onger_variable16) doSomething(); virtual Matrix MultiplyMatrix ( Matrix leftMatrix, Matrix rightMatrix ); for ( very_longer_initialization; very_longer_condition; very_longer_update ) dosomething(); 不允许把多个短语句写在一行中,即一行只写一条语句;if、for、 while、do 等语句自占一行,执行语句不得紧跟其后。示例:风格良好的代码行风格不良的代码行int width; / 宽度int he
28、ight; / 高度int depth; / 深度int width, height, depth; / 宽度高度深度x = a + b; x = a + b; y = c + d; z = e + f; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 21 页 - - - - - - - - - y = c + d; z = e + f; if (width height) dosomething(); if (width height) dosomething();
29、 for (initialization; condition; update) dosomething(); / 空行other(); for (initialization; condition; update) dosomething(); other(); 对齐只使用空格键,不使用TAB 键。说明:以免用不同的编辑器阅读程序时,因TAB 键所设置的空格数目不同而造成程序布局不整齐。函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case语句下的情况处理语句也要遵从语句缩进要求。在多个结构嵌套时,尾部的大括号极容易混淆,请在每个尾部的大括号后说明。示例:for(i
30、nt i = 0; i 10 ; i+) for(int k = 0 ; k 3) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 21 页 - - - - - - - - - /if 结束 循环 k 结束 循环 i结束尽可能在定义变量的同时初始化该变量(就近原则)示例:int width = 10; / 定义并初绐化width int height = 10; / 定义并初绐化height int depth = 10; / 定义并初绐化depth 程序块的分界符(如
31、C/C+ 语言的大括号,?和,?)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及 if、for、do 、while、switch、case语句中的程序都要采用如上的缩进方式。示例:风格良好的对齐风格不良的对齐void Function(int x) / program code void Function(int x) / program code if (condition) / program code if (condition) / program code else 名师资料总结 - - -精品资料欢迎下载 - - - -
32、 - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 21 页 - - - - - - - - - else / program code / program code for (initialization; condition; update) / program code for (initialization; condition; update) / program code While (condition) / program code while (condition) / program code 6.2注释一般
33、情况下,源程序有效注释量必须在20 以上,注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。版权和版本的声明位于头文件和定义文件的开头版权和版本的声明/- / / Copyright (c) 2009, Software College of Hebei Normal University/ / File name: filename.h / / Description: / / Author: / Date: / Version: 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - -
34、- - - 名师精心整理 - - - - - - - 第 19 页,共 21 页 - - - - - - - - - /-函数头部应进行注释,列出:函数的目的/ 功能、输入参数、输出参数、返回值、调用关系(函数、表)等。函数的注释/- / / Function: /Function name / / Description: filename.h / /-边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。注释的内容要清楚、明了,含义准确,防止注释二义性。避免在注释中使用缩写,特别是非常用缩写。7内存管理7.1创建与销毁不要混用C 和 C+的内存操作函数
35、和操作符用 new申请内存之后,应该立即检查指针值是否为NULL 。防止使用指针值为NULL的内存。用 delete释放了内存或对象之后,立即将指针设置为NULL ,防止产生“野指针”。回收用 new 分配的一组对象的内存空间的时候用 delete 动态内存的申请与释放必须配对,防止内存泄漏。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 20 页,共 21 页 - - - - - - - - - 7.2数组与指针不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 21 页,共 21 页 - - - - - - - - -