C++编程规范文档程序员必备.docx
《C++编程规范文档程序员必备.docx》由会员分享,可在线阅读,更多相关《C++编程规范文档程序员必备.docx(17页珍藏版)》请在冰豆网上搜索。
![C++编程规范文档程序员必备.docx](https://file1.bdocx.com/fileroot1/2023-2/3/244022b2-a69d-4d34-9454-994abee00243/244022b2-a69d-4d34-9454-994abee002431.gif)
C++编程规范文档程序员必备
目录
一般原则…………………………………………………………………………………………………2
标识符……………………………………………………………………………………………….4
排版………………………………………………………………………………………………7
注视………………………………………………………………………………………………10
✧采用与操作系统或开发工具的风格一致的标识符命名规则。
✧标识符一般由一个或多个单词组成。
✧变量命名禁止取单个字符。
✧不要仅依赖大小写来区分相似的标识符。
✧枚举、常量、宏的所有字母大写,用”_”分隔。
✧宏定义表达式时,注意使用完整的括号。
✧避免使用一个或两个下划线开头的标识符。
✧程序块要采用缩进风格编写,缩进的空格数为4个。
✧在循环、判断等语句中,若有较长的表达式或语句,则要进行适应的划分,操作符放在新行之首。
✧若函数的参数较长,则要进行适当的划分。
✧不要把多条语句写在一行。
✧if、for、while、do等语句自占一行,执行语句不得紧跟其后。
不论执行语句有多少都要加{}。
✧大括号”{“和“}”应各独占一行并且位于关键字的同一列。
✧对于switch语句的每一个分支,应该有break,必须有default分支。
✧在二元操作符的两侧添加空格,但”.”和“->”除外。
✧注释的内容要清楚、明了,含义准确,防止注释二义性。
✧写代码的同时编写注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
✧注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
✧注释与所描述内容进行同样的缩进排版。
✧注释应考虑程序易读及外观排版的因素,只使用一种语言注释代码。
✧在每个文件的顶部添加文件说明。
一般原则
1.编写简单的代码。
把复杂的语句和函数分解成更简单的片段。
对复杂的逻辑要有明确的注释。
2.显式的使用C/C++的特性。
避免使用C/C++的隐含特性。
例如:
当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化。
注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认的优先级。
若是这些细节若考虑不周,就很有可能留下隐患。
例如:
charhigh,low;
shortword;
word=high<<8|low;
应该写成:
word=((short)high<<8)|(short)low;
3.改进模块结构,降低函数间的耦合度,并提高模块的独立性以及代码可读性、效率和可维护性。
优化时,要遵守以下原则:
1)限制函数的规模:
函数的规模尽量限制在200行以内,过大的要进行分解;
2)降低函数间接口的复杂度;
3)提高函数内聚(单一功能的函数内聚最高);
4)数据结构设计要合理。
要考虑向前兼容和以后版本的升级,并为某些未来可能的应用预留一些空间等。
例如:
structFOO
{
chara;
shortb;
intc;
chard;
};
结构体FOO的设计应该考虑数据对齐(在32位系统上一般是4字节对齐),还应预留将来升级的空间。
结构体FOO可以设计成:
structFOO
{
chara;
chard;
shortb;
intc;
intr[4];//Reserved.
};
4.检查函数所有输入参数和非输入参数(全局变量,数据文件等)的有效性。
BOOLSetStreamType(HANDLEhChannel,STREAM_TYPEStreamType)
{
if(NULL==hChannel)
{
returnFALSE;
}
if(STREAM_TYPE_VIDEO!
=StreamType
||STREAM_TYPE_AUDIO!
=StreamType
||STREAM_TYPE_AVSYNC!
=StreamType)
{
returnFALSE;
}
//programcode
returnTRUE;
}
5.调用外部函数时,对返回值要做判断。
对外提供的API函数要处理好函数的返回值。
FILE*stream=fopen("crt_fopen.c","r");
if(NULL==stream)
{
printf("Thefile'crt_fopen.c'wasnotopened\n");
}
else
{
//programcode
}
6.保持一致的风格。
在一个项目中,标识符、排版、注释的风格保持前后一致。
不要在前期使用一种风格后期又改变。
7.编写代码时,要注意随时保存,并及时提交到服务器上。
防止由于断电、硬盘损坏等原因造成代码丢失。
标识符
8.采用与操作系统或开发工具的风格一致的标识符命名规则。
例如,Windows程序的标识符通常采用“大小写”混排的方式,如AddChild。
而Unix/Linux程序的标识符通常采用“小写加下划线”的方式,如add_child。
别把这两类风格混在一起用。
最好使用完整的单词,或大家能够可以理解的缩写,避免使人产生误解。
9.标识符一般由一个或多个单词组成。
变量名应当使用“名词”,或者“形容词+名词”。
例如:
intnCode;
intm_nMaxWidth;
doublefYScale;
函数名应当使用“动词”或者“动词+名词”的形式。
例如:
BOOLLoad();
LPCTSTRGetFileName();
建议使用以下单词来命名函数:
create
destroy
open
close
add
remove
release
find
first
last
begin
end
previous
next
load
save
10.变量命名禁止取单个字符。
变量,尤其是局部变量,如果用单个字符表示,很容易敲错,而编译时又检查不出来。
有可能为了这个小小的错误而花费大量的查错时间。
但i、j、k作为局部循环变量,x、y、z作为局部几何变量是允许的。
11.不要仅依赖大小写来区分相似的标识符。
例如:
voidfoo(intx);
voidFOO(intx);//C++编译器中,函数foo与FOO容易混淆
12.枚举、常量、宏的所有字母大写,用“_”分隔。
例如:
enum{MAX_LENGTH=100};
#defineMAX_ECODE_COUNT16
constDWORDZERO_VALUE=0;
13.宏定义表达式时,注意使用完整的括号。
如下宏表达式存在隐患:
#defineONE_MB1024*1024
#defineARRAY_SIZE(a)sizeof(a)/sizeof(a[0])
应该改成:
#defineONE_MB(1024*1024)
#defineARRAY_SIZE(a)(sizeof(a)/sizeof((a)[0]))
14.避免使用一个或两个下划线开头的标识符。
标准C(ANSIC)保留了以两个下划线开头的标识符给编译器内部使用,以一个下划线开头的标识符给标准库函数使用。
避免使用这样的标识符,可以排除与编译器或标准库的名称混乱。
15.标识符可以用首字母大写的方式来区分,也可以在单词间用“_”分隔。
例如:
classCVideoConfig;
voidOnLButtonDown(UINTnFlags,CPointpoint);
intnDspCount;
BOARD_INFOboard_info;
16.给标识符加上合适的前缀。
变量名一般由“作用域前缀+类型前缀+词组”组成。
不同的操作系统可能有不同的标识符习惯前缀。
可以根据实际情况来使用前缀。
作用域前缀
说明
(无)
局部变量
m_
类/结构体成员变量
sm_
类/结构体静态成员变量
s_
静态变量(static)
g_
外部全局变量(global)
类型前缀
说明
i或n
有符号整型变量(int、short、long)
dw或u
无符号长整型(DWORD、unsignedlong、unsignedint)
w或u
无符号短整型(WORD、unsignedshort)
c
字符型变量(char)
cb
字节变量(BYTE、unsignedchar)
b
布尔型变量(bool、BOOL)
f
浮点型变量(float、double)
sz
以’\0’结尾的字符串
p或lp
指针变量
h
句柄
pfn
函数指针
17.建议不要使用全局变量。
若一定要使用,最好把全局变量写到全局结构体中。
可以按以下方式使用全局变量。
typedefstruct_T1900_DEVICE
{
HANDLEhThread;
PCOMMAND_DISPATCH_ROUTINEpCommandRoutine;
//Contextofthecommanddispatchroutine
PVOIDpCommandContext;
}T1900_DEVICE,*PT1900_DEVICE;
T1900_DEVICEg_Device;
排版
18.程序块要采用缩进风格编写,缩进的空格数为4个。
对于由开发工具自动生成的代码可以有不一致。
但要避免使用TAB缩进,因为不同编辑器TAB键设置的空格数目不一定,可能造成程序布局不整齐。
19.在循环、判断等语句中,若有较长的表达式或语句,则要进行适应的划分,操作符放在新行之首。
可以写成如下形式。
if((dwDeviceIndex
==pVideoPreview->m_pChannel->m_pDevice->m_dwIndexInAv)
&&
(Setting.dwWidth>dwLimitedWidth
||Setting.dwHeight>dwLimitedHeight))
{
//Dosomething
}
intnAccess=WORLD_READ
||GROUP_READ
||…
||WORLD_WRITE
||GROUP_WRITE
||…;
for(i=0,j=0;
(ii++,j++)
{
//programcode
}
20.若函数的参数较长,则要进行适当的划分。
【必须】
voidCVideoPreview:
:
SortArea(
INconstvector&StartedTaskList,
INDWORDdwDeviceIndex,
OUTvector&AreaList);
n7stat_str_compare((BYTE*)&stat_object,
(BYTE*)&(act_task_table[taskno].stat_object),
sizeof(STAT_OBJECT));
21.不要把多条语句写在一行。
一行代码只做一件事情,如只定义一个变量,或只写一条语句。
这样的代码容易阅读,并且方便于写注释。
如下例子不符合规范。
intnWidth,nHeight;
nWidth=352;nHeight=288;
应如下书写。
intnWidth;
intnHeight;
nWidht=352;
nHeight=288;
22.if、for、while、do等语句自占一行,执行语句不得紧跟其后。
不论执行语句有多少都要加{}。
这样可以防止书写失误。
如下例子不符合规范:
if(NULL==pUser)return;
应如下书写:
if(NULL==pUser)
{
return;
}
23.大括号“{”和“}”应各独占一行并且位于关键字的同一列。
【必须】
BOOLExampleFun()
{
for(inti=0;i<100;i++)
{
//programcode
if(bSuccess)
{
returnTRUE;
}
else
{
returnFALSE;
}
}
24.对于switch语句的每一个分支,应该有break,必须有default分支。
switch语句应该写成如下形式:
switch(nType)
{
case0:
break;
case1:
break;
default:
break;
}
25.在二元操作符的两侧添加空格,但“.”和“->”除外。
Setting.dwWidth=Setting.rcDest.right-Setting.rcDest.left;
dwTotoalArea+=Setting.dwWidth*Setting.dwHeight;
Setting.dblScale=1.0;
26.一行代码保持在80个字符左右。
这样能保正代码在各种编辑器中,都能显示在屏幕中,避免了打印时换行。
27.关键字之后要留空格。
如“if”、“for”、“while”、“catch”等关键字之后应留一个空格再跟左括号“(”,以突出关键字。
函数名之后不要留空格,而是紧跟左括号“(”,以与关键字区别。
28.if语句最好加上else分支,对没有else分支的语句要小心对待。
else分支能够保证逻辑的严谨性
29.合理的空行。
空行起着分隔程序段落的作用。
空行得体(不过多也不过少)将使程序的布局更加清晰。
空行不会浪费内存,虽然打印含有空行的程序是会多消耗一些纸张,但是值得。
所以不要舍不得用空行。
在每个类声明之后、每个函数定义结束之后都要加空行。
在一个函数体内,逻辑上密切相关的语句之间不加空行,其它地方应加空行分隔
注释
30.注释的内容要清楚、明了,含义准确,防止注释二义性。
错误的注释不但无益反而有害。
31.写代码的同时编写注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
删除已经无用注释。
修改已有的代码,必须添加修改人等备注信息。
//2010-5-10,DengFengfixedaBlueScreenbug.
//Bar3Length=BAR3_LENGTH;
Bar3Length=(pde->ChipType==CHIP_HI3511)
?
BAR3_LENGTH_HI3511:
BAR3_LENGTH_HI3520;
//DengFengend.
32.注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
#defineMAX_FRAMES1000//Maxcountintheframelist
#defineABANDON_FRAMES150//Abandonframecount
//ReadPCIconfigspacefromBAR5.
*(PULONG)Irp->AssociatedIrp.SystemBuffer=ReadPciBar(
pde,BAR5,AccessPciBar->Address);
//Setreturnedbytenumber.
Irp->IoStatus.Information=(ULONG_PTR)sizeof(ULONG);
33.注释与所描述内容进行同样的缩进排版。
可使程序排版整齐,并方便注释的阅读与理解。
switch(nSBCode)
{
//scrolltobottom
caseSB_BOTTOM:
break;
//scrolltotop
caseSB_TOP:
break;
default:
break;
}
34.注释应考虑程序易读及外观排版的因素,只使用一种语言注释代码。
在不影响程序易读性和外观排版的前提下,注释语言可以使用中文或英文。
出于对维护人员的考虑,建议使用中文
35.在每个文件的顶部添加文件说明。
下面的文件头说明比较标准,并不局限于此格式。
建议下列信息要包含在内:
////////////////////////////////////////////////////////////////////////////////
//Copyright(C),2009-20XX,XXXXX.
//THISISANUNPUBLISHEDWORKCONTAININGCONFIDENTIALANDPROPRIETARY
//
////////////////////////////////////////////////////////////////////////////////
//FileName:
//Author:
//Version:
//Date:
//Description:
(abriefdescriptionofthefile'scontents)
//History:
(modifiedhistory)
////////////////////////////////////////////////////////////////////////////////
或者使用中文的文件头:
////////////////////////////////////////////////////////////////////////////////
//版权所有,2009-20XX,XXX公司。
//该文件是未公开的,包含了XXXX公司机密和专利内容。
////////////////////////////////////////////////////////////////////////////////
//文件名:
//作者:
//版本:
//日期:
//描述:
(文件内容的简单描述)
//历史记录:
(修改历史)
////////////////////////////////////////////////////////////////////////////////
根据文件创建的时间,确定版权时间。
修订者需要更新文件的历史信息。
36.一般情况下,源程序有效注释量必须在20%以上。
注释的原则是有助于对程序的阅读理解,在该加的地方都加上。
注释不宜太多,也不能太少。
注释语言必须准确、易懂、简洁。
37.通过对变量、结构、宏、函数等正确的命名以及合理地组织代码的结构,使代码成为自注释的。
清晰准确的函数、变量等的命名,可增加代码可读性,并减少不必要的注释。
38.在代码的功能、意图层次上进行注释,提供有用、额外的信息。
注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,避免重复注释信息。
如下注释意义不大。
//ifreceive_flagisTRUE
if(receive_flag)
而如下的注释则给出了额外有用的信息。
//ifmtpreceiveamessagefromlinks
if(receive_flag)
39.对变量的定义、分支语句、循环语句等,要编写注释。
这些语句往往是程序实现某一特定功能的关键。
对于维护人员来说,良好的注释能帮助更好的理解程序,有时甚至优于看设计文档。
40.在重要的函数前添加函数说明。
下面函数说明比较标准,并不局限于此格式。
建议下列信息要包含在内:
////////////////////////////////////////////////////////////////////////////////
//Function:
//Description:
//Parameters:
(listallinputandoutputparameters)
//Return:
//Remarks:
////////////////////////////////////////////////////////////////////////////////
或者用中文的函数头:
////////////////////////////////////////////////////////////////////////////////
//函数名:
//描述:
//参数:
(列出所有输入、输出参数)
//返回值:
//说明:
////////////////////////////////////////////////////////////////////////////////