1、C+编码规范及规定王卓2023-02-21版本 V1.0 第一次编写有关C、C+的编码风格和程序质量可以参照高质量C/C+编程1概述32字体及颜色33文献结构43.1文献头注释43.2头文献113.3实现文献133.4文献的组织结构144命名规则154.1类/结构164.2函数164.3变量174.4常量184.5枚举、联合、typedef184.6宏、枚举值184.7名空间185代码风格与版式195.1类/结构225.2函数285.3变量、常量375.4枚举、联合、typedef395.5宏405.6名空间405.7异常411 概述高品质、易维护的软件开发离不开清楚严格的编码规范。本文档具体
2、描述C+软件开发过程中的编码规范。本规范也合用于所有在文档中出现的源码。2 字体及颜色强烈推荐采用Visual Assist X作为Visual Studio的辅助工具。在编辑源码时,应当根据编辑器支持的自定义选项最大限度地满足下表定义的高亮规范。类型颜色举例注释 R0;G128;B0(深绿)/ 注释例子关键字 R0;G0;B255(蓝)typedef, int, dynamic_cast class .类、结构、联合、枚举 R0;G0;B255(蓝)class CMyClass, enum ERRTYPE, typedef int CODE .名空间 R0;G0;B255(蓝)namespa
3、ce BaiY数字 R255;G0;B0(红)012 119u 0xff .字符、字符串 R0;G128;B128(深蓝绿)string, c .宏定义、枚举值 R255;G128;B0(橙黄)#define UNICODE, enum RED, GREEN, BLUE ;操作符 R136;G0;B0(棕色) , = + - * / ; ( ) .方法/函数 R136;G0;B0(棕色)MyFunc()变量 R128;G128;B128(中灰色)int nMyVar;背景 R255;G255;B255(白色)其它 R0;G0;B0(黑色)other things(通常是一个错误)Windows
4、平台中,应当优先使用字体:Fixedsys,这也是操作系统UI(所有的菜单、按钮、标题栏、对话框等等)默认使用的字体。该字体的好处很多: 1、兼容性好:所有Windows平台都支持该字体2、显示清楚:该字体为点阵字体,相对于矢量字体来说在显示器中呈现的影像更为清楚。矢量字体虽然可以自由缩放,但这个功能对于纯文本格式的程序源码来说没有任何实际作用。并且当显示字号较小(12pt以下)时,矢量字体尚有一些明显的缺陷:l 文字的边沿会有严重的凹凸感。 l 一些笔画的比例也会失调。 l 启动了柔化字体边沿后,还会使文字显得模糊不清。3、支持多语言:Fixedsys是UNICODE字体,支持世界上几乎所有
5、的文字符号。这对编写中文注释是很方便的。3 文献结构3.1 文献头注释所有C+的源文献均必须包含一个规范的文献头,文献头包含了该文献的名称、功能概述、作者、版权和版本历史信息等内容。标准文献头的格式为:/*! file*模块名 : 文献名 : 相关文献 : 文献实现功能 : 作者 : 版本 : -备注 : -修改记录 : 日 期 版本 修改人 修改内容YYYY/MM/DD X.Y */假如该文献有其它需要说明的地方,还可以专门为此扩展一节:/*! file*模块名 : 文献名 : 相关文献 : 文献实现功能 : 作者 : 版本 : -备注 : -修改记录 : 日 期 版本 修改人 修改内容YY
6、YY/MM/DD X.Y * 项目1 - 项目1.1 - 项目1.2=* 项目2 - 项目2.1 - 项目2.2.*/每行注释的长度都不应当超过80个半角字符。还要注意缩进和对其,以利阅读。关于文献头的完整例子,如下:/*! file*模块名 : 白杨string扩展库文献名 : stringEx.h相关文献 : stringEx.cpp文献实现功能 : C+ string 类功能扩展作者 : 白杨版本 : 1.10-备注 : 在string的基础上构建,未添加任何数据成员-修改记录 : 日 期 版本 修改人 修改内容 2023/08/27 1.0 白杨 创建2023/12/29 1.1 白杨
7、 新增正则表达式、 operator操作符等功能2023/01/28 1.2 白杨 新增部分函数2023/02/02 1.3 白杨 新增部分函数2023/03/11 1.6 白杨 新增部分函数 2023/03/29 1.7 白杨 新增ref(), set_size()等函数2023/06/28 1.8 白杨 移植到namespace BaiY2023/07/15 1.9 白杨 新增换码/还原函数;为所有正则函 数增长perl风格的字符类2023/07/19 1.10 白杨 新增vformat()函数;重写、改善 format()函数*版权所有(c) 2023, 2023, 白杨, 保存所有权利
8、=to_str、from_str、to_wstr、from_wstr等函数只能做标准ASCII字符集的宽/窄字符转换=* format和vformat函数所能解决的最大字符串长度限制为MAX_STRING,如需临时改变,可以使用:format(maxLength, fmt, .)函数和vformat(maxLength, fmt, arglist)函数=* 支持如下ostream风格的流式输入操作,可以方便地用于将个类数据追加到串: operator(char) operator(BYTE) operator(int) operator(unsigned) opeartor(long) ope
9、rator(unsigned long) operator(float) operator(double) operator(const stringEx&) operator(const char*) operator(const BYTE*) operator(wchar_t) operator(wstringEx)=* 支持兼容IEEE 1003.2-1992 (“POSIX.2”)标准,并且可以对的解决包含0值之字符串的正则表达式功能。 同时也支持perl风格的字符类。 为此提供了以下函数: regex_find(); regex_find_replace(); regex_find_
10、replace_all(); regex_comp(); regex_find_with_comp(); regex_free(); - 也可以通过定义宏“#define BaiY_USE_REGEX 0”禁用此功能。 - 为了提高搜索效率,避免大量反复的表达式编译:regex_find()会自动缓存最近一次使 用的正则表达式(缓存的内容可以通过用空表达式调用regex_find()函数释放)。假如需要高效率的交替搜索多个表达式,请使用regex_comp()、regex_find_with_comp()、regex_free()函数。 - 对于wstringEx,还保证可以对的辨认UNICO
11、DE字符类(如空白符,大小写等)。所以在构建一个正则表达式的时候,应当尽量使用如:blank:、:upper:这样的字符类,而不是如A-Z这样的自定义集合。 - 以下是所有POSIX字符类描述,及其相应perl字符类 POSIX 类 perl类 描述 :alnum: 字母和数字 :alpha: a 字母 :lower: l 小写字母 :upper: u 大写字母 :blank: 空白字符(空格和制表符) :space: s 所有空格符(比:blank:包含的范围广) :cntrl: 不可打印的控制字符(退格、删除、警铃.) :digit: d 十进制数字 :xdigit: x 十六进制数字 :
12、graph: 可打印的非空白字符 :print: p 可打印字符 :punct: 标点符号 - 此外,perl尚有以下特殊字符类: perl类 等效POSIX表达式 描述 o 0-7 八进制数字 O 0-7 非八进制数字 w :alnum:_ 单词构成字符 W :alnum:_ 非单词构成字符 A :alpha: 非字母 L :lower: 非小写字母 U :upper: 非大写字母 S :space: 非空格符 D :digit: 非数字 X :xdigit: 非十六进制数字 P :print: 非可打印字符 - POSIX字符类必须在方括号中工作,相反,perl字符类则必须在方括号外工作。
13、 - 在允许perl风格的正则搜索和替换中,还可以使用以下特殊字符换码序列: r - 回车 n - 换行 b - 退格 t - 制表符 v - 垂直制表符 - 双引号 - 单引号 =* 支持以给定的换码符和换码表进行换码和还原操作,为此提供了2个函数: stringEx& escape_translate(IN const char cEscape, IN const stringEx vstTransTable2); stringEx& escape_restore(IN const char cEscape, IN const stringEx vstTransTable2, IN boo
14、l bEraseUnknownEscapeSequence = true, IN bool bUntouchEscEsc = false); - 使用范例: / 定义换码表 const stringEx tbl2 = , GT , =, EQ , , / 换码表结束符 ; / 定义换码符 const char ESC = %; stringEx test = aaaa%=%bbbb; cout test.escape_translate( ESC, tbl ) endl; cout test.escape_restore( ESC, tbl ) endl; 程序输出: %LSTEST%GTaa
15、aa%EQ%EQ%bbbb%LS/TEST%GT aaaa%=%bbbb=* 为了增长与C函数一起使用的效率,提供了以下方法: char_type* ref( void ) void set_size( IN size_t len ) void set_length( IN size_t len ) - 可以这样使用: stingEx a; const char* pcStr = test; len = strlen(pcStr); a.reserve(len); strcpy(a.ref(), pcStr); a.set_size(len); - 但是假如有另一个stringEx类对象与“a
16、”引用同一块存储的话,则会导致两个对象的内容同时被改变,为防止这种情况发生,应当这样使用它们: stringEx a,b; a = something; b = a; / b和a引用同一块内存 const char* pcStr = test; len = strlen(pcStr); a.resize(len); / 对象a发生写时拷贝 strcpy(a.ref(), pcStr); 但是很显然,前一种方法效率较高。 - set_length() 方法是set_size方法的一个别名 - 使用以上函数时需要在basic_string模板类中添加两个保护成员函数,具体请参看“安装事项”文档。*
17、/关于文献头的模板,如下:文献头注释/*! file*模块名 :文献名 :相关文献 :文献实现功能 :作者 : 版本 : 1.0-备注 : -修改记录 : 日 期 版本 修改人 修改内容 YYYY/MM/DD 1.0 创建* 版权所有(c) YYYY, , 保存所有权利*/标准类注释/*! class*类名称 : 功能 : 异常类 : -备注 : 典型用法 : -作者 : */class CXXXpublic:/ 类型定义public:/ 构造、析构、初始化public:/ 虚函数public:/ 公用方法public:/ 静态方法protected:/ 内部方法private/ 私有类型定义
18、private:/ 私有方法private:/ 属性private:/ 静态属性private:/ 禁用的方法;标准函数注解/*! function*函数名 : 功能 : 参数 : 返回值 : 抛出异常 : -复杂度 : 备注 : 典型用法 : -作者 : */标准函数注解/ 这组语句或函数的功能 ./ 这组语句或函数的功能语句块/ =/ = 说明由此以下一系列语句执行的操作分割带/ #/ #/ #/ # 本地数据和函数./ # 本地数据和函数/ #/ #/ # Cxxx类成员定义./ # Cxxx类成员定义/ #/ #/ # 其它部分开始 ./ # 其它部分结束/ #3.2 头文献头文献通常
19、由以下几部分组成:文献头注释每个头文献,无论是内部的还是外部的,都应当由一个规范的文献头注释作为开始。 预解决块为了防止头文献被反复引用,应当用ifndef/define/endif结构产生预解决块。 函数和类/结构的声明等声明模块的接口 需要包含的内联函数定义文献(假如有的话)假如类中的内联函数较多,或者一个头文献中包含多个类的定义(不推荐),可以将所有内联函数定义放入一个单独的内联函数定义文献中,并在类声明之后用“#include”指令把它包含进来。头文献的编码规则:引用文献的格式用 #include 格式来引用标准库和系统库的头文献(编译器将从标准库目录开始搜索)。 用 #include
20、 filename.h 格式来引用当前工程中的头文献(编译器将从该文献所在目录开始搜索)。 分割多组接口(假如有的话)假如在一个头件中定义了多个类或者多组接口(不推荐),为了便于浏览,应当在每个类/每组接口间使用分割带把它们互相分开。关于头文献的完整例子,如下:/*! file*模块名 : 代码风格示例模块文献名 : sample.h相关文献 : sample.cpp, sample.inl文献实现功能 : 演示对的的代码风格作者 : 白杨版本 : 1.0-备注 : -修改记录 : 日 期 版本 修改人 修改内容 2023/07/22 1.0 白杨 创建* 版权所有(c) 2023, 白杨,
21、保存所有权利*/#ifndef _BaiY_Sample_H_ / 防止sample.h被反复引用#define _BaiY_Sample_H_#include / 引用标准库的头文献/ .#include ./common.h / 引用当前工程中的头文献/ .extern voidMyFunction( void ); / 全局函数声明class CMyClass / 类/结构声明/ .;#include sample.inl / 定义所有CMyClass中的内联函数#endif /_BaiY_Sample_H_3.3 实现文献实现文献包含所有数据和代码的实现体。实现文献的格式为: 文献头注
22、释每个实现文献都应当由一个规范的文献头注释作为开始 对配套头文献的引用引用声明了此文献实现的类、函数及数据的头文献 对一些仅用于实现的头文献的引用(假如有的话)将仅与实现相关的接口包含在实现文献里(而不是头文献中)是一个非常好的编程习惯。这样可以有效地屏蔽不应当暴露的实现细节,将实现改变对其它模块的影响减少到最少 。程序的实现体数据和函数的定义实现文献的编码规则:分割每个部分在本地(静态)定义和外部定义间,以及不同接口或不同类的实现之间,应使用分割带互相分开。关于实现文献的完整例子,如下:/*! file*模块名 : 代码风格示例模块文献名 : sample.cpp相关文献 : sample.h, sample.inl文献实现功能 : 演示对的的代码