【c++】编码规范及相应的配置方法
来源:互联网 发布:ppt 触发器 mac 设置 编辑:程序博客网 时间:2024/06/06 19:52
编程规范来源:腾讯 GL/YF 014-2007V1.0-L1
程序的板式
1、程序块要采用缩进风格编写,缩进的空格数为4个。
由开发工具自动生成的代码可能不一致,但如果开发工具可以配置,则应该统一配置缩进为4个空格。
配置方法:在菜单中选择: 工具-->选项-->文本编辑器--->所有语言-->制表符 在窗口中选择,制表符大小选为4,勾
选插入空格。
2、缩进或者对其只能使用空格键,不可使用TAB键。
3、相对独立的程序块之间、变量说明之后必须加空行。
以下情况应该是用空行分开:
1)函数之间应该用空行分开;
2)变量声明应尽可能靠近第一次使用处,避免一次性声明一组没有马上使用的变量;
3)用空行将代码按照逻辑片断划分;
4)每个类声明之后应该加入空格同其他代码分开。
示例:
if (!valid_ni(ni)) { ... // program code } repssn_ind = ssn_data[index].repssn_index; repssn_ni = ssn_data[index].ni;
4、较长的语句(>80字符)要分成多行书写。
1)长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行
要进行适当的缩进,使排版整齐,语句可读。
2)若函数或过程中的参数较长,则要进行适当的划分。
3)循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式
要在低优先级操作符处划分新行,操作符放在新行之首。
示例:
perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN + STAT_SIZE_PER_FRAM * sizeof( _UL ); act_task_table[frame_id * STAT_TASK_CHECK_NUMBER + index].occupied = stat_poi[index].occupied; act_task_table[taskno].duration_true_or_false = SYS_get_sccp_statistic_state( stat_item ); report_or_not_flag = ((taskno < MAX_ACT_TASK_NUMBER) && (n7stat_stat_item_valid (stat_item)) && (act_task_table[taskno].result_data != 0)); n7stat_str_compare((BYTE *) & stat_object, (BYTE *) & (act_task_table[taskno].stat_object), sizeof (_STAT_OBJECT)); n7stat_flash_act_duration( stat_item, frame_id *STAT_TASK_CHECK_NUMBER + index, stat_object ); if ((taskno < max_act_task_number) && (n7stat_stat_item_valid (stat_item))) { ... // program code } for (i = 0, j = 0; (i < BufferKeyword[word_index].word_length) && (j < NewKeyword.word_length); i++, j++) { ... // program code } for (i = 0, j = 0; (i < first_word_length) && (j < second_word_length); ` i++, j++) { ... // program code }
5、不允许把多个短语句写在一行中,即一行只写一条语句。
一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。
6、if、for、do、while、case、switch、default等语句自占一行,且if、for、do、while等语句的执行语句部分无论多少都要加括号{}。
示例:
如下例子不符合规范:
if (pUserCR == NULL) return;
应如下书写:
if (pUserCR == NULL) { return; }
7、代码行之内应该留有适当的空格
采用这种松散方式编写代码的目的是使代码更加清晰。代码行内应该适当的使用空格。
具体如下:
1)关键字之后要留空格。像const、virtual、inline、case 等关键字之后至少要留一个空格,否则无法辨析关键字。像if、for、while 等关键字之后应留一个空格再跟左括号‘( ’, 以突出关键字。
2)函数名之后不要留空格, 紧跟左括号’(’ , 以与关键字区别。
3)‘( ’ 向后紧跟,‘ )’、‘ ,’、‘ ;’ 向前紧跟, 紧跟处不留空格。
4)‘ ,’ 之后要留空格, 如Function(x, y, z)。如果‘ ;’ 不是一行的结束符号, 其后也要留空格, 如for (initialization; condition; update)。
5)值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“ =”、“ +=” “ >=”、“ <=”、“ +”、“ *”、“ %”、“ &&”、“ ||”、“ <<” 、“ ^” 等二元操作符的前后应当加空格。
6)一元操作符如“ !”、“ ~”、“ ++”、“ --”、“ &”( 地址运算符) 等前后不加空格。
7)像“[ ]”、“ .”、“ ->” 这类操作符前后不加空格。
示例:
void foo() { …// program code } if (i == 0) { …// program code } foo->bar, foo.bar, foo[bar] i++, !i, &i i += 9, a * b
8、程序块的分界符(如'{'和'}')应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。
示例:
如下例子不符合规范:
for (...) { ... // program code } if (...) { ... // program code } void example_fun( void ) { ... // program code }
应如下书写:
for (...) { ... // program code } if (...) { ... // program code } void example_fun( void ) { ... // program code }
注释
9、源文件头部应进行注释,列出;生成日期、作者、模块目的/功能等。
示例:
/************************************************************ FileName: test.cpp Author: Version : Date: Description: // 模块描述 Version: // 版本信息 Function List: // 主要函数及其功能 1. ------- History: // 历史修改记录 <author> <time> <version > <desc> David 96/10/12 1.0 build this moudle ***********************************************************/
10、函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值等。
示例:
/************************************************* Description: // 函数功能、性能等的描述 Input: // 输入参数说明,包括每个参数的作 // 用、取值说明及参数间关系。 Output: // 对输出参数的说明。 Return: // 函数返回值的说明 Others: // 其它说明 *************************************************/
右击函数名,然后依次点击“Refacto”–>“Document Method”。
//************************************// Description: // Method: $SymbolName$// FullName: $SymbolContext$// Access: $SymbolVirtual$$SymbolPrivileges$$SymbolStatic$// Parameter: $MethodArg$// Returns: $SymbolType$// Author: xxx// Date: $DATE$// History://************************************
11、注释应该和代码同时更新,不再有用的注释要删除。
12、注释的内容要清楚、明了、不能有二义性。
13、避免在注释中使用非常用的缩写或者术语。
14、注释的主要目的应该是解释为什么这样做,而不是正在做什么。如果从上下文不容易看出作者的目的,说明程序的可读性本身存在比较大的问题。
15、避免非必要的注释。
例如:
ClassA *pA = new ClassA();//创建新实例 … …… … delete pA; //销毁对象16、注释的板式
说明:注释也需要与代码一样整齐排版
1)注释应与其描述的代码相近,对代码的注释应放在其上方或右方相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
2)注释与所描述内容进行同样的缩排。
3)将注释与其上面的代码用空行隔开。
4)变量、常量、宏的注释应放在其上方相邻位置或右方。
示例:如下例子不符合规范。
注释在代码行之下:
repssn_ind = ssn_data[index].repssn_index; repssn_ni = ssn_data[index].ni; /* get replicate sub system index and net indicator */缩进不统一:
void example_fun( void ) { /* code one comments */ CodeBlock One /* code two comments */ CodeBlock Two }
代码过于紧凑:/* code one comments */ program code one /* code two comments */ program code two17、对于所有有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其物理含义。
示例:以下都是允许的注释方式
/* active statistic task number */ #define MAX_ACT_TASK_NUMBER 1000 #define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number */18、数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释可放在此域的右方。
示例:
/* sccp interface with sccp user primitive message name */ enum SCCP_USER_PRIMITIVE { N_UNITDATA_IND, /* sccp notify sccp user unit data come */ N_NOTICE_IND, /* sccp notify user the No.7 network can not */ /* transmission this message */ N_UNITDATA_REQ, /* sccp user's unit data transmission request*/ };19、对重要变量的定义需编写注释,特别是全局变量。,更应有较详细的注释,包括对其功能、取值范围、以及存取时注意事项等说明。
示例:
/* The ErrorCode when SCCP translate Global Title failure, as follows // 变量作用、含义 0 - SUCCESS 1 - GT Table error 2 - GT error Others - not in use // 变量取值范围 only function SCCPTranslate() in this module can modify it, and other module can visit it through call the function GetGTTransErrorCode() */ // 使用方法 BYTE g_GTTranErrorCode;20、分支语句(条件分支、循环语句等)需编写注释。
21、注释不宜过多,也不能太少,源程序中有效注释量控制在20%~30%之间。
标识符命名
22、命名尽量使用英文单词,力求简单清楚,避免使用引起误会的词汇和模糊的缩写,使人产生误解。
较短的单词可通过去掉“元音”形成缩写;较长的单词可取单词的头几个字母形成缩
写;一些单词有大家公认的缩写。
示例:如下单词的缩写能够被大家基本认可
temp 可缩写为 tmp ;
flag 可缩写为 flg ;
statistic 可缩写为 stat ;
increment 可缩写为 inc ;
message 可缩写为 msg ;
23、命名规范必须与所使用的系统风格保持一致,并在同一项目中统一。
说明:
1)如在 UNIX系统,可采用全小写加下划线的风格或大小写混排的方式,但不能使用大小写与下划线混排的方式。
2)用作特殊标识如标识成员变量或全局变量的 m_和g_,其后加上大小写混排的方式是允许的。
示例:
Add_User不允许,add_user、AddUser、m_AddUser允许。
24、变量的命名可参考“匈牙利”标记法。
例外:
c++程序不建议采用匈牙利命名法。因为c++本身就是强类型语言,不需要像c一样用匈牙利命名法来强调变量类型。
有两个匈牙利命名法可以保留:m_xxxx表示类的成员变量,g_xxx表示全局变量。
25、常量、宏和模版名采用全大写的方式,每个单词间用下划线分割。
26、枚举类型enum常量应以大写字母开头或全部大写。
27、命名中若使用了特殊约定或缩写,则要有注释说明。
28、对于变量命名,禁止取单个字符(如i,j,k。。),建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i,j,k作局部循环变量是允许的。
说明:变量,尤其是局部变量,如果用单个字符表示,很容易敲错,而编译时又检查不出来,有可能为了这个小小的错误而花费大量的查错时间。
29、函数名以大写字母开头,采用谓-宾结构(动-名),且反映函数执行什么操作以及返回什么内容。
说明:
函数在表达式中使用,通常用于 if 子句,因此它们的意图应一目了然。
示例:
不好的命名:if (CheckSize(x))
没有帮助作用,因为它没有告诉我们 CheckSize 是在出错时返回 true 还是在不出错时返回 true。
好的命名:if (ValidSize(x))
则使函数的意图很明确。
30、类、结构、联合、枚举的命名须分别以C、S、U、E开头。
可读性
31、用括号明确表达式的操作顺序,避免使用默认优先级。
说明:防止阅读程序时产生误解,防止因默认的优先级与设计思想不符而导致程序出错。
32、不要编写太复杂、多用途的符合表达式。
33、涉及物理状态或者含有物理意义的常量,避免直接使用数字,必须用有意义的枚举或者常量来代替。
示例:
如下例子可读性差:
if (Trunk[index].trunk_state == 0) { Trunk[index].trunk_state = 1; ... // program code }
应改为如下形式:const int TRUNK_IDLE = 0; const int TRUNK_BUSY = 1; if (Trunk[index].trunk_state == TRUNK_IDLE) { Trunk[index].trunk_state = TRUNK_BUSY; ... // program code }34、禁止使用难以理解,容易产生歧义的语句。
示例:
如下表达式难以理解:
* stat_poi ++ += 1; * ++ stat_poi += 1;应分别改为如下:
*stat_poi += 1; stat_poi++; // 此二语句功能相当于“ * stat_poi ++ += 1; ” ++ stat_poi; *stat_poi += 1; // 此二语句功能相当于“ * ++ stat_poi += 1; ”
变量、结构
35、尽量少使用全局变量,尽量去掉没必要的公共变量。说明:公共变量是增大模块间耦合的原因之一,故应减少没必要的公共变量以降低模块间的耦合度。
36、变量,特别是指针变量,被创建之后应当及时把它们初始化,以防止未被初始化的变量当成右值使用。
说明:在c/c++中引用未经赋值的指针,经常会引起系统崩溃。
37、仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引用误用现象。
38、留心具体语言及编译器处理不同数据类型的原则及有关细节。
说明:如在C语言中,static局部变量将在内存“数据区”中生成,而非static局部变量将在“堆栈”中生成。这些细节对程序质量的保证非常重要。
39、尽量减少没有必要的数据类型默认转换与强制转换。
说明:当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。
40、当声明用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的字节顺序、使用的位域及字节对其等问题。
说明:
1)在intel CPU与SPARC CPU,在处理位域及整数时,其在内存存放的“顺序”正好相反。
2)在对齐方式下,CPU的运行效率要快一些。
函数、过程
41、调用函数要检查所有可能的返回情况,不应该的返回情况要用ASSERT来确认。
42、编写可重入函数时,应注意局部变量的使用。(……)
43、调用公共接口函数时,调用者有保障调用参数符合要求的义务。作为一种防御性的编程风格,被调用函数也应该对传入参数做必须的安全检查。
44、函数的规模尽量限制在100行以内。不包括注释和空行。
45、不能用AEESET代替必要的安全处理代码,确保发布版的程序也能够合理地处理异常情况。
例如:
void Reset(int *p) { assert(NULL != p); if(NULL != p) //不能因为前面的assert,省略此处的判断 { *p = 0; } }46、尽量写类的构造、拷贝构造、析构和赋值函数,而不使用系统缺省的。(……)
47、检查函数所有参数与非参数的有效性。
说明:
1)函数的输入主要有两种:一种是参数输入;另一种是全局变量、数据文件的输入,即非参数输入。函数在使用输入之前,应进行必要的检查。
2)不应该的入口情况要用ASSERT 来确认。
3)有时候不处理也是一种处理,但要明确哪些情况不处理。try...catch 是一种常用的不处理的处理手段。
48、函数实现中不改变内容的参数要定义成const。
示例:
int GetStrLen(const char*); int GetNumberCount(const CString&);49、函数的返回值要清楚、明了,让使用者不容易忽视错误情况。
说明:
函数的每种出错返回值的意义要清晰、明了、准确,防止使用者误用、理解错误或忽视错误返回码。
C++专用规范
50、在高警告级别下干净地编译。
使用编译器的最高警告级别。要求干净的(没有警告的)构建(build)并理解所有的警告。通过修改代码来消除警告,而不是通过降低警告级别来消除。对于明确理解其
含义,确信不会造成任何问题的警告,则可以局部关闭。
51、主动使用const,避免使用宏。
应该尽可能的使用常量而不用变量,另外在定义数值的时候,应该把 const 做为默认的选项。它是安全的,在编译的时候(参见附录C《编码安全规范》)检查,它集成在
C++的类型系统中。除非要调用一个非const 函数,否则不要强制去除const。 宏无视作用域,无视类型系统,无视所有其它的语言特性和规则,并从#define 处开始将该符号劫持。只有对少数的重要任务,宏仍是仅有的解决方案,如#include 防护哨,用于条件编译的#ifdef 和#if defined,以及用来实现assert。
52、合理使用组合和继承。
继承是C++中耦合度最强的关系之一。软件工程的一条重要原则是尽量减少耦合,在组合和继承都能均可适用的情况下,应该优先考虑使用组合。组合的意思是将一种类型
以成员变量方式嵌入相关类型中。组合有如下优点:
1)在不影响调用代码的同时也更灵活。
2)编译期绝缘性好,编译时间也能缩短。
3)代码不可预测程度降低(有些类不适合作为基类)。
53、尽可能局部地声明变量。
尽可能局部地声明每个变量,这通常是在程序具备了足够的数据来初始化变量之后,并紧接着首次使用该变量之前。
例外:
1)有时将变量从循环内提出到循环外是有益的。
2)由于常量不增加状态,因此本条对常量不适用。
54、通过值,指针,或引用适当地取得参数。
对仅用于输入的参数来说:
1)始终给仅用于输入的指针或引用参数加上const 限定符。
2)最好是通过原始类型(例如:char,float)和可以通过值来复制并且复制成本低的值对象(例如:Point complex<float>)来取得参数。
3)对其它自定义类型的输入,最好是通过const 引用来取得。
4)如果函数需要参数的复本,那么可以考虑用传递值来代替传递引用。从概念上说,这等价于取得一个 const 引用再做一次复制,它可以帮助编译器更好地优化掉临时对象。
对输出或输入/输出参数来说:
1)如果参数是可选的(因此调用方可以传递空指针来表示“不可用”或“不关心”的值),或者函数要保存指针的一个复本或操控参数的所有权,那么最好是通过(智能)指针传递。
2)如果参数是必需的,而且函数无需保存指向该参数的指针或无需操控参数的所有权,那么最好是通过引用传递。这表明该参数是必需的,并让调用方来负责提供一个有效的对象。
- 【c++】编码规范及相应的配置方法
- 编码规范及编码规范的意义
- C语言的编码规范
- Android项目及编码的规范
- Android 项目及编码的规范
- unicode及编码的规范问题
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Google的Objective-C编码规范
- Linux下的C语言编码规范
- 一些Objective-C的编码规范
- C语言良好的编码规范
- 编码规范,objective-c编码规范
- 八、动态方法的调用和使用通配符定义action
- POJ 1284 Primitive Roots 已翻译
- 练习c语言
- 转战Hexo
- 【学习】彻底理解树状数组
- 【c++】编码规范及相应的配置方法
- 函数
- 终止进程的工具kill,killall,pkill和xkill
- 十、自定义类型转换器
- 责任链模式
- hive删除表错误
- 跟踪算法
- wireshark 相关提示
- Eclipse如何修改eclipse默认的工作空间路径