高質量C++/C程式設計指南(第2章 程式的版式) (轉)

worldblog發表於2007-12-12
高質量C++/C程式設計指南(第2章 程式的版式) (轉)[@more@] 

章 的版式

  版式雖然不會影響程式的功能,但會影響可讀性。程式的版式追求清晰、美觀,是程式風格的重要構成因素。

可以把程式的版式比喻為“書法”。好的“書法”可讓人對程式一目瞭然,看得興致勃勃。差的程式“書法”如螃蟹爬行,讓人看得索然無味,更令維護者煩惱有加。請程式設計師們學習程式的“書法”,彌補大學教育的,實在很有必要。

空行

空行起著分隔程式段落的作用。空行得體(不過多也不過少)將使程式的佈局更加清晰。空行不會浪費,雖然列印含有空行的程式是會多消耗一些紙張,但是值得。所以不要捨不得用空行。

 :namespace prefix = o ns = "urn:schemas--com::office" />

【規則2-1-1在每個類宣告之後、每個定義結束之後都要加空行。參見示例2-1(a)

【規則2-1-2在一個函式體內,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。參見示例2-1(b )

 

// 空行

void Function1(…)

{

  …

}

// 空行

void Function2(…)

{

  …

}

// 空行

void Function3(…)

{

  …

}

 

// 空行

while (condition)

{

  statement1;

  // 空行

  if (condition)

  {

  statement2;

  }

  else

  {

  statement3;

  }

// 空行

  statement4;

示例2-1(a) 函式之間的空行   示例2-1(b) 函式內部的空行

 

程式碼行

【規則2-2-1一行程式碼只做一件事情,如只定義一個變數,或只寫一條語句。這樣的程式碼容易閱讀,並且方便於寫註釋。

【規則2-2-2if、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-1關鍵字之後要留空格。象const、virtual、inline、case 等關鍵字之後至少要留一個空格,否則無法辨析關鍵字。象if、for、while等關鍵字之後應留一個空格再跟左括號‘(’,以突出關鍵字。

【規則2-3-2函式名之後不要留空格,緊跟左括號‘(’,以與關鍵字區別。

【規則2-3-3‘(’向後緊跟,‘)’、‘,’、‘;’向前緊跟,緊跟處不留空格。

【規則2-3-4‘,’之後要留空格,如Function(x, y, z)。如果‘;’不是一行的結束符號,其後要留空格,如for (initialization; condition; update)。

【規則2-3-5賦值運算子、比較運算子、算術運算子、邏輯運算子、位域運算子,如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<

【規則2-3-6一元運算子如“!”、“~”、“++”、“--”、“&”(地址運算子)等前後不加空格。

【規則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

int *x = &y;  // 良好的風格 

int * x = & y;  // 不良的風格 

array[5] = 0;  // 不要寫成 array [ 5 ] = 0;

a.Function();  // 不要寫成 a . Function();

b->Function();  // 不要寫成 b -> Function();

 

示例2-3 程式碼行內的空格

 

對齊

【規則2-4-1程式的分界符‘{’和‘}’應獨佔一行並且位於同一列,同時與引用它們的語句左對齊。

【規則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-1程式碼行最大長度宜控制在70至80個字元以內。程式碼行不要過長,否則眼睛看不過來,也不便於列印。

【規則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 長行的拆分

修飾符的位置

修飾符 * 和 & 應該靠近資料型別還是該靠近變數名,是個有爭議的活題。

若將修飾符 * 靠近資料型別,例如:int*  x; 從語義上講此寫法比較直觀,即x是int 型別的指標。

上述寫法的弊端是容易引起誤解,例如:int*  x, y; 此處y容易被誤解為指標變數。雖然將x和y分行定義可以避免誤解,但並不是人人都願意這樣做。

 

【規則2-6-1應當將修飾符 * 和 & 緊靠變數名

例如:

char  *name;

  int  *x, y;  // 此處y不會被誤解為指標

註釋

C語言的註釋符為“/*…*/”。C++語言中,程式塊的註釋常採用“/*…*/”,行註釋一般採用“//…”。註釋通常用於:

(1)版本、版權宣告;

(2)函式介面說明;

(3)重要的程式碼行或段落提示。

雖然註釋有助於理解程式碼,但注意不可過多地使用註釋。參見示例2-6。

 

【規則2-7-1註釋是對程式碼的“提示”,而不是文件。程式中的註釋不可喧賓奪主,註釋太多了會讓人眼花繚亂。註釋的花樣要少。

【規則2-7-2如果程式碼本來就是清楚的,則不必加註釋。否則多此一舉,令人厭煩。例如

i++;   // i 加 1,多餘的註釋

【規則2-7-3邊寫程式碼邊註釋,修改程式碼同時修改相應的註釋,以保證註釋與程式碼的一致性。不再有用的註釋要刪除。

【規則2-7-4註釋應當準確、易懂,防止註釋有二義性。錯誤的註釋不但無益反而有害。

【規則2-7-5儘量避免在註釋中使用縮寫,特別是不常用縮寫。

【規則2-7-6註釋的位置應與被描述的程式碼相鄰,可以放在程式碼的上方或右方,不可放在下方。

【規則2-7-8當程式碼比較長,特別是有多重巢狀時,應當在一些段落的結束處加註釋,便於閱讀。

 

 

/*

* 函式介紹:

* 輸入引數:

* 輸出引數:

* 返回值  :

*/

void Function(float x, float y, float z)

{

  …

}

 

if (…)

{

  …

  while (…)

  {

} // end of while

} // end of if

示例2-6 程式的註釋

 

類的版式

類可以將資料和函式封裝在一起,其中函式表示了類的行為(或稱服務)。類提供關鍵字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) 以行為為中心的版式

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991839/,如需轉載,請註明出處,否則將追究法律責任。

相關文章