代码规范。高质量c/c++编程(2)

 

 

自做C语言底层开发,积累了有些代码书写的经验供大家参考:

第2章 程序的版式

1.C语言书写规范
1.1标志命名规则
1.1.1记名包模块名、常量称为、标号名、子程序名等。这些名应该会反映其所表示的实际上东西,具有自然之含义,使其能显现名知义,有助于对先后功能的掌握。命名采用匈牙利命名法。规则如下:
(1)所有宏定义、枚举常数和const变量,用老写字母命名。在复合词里之所以生划线隔开每个词。
(2)复合词中每个单词的率先个假名大写。除了规则5.1.1.1以外,避免下下划线。
(3)类、类型定义和枚举型名的率先单字母大写。
(4)函数叫作是复合词的,第一单词用任何大写,随后每个单词采用第一单假名大写,其它字母小写方式;如果是不过个词之,采用全大写方式。
(5)循环变量可采用i, j, k等,不吃上述规则限制。
(6) 类的成员变量应采用m_开头。
(7) 全局变量词头为g_ 。
(8) 临时变量词头为tmp_ 。
(9) 对结构体内的变量命名, 遵循变量的具体意思命名规则
(10)用小写字母的前缀表示变量的类别,前缀的产一个字母用大写。 
表 1
词 头 类 型 词 头 类 型
ch char l long
i integer u unsigned 
b boolean p pointer 
f float lp long pointer
d double s string
st structure sz ASCII string
by byte n short int
H handle x,y 分别为x,y坐标
dw DWORD fn function

      
版式虽然非见面影响程序的机能,但会潜移默化可读性。程序的版式追求清晰、美观,是程序风格的主要组成因素。

表 2
词 头 变 量 名 词 头 变 量 名 
task task sig signal
sb binary semaphores wd watchdog
sm mutual exclusion 
semaphores tm timer
sc counting semaphores msg message
pipe pipe 
例:
#define ARRAY_SIZE 24 /*规则5.1.1.1*/

好管程序的版式比喻为“书法”。好的“书法”可让人对程序一目了然,看得津津有味。差之次序“书法”如螃蟹爬,让丁拘禁得索然无味,更让维护者烦恼有加。请程序员们读书程序的“书法”,弥补大学计算机教育之纰漏,实在非常有必不可少。

int g_iFlag; 
class MyClass /*规则5.1.1.3*/
{
};

2.1空行

void someFunc( ) /*规则5.1.1.2和5.1.1.4*/
{
.2.
Q/ECC/BJ 010—2001

空行起在分隔程序段落的企图。空行得体(不过大多为只是不见)将如程序的布局进一步鲜明。空行不见面浪费内存,虽然打印带有空行的顺序是会多淘一些纸,但是值得。所以不要舍不得用空行。

int nArray[ARRAY_SIZE];
unsigned char uchByte;
char szName[ ];
char *pszName = szName;
}
(11)有些词头(如p和u)可以与其他词头组合。 

 

例:WDOG_ID wdId;
WDOG_ID g_wdId; /*全局watchdog Id,故以g_开头*/
1.1.2名字的长一般不要过长或过少。过长的名会大增工作量,使程序逻辑流程变得模糊;过差的名无法发挥符号的实际意义。约定长度限制:3-31;

l        
【规则2-1-1】以每个接近声明后、每个函数定义了之后还设加以空行。参见示例2-1(a)

1.2数目与函数说明
1.2.1数说明次序应当规范化,使数码性容易招来,也便宜测试、排错和维护。说明的程序次序应固定,应以逻辑功能排序,逻辑功能块内建议利用下列顺序:整型说明、实型说明、字符说明、逻辑量说明。
1.2.2要计划了一个扑朔迷离的数据结构,应当透过注释对那个变量的意思、用途进行认证。
1.2.3于函数的宣示中采用大声明。
如:void f() throw(toobig, toosmall, divzero);
当声明一个函数时,将其所摒弃来的不胜排列有,便于函数的使用者了解或会见时有发生怎样大。

l        
【规则2-1-2】在一个函数体内,逻揖上精心相关的语之间无加空行,其它地方应加以空行分隔。参见示例2-1(b

1.3 程序注释 
1.3.1次注释是程序员和下之顺序读者之间通信的重要性手段之一,注释分为文件注释、函数注释和功能注释。
1.3.2标准程序的注解应注意:
——注释行的数占据到全部源程序的1/3届1/2。
1.3.3文本注释位于整个源程序的顶初步有的,注释后空少实行开始先后正文。它概括:
——程序标题。
——目的、功能说明。
——文件作者、最后修改日期等证明。
例:
./********************************************************************
(空一行)
标题: Demo.c
功用: 测试VxWorks的各种系统调用. 
说明: 
欠次测试各种VxWorks的系统调用函数。包括任务(taks)的创始、挂于与任务之中透过信号灯实现同台,通过信息队列进行报道。
次第创建了个别独任务:一个胜似优先级的职责及一个低优先级的天职。两单任务之中透过一个二进制的信号灯进行同步,通过信息队列进行报道。
当前版: x.x
修改信息: 2000.06.05 John, Initial Version
2000.07.05 Tom, Bug xxxx fixed
**************************************************************/
(空2推行,开始先后正文)

 

1.3.4
函数注释通常置于各函数或过程的上马部分,它应被有函数或过程的总体说明对了解程序本身装有引导作用。一般包括如下条目:
——模块标题。
——有关以模块功能和目的的认证。
——调用格式
——接口说明:包括输入、输出、返回值、异常。
——算法。如果模块中以了有错综复杂的算法。
例:
file://(注释开头应同上一函数空两行)
(注释开头和上一函数最后一行间隔两执)
/********************************************************************
标题:assignmentComplete
意义:BSC=>MSC消息生成函数,生成assignment_complete指配完成信息(BSMAP消息)
.
格式:
int assignmentComplete(int iCellId, int iServiceChannnelNum, char
*pszMSGData) throw(exception1, exception2)
输入:
int iCellId: MS所于的小区识别
iCellId取值:0x00-——0xff .4.
Q/ECC/BJ 010—2001

// 空行
void Function1(…)
{
 …
}
// 空行
void Function2(…)
{
 …
}
// 空行
void Function3(…)
{
 …
}
 
// 空行
while (condition)
{
 statement1;
 // 空行
 if (condition)
 {
     statement2;
 }
 else
 {
     statement3;
 }
// 空行
 statement4;

int iServiceChannnelNum:MS所占的事体信道号码
输出:
char * pszMSGData:指配完成信息数据
返回值: 0x00正常
酷:exception1异常情况1, exception2异常情况2
********************************************************************/
( 注释后直接开先后正文,不空行。)
1.3.5功能性注释嵌在源程序体中,用于描述下的语句或程序段做啊工作,也就算是解说下要举行呀,或是执行了底的语句会怎么样。而不用讲下怎么开,因为解释怎么开常常同程序本身是再次的。
例:
/*把 amount 加到 total中*/ 
total = amount + total;
如此的笺注仅仅是重了下面的主次,对于了解她的干活并不曾什么作用。而脚的诠释,有助于读者了解。
/*以每月的销售额amount加至年销售额total中*/
total = amount + total;
1.4 函数编写应尽量短小精悍,一般不越两屏,以便让调试以及掌握。

演示2-1(a)
函数之间的空行                  示例2-1(b) 函数内部的空行

1.5告知句结构
否确保语句结构的清和顺序的可读性,在编辑软件程序时承诺注意以下几个方面的题材:
——在一行内单写一长条语句,并运用空格、空行和移行保证清楚的视觉效果。
——每一个嵌套的函数片,使用一个TAB缩进(可以设定也4个空格),大括哀号要在规范语句的生一行,单独成一行,便于匹对:
倘,有同样段先后如下:
for(i=1;i<n-1;i++){ t=1; for(j=i+1;j<n;j++){
if(a[j]<a[t] ) t=j; if(t!=i
){work=a[t];a[t]=a[I];a[I]=work;}}}
应写为
for( i=1; i<n-1; i++)
{
t=1;
for(j = i+1; j<n; j++)
{
if(a[i]<a[j]) 
t=j;
if(t!=1)
{ .5. 

 

Q/ECC/BJ 010—2001
work=a[t];
a[t]=a[i];
a[i]=work;
}

}

2.2代码行

——文件中不得是无规则的空行,比如说连续十个空行。
一般来讲函数和函数之间的空行为2-3行;
以部数体内部,在逻辑上独的鲜独函数块可适当空行,一般也1-2履。
——程序编制首先应考虑清晰性,不要刻意追求技巧性而使得程序难以明白。
——每行长度尽量避免超过屏幕宽度,应不超80独字符。
——除非对效率有特殊要求,编写程序要作到清第一,效率第二。
——尽可能用函数库。
——尽量用公家过程或子程序去替代重复的效力代码段。要顾,这个代码应具备一个独立的效益,不要只是坐代码形式一样就是以那个抽出组成一个国有过程或子程序。
——使用括号清晰地发挥算术表达式和逻辑表达式的演算顺序。如用 x=a*b/c*d
写成 x=(a*b/c)*d可避免阅读者误解呢x=(a*b)/(c*d)。
——避免不必要的变。
——避免使用过于复杂的准绳测试。
——避免过多之巡回嵌套和规格嵌套。
——建议不要采用 *=,^=, /=等运算符。
——一个函数不要过200执。一个文书应避免过2000实行。
——尽量避免使用go to语句。
——避免使用多赋值语句,如x = y = z ;
——不鼓励采取?:操作符,如z = (a>b)?a:b;
——不要使用空的if else 语句。如
if(cMychar >= ‘A’)
if(cMychar <= ‘Z’)
printf(“This is a letter \n”);
else
printf(“This is not a letter \n”);
else到底是否定哪个if容易招误解。可经加{}避免误解。 
——尽量减少使用“否定”条件的尺码语句。如:
把 if( !( (cMychar<’0’) || (cMychar>’9’) ) ) 
改为if( (cMychar>=’0’) && (cMychar<=’9’) )

l        
【规则2-2-1】一行代码只做同桩业务,如只是定义一个变量,或只有写一修语句。这样的代码容易看,并且有利于于写注释。

l        
【规则2-2-2】if、for、while、do等报告句自占一行,执行语句不得紧跟其后。不论执行报告句有些许还设加{}。这样可防止书写出错。

 

演示2-2(a)为作风好的代码行,示例2-2(b)为风格不良的代码行。

 

 
int width;    // 宽度
int height;   // 高度
int depth;    // 深度
 
int width, height, depth; // 宽度高度深度
 
x = a + b;
y = c + d;
z = e + f;
X = a + b;   y = c + d; z = e + f;
 
if (width < height)
{
dosomething();
}
if (width < height) dosomething();
for (initialization; condition; update)
{
dosomething();
}
// 空行
other();
 
for (initialization; condition; update)
     dosomething();
other();
 
 

示例2-2(a)
作风好的代码行                示例2-2(b)
风格不良的代码行

 

²       
【建议2-2-1】尽量在概念变量的以初始化该变量(就近原则)

要是变量的引用处和其定义处相隔比较多,变量的初始化很容易被忘记。如果引用了无让初始化的变量,可能会见促成程序错误。本建议可以减去隐患。例如

int width = 10;     // 定义并初绐化width

int height = 10;    // 定义并初绐化height

int depth = 10;     // 定义并初绐化depth

 

2.3替码行内的空格

l        
【规则2-3-1】重大字之后如果留空格。象const、virtual、inline、case
等主要字后至少要留一个空格,否则无法解析关键字。象if、for、while等关键字之后应留一个空格再和左括哀号‘(’,以崛起重点字。

l        
【规则2-3-2】函数号称后不要留空格,紧跟左括号‘(’,以和重点字区别。

l        
【规则2-3-3】‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留下空格。

l        
【规则2-3-4】‘,’之后如果留下空格,如Function(x, y,
z)。如果‘;’不是单排的截止符号,其后若留空格,如for (initialization;
condition; update)。

l        
【规则2-3-5】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”
“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的左右应加空格。

l        
【规则2-3-6】一元操作符如“!”、“~”、“++”、“–”、“&”(地址运算符)等内外未加以空格。

l        
【规则2-3-7】形象“[]”、“.”、“->”这好像操作符前后未加空格。

²       
【建议2-3-1】对于表达式比较长的for语句和if语句,为了紧凑起表现得方便地去丢一部分空格,如for
(i=0; i<10; i++)和if ((a<=b) && (c<=d))

 

void Func1(int x, int y, int z);          // 良好的风格
void Func1 (int x,int y,int z);           // 不良的风格
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 < b ? a : b;                        // 良好的风格
x=a<b?a:b;                                // 不好的风格
int *x = &y;                              // 良好的风格 
int * x = & y;                            // 不良的风格 
array[5] = 0;                             // 不要写成 array [ 5 ] = 0;
a.Function();                             // 不要写成 a . Function();
b->Function();                            // 不要写成 b -> Function();
 

演示2-3 代码行内的空格

 

2.4对齐

l        
【规则2-4-1】次的分界符‘{’和‘}’应把一行以位居同一列,同时和援它的晓词左对旅。

l        
【规则2-4-2】{ }之内的代码块当‘{’右边数格处左对合。

 

以身作则2-4(a)为作风好的对齐,示例2-4(b)为风格不良的对齐。

 

 
void Function(int x)
{
… // program code
}
 
void Function(int x){
… // program code
}
 
if (condition)
{
… // program code
}
else
{
… // program code
}
if (condition){
… // program code
}
else {
… // program code
}
for (initialization; condition; update)
{
… // program code
}
for (initialization; condition; update){
… // program code
}
While (condition)
{
… // program code
}
while (condition){
… // program code
}
如果出现嵌套的{},则使用缩进对齐,如:
     {
       …
          {
           …
          }
       …
}
 

示例2-4(a)
风格好的对齐                      示例2-4(b)
作风不良的对齐

 

2.5长行拆分

l        
【规则2-5-1】代码行最酷长宜控制以70至80单字符中。代码行不要了长,否则眼睛看无过来,也未便于打印。

l        
【规则2-5-2】加上表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出底新行要进行适宜的缩进,使排版整齐,语句可读。

 

if ((very_longer_variable1 >= very_longer_variable12)
&& (very_longer_variable3 <= very_longer_variable14)
&& (very_longer_variable5 <= very_longer_variable16))
{
    dosomething();
}
virtual CMatrix CMultiplyMatrix (CMatrix leftMatrix,
                                 CMatrix rightMatrix);
 
for (very_longer_initialization;
     very_longer_condition;
     very_longer_update)
{
    dosomething();
}

演示2-5 长行的拆分

2.6编纂饰符的职务

修饰符 * 和 & 应该接近数据类型还是该接近变量名,是独出争论之活题。

若是用修饰符 * 靠近数据类型,例如:int* x;
从语义上讲此写法比较直观,即x是int 类型的指针。

上述写法的流弊是易引起误会,例如:int* x, y;
此处y容易受误会呢指针变量。虽然将x和y分行定义可以避误会,但并无是众人都甘愿这样做。

 

l        
【规则2-6-1】应用修饰符 * 和 & 紧依变量名

例如:

char *name;

    int   *x, y;    // 此处y不会见于误会呢指针

2.7注释

C语言的注释符为“/*…*/”。C++语言中,程序块的注释常使“/*…*/”,行注释一般用“//…”。注释通常用于:

(1)版本、版权声明;

(2)函数接口说明;

(3)重要之代码行或段落提示。

虽然注释有助于了解代码,但只顾不可过多地采取注释。参见示例2-6。

 

l        
【规则2-7-1】注解是指向代码的“提示”,而未是文档。程序中的注解不可喧宾夺主,注释太多了见面叫丁乱。注释的花头要少。

l        
【规则2-7-2】苟代码本来就是掌握的,则不用加注。否则多是一举,令人头痛。例如

i++;    // i 加 1,多余的注解

l        
【规则2-7-3】限写代码边注释,修改代码同时修改相应的诠释,以确保注释与代码的一致性。不再灵光之诠释要去。

l        
【规则2-7-4】注应当规范、易懂,防止注释有二义性。错误的诠释不但行不通反而有害。

l        
【规则2-7-5】尽量避免在诠释中运用缩写,特别是免常用缩写。

l        
【规则2-7-6】注解的职务应同被描述的代码相邻,可以在代码的上方或右,不可在下方。

l        
【规则2-7-8】当代码比较丰富,特别是发多更嵌套时,应当以一部分段子的扫尾处加注释,便于阅读。

 

 
/*
* 函数介绍:
* 输入参数:
* 输出参数:
* 返回值 :
*/
void Function(float x, float y, float z)
{
 …
}
 
if (…)
{
 …
 while (…)
 {
} // end of while
} // end of if

示范2-6 顺序的注释

 

2.8类的版式

恍如可以拿数据以及函数封装于一起,其中函数表示了近似的一言一行(或称服务)。类提供关键字public、protected和private,分别用于声明哪些数据和函数是公有的、受保障之抑是个体的。这样可高达信息隐藏的目的,即让类仅仅公开必须使受外界知道之情节,而隐形其它任何情节。我们不得以滥用类的包装功能,不要把它正是火锅,什么事物都为里扔。

好像的版式主要出星星点点种植办法:

(1)将private类型的多寡勾勒于面前,而将public类型的函数写于背后,如示例8-3(a)。采用这种版式的程序员主张类的计划“以数量也主干”,重点关注类的内部结构。

(2)将public类型的函数写以前头,而以private类型的数额形容以末端,如示例8.3(b)采用这种版式的程序员主张类的宏图“以执行也耶中心”,重点关注的凡接近应该提供怎样的接口(或劳动)。

不少C++教课书受到Biarne
Stroustrup第一据著作的熏陶,不知不觉地使用了“以数量为核心”的书写道,并无展现得生稍许道理。

自建议读者以“以履行啊也核心”的书道,即首先考虑类应该提供什么样的函数。这是很多人的阅历——“这样做不仅给好当计划类时思路清楚,而且便于人家看。因为用户最好关注的凡接口,谁愿意先看到同一堆放私出多少成员!”

 

class A
{
 private:
int    i, j;
float x, y;
    …
 public:
void Func1(void);
void Func2(void);
}
class A
{
 public:
void Func1(void);
void Func2(void);
 private:
int    i, j;
float x, y;
    …
}

演示8.3(a) 以数为主干版式                 示例8.3(b)
以履行也乎主导的版式

 

 

 

 

相关文章