for(initialization;condition;update)
{
dosomething();
}
//空行
other();
for(initialization;condition;update)
dosomething();
other();
图5 风格良好的代码行(左),与风格不良的代码行(右)
15.2.3 尽可能在定义变量的同时初始化该变量。
若变量的引用处与其定义处相隔比较远,变量的初始化易被忘记。
若引用了未被初始化的变量,易导致程序错误。
1示例:
intwidth=10;//定义并初绐化width
intheight=10;//定义并初绐化height
intdepth=10;//定义并初绐化depth
15.3 代码行内的空格
voidFunc1(intx,inty,intz);//良好的风格
voidFunc1(intx,inty,intz);//不良的风格
if(year>=2000)//良好的风格
if(year>=2000)//不良的风格
if((a>=b)&&(c<=d))//良好的风格
if(a>=b&&c<=d)//不良的风格
for(i=0;i<10;i++)//良好的风格
for(i=0;i<10;i++)//不良的风格
for(i=0;I<10;i++)//过多的空格
x=a
a:
b;//良好的风格
x=a
a:
b;//不好的风格
int*x=&y;//良好的风格
int*x=&y;//不良的风格
array[5]=0;//不应写成array[5]=0;
a.Function();//不应写成a.Function();
b->Function();//不应写成b->Function();
图6 代码行内的空格
15.3.1 关键字之后应留空格。
如if、for、while等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。
15.3.2 函数名之后应不留空格,紧跟左括号‘(’,以与关键字区别。
15.3.3 ‘(’后面应不留空格,‘)’、‘,’、‘;’前面应不留空格。
15.3.4 ‘,’之后应留空格,如Function(x,y,z)。
若‘;’不是一行的结束符号,其后应留空格,如for(initialization;condition;update)。
15.3.5 赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应加空格。
15.3.6 一元操作符如“!
”、“~”、“++”、“--”、“&”(地址运算符)等前后应不加空格。
15.3.7 “[]”、“.”、“->”等操作符前后应不加空格。
1注:
对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格,如for(i=0;i<10;i++)和if((a<=b)&&(c<=d))
15.4 对齐
voidFunction(intx)
{
…//programcode
}
voidFunction(intx){
…//programcode
}
if(condition)
{
…//programcode
}
else
{
…//programcode
}
if(condition){
…//programcode
}
else{
…//programcode
}
for(initialization;condition;update)
{
…//programcode
}
for(initialization;condition;update){
…//programcode
}
While(condition)
{
…//programcode
}
while(condition){
…//programcode
}
若出现嵌套的{},则使用缩进对齐,如:
{
…
{
…
}
…
}
图7 风格良好的对齐(左),与风格不良的对齐(右)
15.4.1 程序块应采用缩进风格编写,缩进的空格数为4个。
2注:
对于由开发工具自动生成的代码可以有不一致。
15.4.2 对齐只使用空格键,不使用TAB键。
3注:
以免用不同的编辑器阅读程序时,因TAB键所设置的空格数目不同而造成程序布局不整齐,不应使用BC作为编辑器合版本,因为BC会自动将8个空格变为一个TAB键,因此使用BC合入的版本大多会将缩进变乱。
15.4.3 程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。
(见图7)
15.4.4 在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。
(见图8)
for(...)
{
...//programcode
}
if(...)
{
...//programcode
}
voidexample_fun(void)
{
...//programcode
}
for(...){
...//programcode
}
if(...)
{
...//programcode
}
voidexample_fun(void)
{
...//programcode
}
图8 风格良好的分界(左),与风格不良的分界(右)
15.5 长行拆分
15.5.1 代码行最大长度宜控制在120个字符以内。
15.5.2 长表达式宜在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。
拆分出的新行应进行适当的缩进,使排版整齐,语句可读(见图8)。
if((very_longer_variable1>=very_longer_variable12)
&&(very_longer_variable3<=very_longer_variable14)
&&(very_longer_variable5<=very_longer_variable16))
{
dosomething();
}
virtualCMatrixCMultiplyMatrix(CMatrixleftMatrix,
CMatrixrightMatrix);
for(very_longer_initialization;
very_longer_condition;
very_longer_update)
{
dosomething();
}
图9 长行的拆分
15.5.3 若函数或过程中的参数较长,则要进行适当的划分。
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);
图10 参数的拆分
15.5.4 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。
4注:
采用这种松散方式编写代码的目的是使代码更加清晰。
由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如果语句已足够清晰则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格,因为在C/C++语言中括号已经是最清晰的标志了。
在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。
给操作符留空格时不要连续留两个以上空格。
15.6 注释
15.6.1 概述
注释分为序言性注释和功能性注释:
11——序言性注释通常置于每一个程序模块的开头部分,给出程序的整体说明,对于理解程序具有引导作用;
12——功能性注释嵌在源程序体中,用以描述其后的语句或程序段在做什么工作。
15.6.2 注释行的数量不得少于整个源程序的1/10。
15.6.3 单行注释原则上不得超过可视窗口宽度。
15.6.4 若代码本来就是清楚的,则不必加注释。
2示例:
i++;//i加1,多余的注释
15.6.5 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
不再有用的注释应删除。
在存档的某一版本的源代码中不得存在由于调试而留下的大篇注释。
15.6.6 注释应当准确、易懂,防止注释有二义性。
15.6.7 尽量避免在注释中使用缩写,特别是不常用缩写。
15.6.8 注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。
(见图11)
15.6.9 在同一函数或模块中的注释应尽量对齐,如下例所示:
3示例:
BOOLbReturnCache;//是否将Cache中的内容返回客户端
HANDLEFileToWrite;//用来写数据的文件
DWORDBytesWritten;//写入的数据长度
/*getreplicatesubsystemindexandnetindicator*/
repssn_ind=ssn_data[index].repssn_index;
repssn_ni=ssn_data[index].ni;
例1:
/*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*/
图11 风格良好的注释(左),与风格不良的注释(右)
15.6.10 当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读(见图12)。
/*
*函数介绍:
*输入参数:
*输出参数:
*返回值:
*/
voidFunction(floatx,floaty,floatz)
{
…
}
if(…)
{
…
while(…)
{
…
}//endofwhile
…
}//endofif
图12 程序的注释
15.6.11 注释与所描述内容进行同样的缩排。
5注:
可使程序排版整齐,并方便注释的阅读与理解。
4示例:
如下例子,排版不整齐,阅读不方便。
voidexample_fun(void)
{
/*codeonecomments*/
CodeBlockOne
/*codetwocomments*/
CodeBlockTwo
}
应改为如下布局。
voidexample_fun(void)
{
/*codeonecomments*/
CodeBlockOne
/*codetwocomments*/
CodeBlockTwo
}
15.6.12 将注释与其上面的代码用空行隔开。
5示例:
如下例子,显得代码过于紧凑。
/*codeonecomments*/
programcodeone
/*codetwocomments*/
programcodetwo
应如下书写
/*codeonecomments*/
programcodeone
/*codetwocomments*/
programcodetwo
15.6.13 函数注释(序言性注释)
15.6.13.1 单元文件宜不超过1000行(包括注释),复杂的组件单元可以不受此限制.
15.6.13.2 每个函数或过程代码必须有注释文字,每个函数体中,每一小功能段都应有注释。
15.6.13.3 函数定义之前必须有对整个函数的描述,注释格式如下
/*****************************************************************************
【函数名称】(必需)
【函数功能】(必需)
【参数】(若有参数则必需注明)
【全局变量】(可选)
【返回值】(若有返回值则必需注明)
【备注】(可选)
【开发者及日期】(若与头文件注释中的开发者为不同的人,则必需注明)
【版本】(若与头文件注释中的版本不同,则必需注明)
【更改记录】(若有修改,则必需注明)
[最后修改]
[修改日期]
更改原因概要
[版本]
【使用情况】(可选)
*****************************************************************************/
注释内容说明:
函数名称:
应包括函数名及参数;
参数:
在本项中标明是输入参数(用[in]表示)还是输出参数(用[out]表示);
全局变量:
该函数访问的全局变量和成员全局变量;
版本:
如1.0;
更改记录:
每次改动时增加一行注释,说明更改标识,更改日期,人,版本,更改原因概要;
使用情况:
即函数的调用情况,被调用的次数;
6示例:
/*****************************************************************************
【函数名称】
intMy_GetLastModifedTime(CStringstrFileName,char*FileTime,long*cl)
【函数功能】
寻找目标文件,从中读取Last-Modified:
信息、Contene-Length信息
【参数】
FileName[in]指向目标文件(从URL而来,需要转换,与目标文件一一对应)
FileTime[out]获取的Last-Modified:
信息
cl[out]获取的Contene-Length信息
【返回值】
1文件存在,并从中取得Last-Modified:
信息
-1else
【备注】
使用了StrStrI函数,所以必须includeshlwapi.h文件,且在编译的link项中包括shlwapi.li文件
【开发者及日期】
周慈2000-02-05
【版本】
1.0
【修改历史】
[最后修改]XXX
[2000-03-26]
修改打开文件的模式,从OPEN_ALWAYS改为OPEN_EXISTING
[2000-03-28]
返回的时间字符串,最后一位不需要'\n',而且清除后面的所有空格
[版本]
1.2
【使用情况】
仅在ProxyThread函数中被调用一次
*****************************************************************************/
15.6.14 程序注释(功能性注释)
15.6.14.1 变量
对所有有特定含义的变量命名,若其不能充分自注释,则必须注释变量意义;全局变量必须有较详细的注释,包括:
功能、取值范围、存取关系、哪些函数或过程存取它以及注意事项等。
7示例:
/*activestatistictasknumber*/
#defineMAX_ACT_TASK_NUMBER1000
#defineMAX_ACT_TASK_NUMBER1000/*