CC++语言编码规范.docx
- 文档编号:23190882
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:17
- 大小:22.31KB
CC++语言编码规范.docx
《CC++语言编码规范.docx》由会员分享,可在线阅读,更多相关《CC++语言编码规范.docx(17页珍藏版)》请在冰豆网上搜索。
CC++语言编码规范
CMMIML-3v1.2
C/C++语言编码规范(TS)
文件编号:
TS-G-05
编制
日期
审核
日期
批准
日期
变更记录
版本号
变更日期
变更类型
变更人
变更摘要
备注
目录
变更记录2
1.排版规范4
1.1.缩进4
1.2.空行4
1.3.分行4
1.4.分界符5
1.5.空格6
1.6.宏定义6
1.7.类定义6
1.8.其他7
2.命名规范8
2.1.原则8
2.2.命名注释8
2.3.命名风格统一8
2.4.变量命名9
3.变量结构10
3.1.赋值检查10
3.2.变量初始化10
3.3.单一功能结构体10
3.4.结构中的元素个数11
4.函数过程13
4.1.避免直接使用函数参数13
4.2.简单功能函数14
4.3.避免多参数函数14
4.4.参数检查15
4.5.重复代码16
5.注释规范17
5.1.文件注释17
5.2.函数注释18
5.3.代码注释18
5.4.注释位置19
1.排版规范
1.1.缩进
程序块要采用缩进风格编写,缩进的长度为4个空格,方式为IDE自动缩进或TAB缩进。
一行程序以小于65字符为宜,不要写得过长。
对于由开发工具自动生成的代码可以有不一致。
函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case语句下的情况处理语句也要遵从语句缩进风格。
1.2.空行
相对独立的程序块之间、变量说明之后必须加空行。
示例:
if(!
valid_ni(ni))
{
...//programcode
}
//空行
repssn_ind=ssn_data[index].repssn_index;
repssn_ni=ssn_data[index].ni;
1.3.分行
当语句超出或即将超出规定的列宽,遵循以下规则进行换行:
1)在逗号后换行。
2)在运算符,关键字前换行。
3)选择在较高级别(higher-level)的运算符处断开。
4)新的一行应该与上一行同一级别表达式的开头处对齐。
5)如果以上规则导致你的代码混乱或者使你的代码都堆挤在右边,那就代之以缩进8个空格。
6)规则1优先于规则2。
当以上规则会导致代码混乱的时候自己采取更灵活的换行规则。
示例:
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);
1.4.分界符
程序块的分界符(如C/C++语言的大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。
在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。
示例:
for(...)
{
...//programcode
}
if(...)
{
...//programcode
}
else
{
...//programcode
}
voidexample_fun(void)
{
...//programcode
}
1.5.空格
1.关键字后需要有空格
2.运算符前后要有空格
3.功能段之间可以适当使用空格
4.要遵循手写英语中标点符号的规范,’,’和’;’后要加空格,’(’除外,
例如:
background=newColor(red,green,blue);
在操作符前后可以使用空格使代码增强代码可读性。
对于与英文意义不同的操作符不遵循上述规则,例如:
’.’和’->’后不用空格。
1.6.宏定义
在宏定义中,尽量使用下面结构
#ifndef
#define
#endif
1.7.类定义
每个类定义中都要依次包含‘public’,‘protected’,‘private’部分。
每个部分中要最先给出构造函数和析构函数,成员函数按照函数名字母排序。
1.成员变量用m_做前缀;
2.类名已大写C开头,后面用pascal命名规则;
3.成员函数命名也按pascal命名规则
如:
classCMyClass
{
public:
voidDisplay();
private:
intm_iCount;
};
1.8.其他
1.每行只能写一条代码,且厂度不超过80个字符;
2.常量应定义为宏,枚举;
3.左{后不可以出现代码,右}前不可出现代码;
4.设计常量判断语句要把常量放左边,这样可以防止把==写成=;
5.所有新变量在第一次使用都要进行初始化;
6.对有返回值的函数要对返回值进行判断;
7.设计到锁问题都需要成对的出现;
2.命名规范
2.1.原则
能清楚表达对象的含义,尽可能避免二义性。
2.2.命名注释
命名中若使用特殊约定或缩写,则要有注释说明。
应该在源文件的开始之处,对文件中所使用的缩写或约定,特别是特殊的缩写,进行必要的注释说明。
2.3.命名风格统一
己特有的命名风格,要自始至终保持一致,不可来回变化。
个人的命名风格,在符合所在项目组或产品组的命名规则的前提下,才可使用。
(即命名规则中没有规定到的地方才可有个人命名风格)。
用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
示例面是一些在软件中常用的反义词组:
add/removebegin/endcreate/destroy
insert/deletefirst/lastget/release
increment/decrementput/get
add/deletelock/unlockopen/close
min/maxold/newstart/stop
next/previoussource/targetshow/hide
send/receivesource/destination
cut/pasteup/downget/set
示例:
intmin_sum;
intmax_sum;
intadd_user(BYTE*user_name);
intdelete_user(BYTE*user_name);
2.4.变量命名
命名通常使用一个或多个单词,不用词组,使用简单结构表示。
例如:
用‘parameter_count’替代‘number_of_parameters’。
命名可以用数字、动词、形容词、副词,不要用前置词、代词等易混淆概念的词。
禁止取单个字符(如i、j、k...),建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i、j、k作局部循环变量是允许的。
变量,尤其是局部变量,如果用单个字符表示,很容易敲错(如i写成j),而编译时又检查不出来,有可能为了这个小小的错误而花费大量的查错时间。
除了编译开关/头文件等特殊应用,应避免使用_EXAMPLE_TEST_之类以下划线开始和结尾的定义。
3.变量结构
3.1.赋值检查
当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。
若有必要应进行合法性检查,以提高代码的可靠性、稳定性。
3.2.变量初始化
变量使用前需要初始化,在C/C++中引用未经赋值的指针,经常会引起系统崩溃。
3.3.单一功能结构体
设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。
结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。
示例:
如下结构不太清晰、合理。
typedefstructSTUDENT_STRU
{
unsignedcharname[8];/*student'sname*/
unsignedcharage;/*student'sage*/
unsignedcharsex;/*student'ssex,asfollows*/
/*0-FEMALE;1-MALE*/
unsignedchar
teacher_name[8];/*thestudentteacher'sname*/
unisgnedchar
teacher_sex;/*histeachersex*/
}STUDENT;
若改为如下,可能更合理些。
typedefstructTEACHER_STRU
{
unsignedcharname[8];/*teachername*/
unisgnedcharsex;/*teachersex,asfollows*/
/*0-FEMALE;1-MALE*/
}TEACHER;
typedefstructSTUDENT_STRU
{
unsignedcharname[8];/*student'sname*/
unsignedcharage;/*student'sage*/
unsignedcharsex;/*student'ssex,asfollows*/
/*0-FEMALE;1-MALE*/
unsignedintteacher_ind;/*histeacherindex*/
}STUDENT;
3.4.结构中的元素个数
结构中元素的个数应适中。
若结构中元素个数过多可考虑依据某种原则把元素组成不同的子结构,以减少原结构中元素的个数。
增加结构的可理解性、可操作性和可维护性。
示例:
typedefstructPERSON_BASE_INFO_STRU
{
unsignedcharname[8];
unsignedcharage;
unsignedcharsex;
}PERSON_BASE_INFO;
typedefstructPERSON_ADDRESS_STRU
{
unsignedcharaddr[40];
unsignedcharcity[15];
unsignedchartel;
}PERSON_ADDRESS;
typedefstructPERSON_STRU
{
PERSON_BASE_INFOperson_base;
PERSON_ADDRESSperson_addr;
}PERSON;
4.函数过程
4.1.避免直接使用函数参数
将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。
对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
下函数的实现不太好:
voidsum_data(unsignedintnum,int*data,int*sum)
{
unsignedintcount;
*sum=0;
for(count=0;count { *sum+=data[count];//sum成了工作变量,不太好。 } } 若改为如下,则更好些: voidsum_data(unsignedintnum,int*data,int*sum) { unsignedintcount; intsum_temp; sum_temp=0; for(count=0;count { sum_temp+=data[count]; } *sum=sum_temp; } 4.2.简单功能函数 虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。 功能不明确较小的函数,特别是仅有一个上级函数调用它时,应考虑把它合并到上级函数中,而不必单独存在。 如下语句的功能不很明显: value=(a>b)? a: b; 改为如下就很清晰了: intmax(inta,intb) { return((a>b)? a: b); } value=max(a,b); 或改为如下。 #defineMAX(a,b)(((a)>(b))? (a): (b)) value=MAX(a,b); 4.3.避免多参数函数 本建议目的是防止函数间的控制耦合。 调度函数是指根据输入的消息类型或控制命令,来启动相应的功能实体(即函数或过程),而本身并不完成具体功能。 控制参数是指改变函数功能行为的参数,即函数要根据此参数来决定具体怎样工作。 非调度函数的控制参数增加了函数间的控制耦合,很可能使函数间的耦合度增大,并使函数的功能不唯一。 非调度函数应减少或防止控制参数,尽量只使用数据参数。 如下函数构造不太合理: intadd_sub(inta,intb,unsignedcharadd_sub_flg) { if(add_sub_flg==INTEGER_ADD) { return(a+b); } else { return(a-b); } } 不如分为如下两个函数清晰: intadd(inta,intb) { return(a+b); } intsub(inta,intb) { return(a-b); } 4.4.参数检查 检查函数所有非参数输入的有效性,如数据文件、公共变量等。 函数的输入主要有两种: 一种是参数输入;另一种是全局变量、数据文件的输入,即非参数输入。 函数在使用输入之前,应进行必要的检查。 在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责。 但函数的提供者也要对输出做基本的合法性检查。 4.5.重复代码 如果多段代码重复做同一件事情,那么在函数的划分上可能存在问题。 若此段代码各语句之间有实质性关联并且是完成同一件功能的,那么可考虑把此段代码构造成一个新的函数。 5.注释规范 5.1.文件注释 文件头部应进行注释,注释必须列出: 版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 示例: 下面这段文件注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************* Copyright(C),19xx-20xxInfocore.Co.Ltd. Filename: //文件名 Author: Version: Date: //作者、版本及完成日期 Description: //用于详细说明此程序文件完成的主要功能,与其他模块 //或函数的接口,输出值、取值范围、含义及参数间的控 //制、顺序、独立或依赖等关系 FunctionList: //主要函数列表,每条记录应包括函数名及功能简要说明 1..... History: //修改历史记录列表,每条修改记录应包括修改日期、修改 //者及修改内容简述 1.Date: Author: Modification: 2.... *************************************************/ 5.2.函数注释 函数头部应进行注释,列出: 函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。 下面这段函数的注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************* Function: //函数名称 Description: //函数功能、性能等的描述 Calls: //被本函数调用的函数清单 CalledBy: //调用本函数的函数清单 TableAccessed: //被访问的表(此项仅对于牵扯到数据库操作的程序) TableUpdated: //被修改的表(此项仅对于牵扯到数据库操作的程序) Parameter: //输入`输出参数说明,包括每个参数的作 //用、取值说明及参数间关系。 Return: //函数返回值的说明 Others: //其它说明 *************************************************/ 5.3.代码注释 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。 不再有用的注释要删除。 修改他人的代码时应该将其本来代码注释掉后重新编写(并标明修改人,修改日期,问题描述),而不能简单的删除后用自己的代码代替。 在代码的功能、意图层次上进行注释,提供有用、额外的信息。 注释格式尽量统一,建议使用“/*……*/”。 注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。 示例: 如下注释意义不大。 /*ifreceive_flagisTRUE*/ if(receive_flag) 而如下的注释则给出了额外有用的信息。 /*ifmtpreceiveamessagefromlinks*/ if(receive_flag) 5.4.注释位置 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。 如下例子不符合规范: 例1: ……//code /*getreplicatesubsystemindexandnetindicator*/ repssn_ind=ssn_data[index].repssn_index; repssn_ni=ssn_data[index].ni; 例2: repssn_ind=ssn_data[index].repssn_index; repssn_ni=ssn_data[index].ni; /*getreplicatesubsystemindexandnetindicator*/ 应如下书写 ……//code /*getreplicatesubsystemindexandnetindicator*/ repssn_ind=ssn_data[index].repssn_index; repssn_ni=ssn_data[index].ni;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CC 语言 编码 规范