高品質C++/C 編程指南一

來源:互聯網
上載者:User

首先,強烈推薦林銳博士這本《高品質C++/C 編程指南》,請花一兩個小時認真閱讀這本百頁經書,你將會獲益匪淺。草草看過,個人收穫記錄如下。
標頭檔的作用略作解釋:
(1)通過標頭檔來調用庫功能。在很多場合,原始碼不便(或不準)向使用者公布,只要向使用者提供標頭檔和二進位的庫即可。使用者只需要按照標頭檔中的介面聲明來調用庫功能,而不必關心介面怎麼實現的。編譯器會從庫中提取相應的代碼。
(2)標頭檔能加強型別安全檢查。如果某個介面被實現或被使用時,其方式與標頭檔中的聲明不一致,編譯器就會指出錯誤,這一簡單的規則能大大減輕程式員調試、改錯的負擔。
另:extern可以置於變數或者函數前,以標示變數或者函數的定義在別的檔案中,提示編譯器遇到此變數和函數時在其他模組中尋找其定義。如果函數的聲明中帶有關鍵字extern,僅僅是暗示這個函數可能在別的源檔案裡定義,沒有其它作用。
空行
a.在每個類聲明之後、每個函數定義結束之後都要加空行。
b.在一個函數體內,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。(這一條值得注意)
程式碼
a.一行代碼只做一件事情,如只定義一個變數,或唯寫一條語句。這樣的代碼容易閱讀,並且方便於寫注釋。
b.if、for、while、do 等語句自佔一行,執行語句不得緊跟其後。不論執行語句有多少都要加{}。這樣可以防止書寫失誤。

for(initalization;contition;update){    dosomething();}//空行other();

c.儘可能在定義變數的同時初始化該變數(就近原則)

程式碼內的空格

a.關鍵字後要留空格,如const、virtual、inline、case以及if、for、while;函數名之後不要留空格,緊跟左括弧‘(’,以與關鍵字區別。

b.逗號與分號之後要留空格;“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前後應當加空格;一元操作符前後不加空格。

c.象“[]”、“.”、“->”這類操作符前後不加空格。

d.對於運算式比較長的for 語句和if 語句,為了緊湊起見可以適當地去掉一些空格。

for (i=0; i<10; i++) // 良好的風格

長行拆分

程式碼最大長度宜控制在70 至80 個字元以內。長運算式要在低優先順序操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進行適當的縮排,使排版整齊,語句可讀。

if ((very_longer_variable1 >= very_longer_variable12)    && (very_longer_variable3 <= very_longer_variable14)    && (very_longer_variable5 <= very_longer_variable16)){    dosomething();}

注釋

a.注釋是對代碼的“提示”,而不是文檔。程式中的注釋不可喧賓奪主,注釋太多了會讓人眼花繚亂。注釋的花樣要少。

b.邊寫代碼邊注釋,修改代碼同時修改相應的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。

c.盡量避免在注釋中使用縮寫,特別是不常用縮寫。

d.注釋的位置應與被描述的代碼相鄰,可以放在代碼的上方或右方,不可放在下方。

f.當代碼比較長,特別是有多重嵌套時,應當在一些段落的結束處加註釋,便於閱讀。

類的版式

類的版式主要有兩種方式:

(1)將private 類型的資料寫在前面,而將public 類型的函數寫在後面。採用這種版式的程式員主張類的設計“以資料為中心”,重點關注類的內部結構。

(2)將public 類型的函數寫在前面,而將private 類型的資料寫在後面。採用這種版式的程式員主張類的設計“以行為為中心”,重點關注的是類應該提供什麼樣的介面(或服務)。

建議讀者採用“以行為為中心”的書寫方式,即首先考慮類應該提供什麼樣的函數。

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

共性規則

a.標識符應當直觀且可以拼讀,可望文知意;標識符的長度應當符合“min-length && max-information”原則。

b.命名規則盡量與所採用的作業系統或開發工具的風格保持一致。

例如 Windows 應用程式的標識符通常採用“大小寫”混排的方式,如AddChild。而Unix 應用程式的標識符通常採用“小寫加底線”的方式,如add_child。別把這兩類風格混在一起使用。

c.變數的名字應當使用“名詞”或者“形容詞+名詞”;全域函數的名字應當使用“動詞”或者“動詞+名詞”(動賓片語)。

d.盡量避免名字中出現數字編號,如Value1,Value2 等,除非邏輯上的確需要編號。這是為了防止程式員偷懶,不肯為命名動腦筋而導致產生無意義的名字(因為用數字編號最省事)。

簡單的Windows 應用程式命名規則

a.類名和函數名用大寫字母開頭的單片語合而成

b.變數和參數用小寫字母開頭的單片語合而成。

c.常量全用大寫的字母,用底線分割單詞。

d.靜態變數加首碼s_(表示static)。

e.如果不得已需要全域變數,則使全域變數加首碼g_(表示global)。

f.類的資料成員加首碼m_(表示member),這樣可以避免資料成員與成員函數的參數同名。

g.為了防止某一軟體庫中的一些標識符和其它軟體庫中的衝突,可以為各種標識符加上能反映軟體性質的首碼。

if語句

不可將浮點變數用“==”或“!=”與任何數字比較。

if ((x >= -EPSINON) && (x <= EPSINON))//其中EPSINON 是允許的誤差(即精度)。

有時候我們可能會看到 if (NULL == p) 這樣古怪的格式。不是程式寫錯了,是程式員為了防止將 if (p == NULL) 誤寫成 if (p = NULL),而有意把p 和NULL 顛倒。編譯器認為 if (p = NULL) 是合法的,但是會指出 if (NULL = p)是錯誤的,因為NULL不能被賦值。

程式中有時會遇到 if/else/return 的組合,應該將如下不良風格的程式

if (condition)    return x;return y;

改寫為

if (condition){    return x;}else{    return y;}

或者改寫成更加簡練的

return (condition ? x : y);

迴圈語句的效率

C++/C 迴圈語句中,for 語句使用頻率最高,while 語句其次,do 語句很少用。提高迴圈體效率的基本辦法是降低迴圈體的複雜性。

在多重迴圈中,如果有可能,應當將最長的迴圈放在最內層,最短的迴圈放在最外層,以減少CPU 跨切迴圈層的次數。

switch 語句

不要忘記最後那個default 分支。即使程式真的不需要default 處理,也應該保留語句 default : break; 這樣做並非多此一舉,而是為了防止別人誤以為你忘了default 處理。

goto 語句

我們主張少用、慎用goto 語句,而不是禁用。

const 與 #define 的比較

C++ 語言可以用const 來定義常量,也可以用 #define 來定義常量。但是前者比後者有更多的優點:

(1)const 常量有資料類型,而宏常量沒有資料類型。編譯器可以對前者進行型別安全檢查。而對後者只進行字元替換,沒有型別安全檢查,並且在字元替換可能會產生意料不到的錯誤(邊際效應)。

(2)有些整合化的調試工具可以對const 常量進行調試,但是不能對宏常量進行調試。

建議:在C++ 程式中只使用const 常量而不使用宏常量。

類中的常量

有時我們希望某些常量只在類中有效。由於#define 定義的宏常量是全域的,不能達到目的,於是想當然地覺得應該用const 修飾資料成員來實現。const 資料成員的確是存在的,但其含義卻不是我們所期望的。const 資料成員只在某個物件存留期內是常量,而對於整個類而言卻是可變的,因為類可以建立多個對象,不同的對象其const 資料成員的值可以不同。不能在類聲明中初始化const 資料成員。以下用法是錯誤的,因為類的對象未被建立時,編譯器不知道SIZE 的值是什麼。

class A{    …    const int SIZE = 100; // 錯誤,企圖在類聲明中初始化const 資料成員    int array[SIZE]; // 錯誤,未知的SIZE};

const 資料成員的初始化只能在類建構函式的初始化表中進行,例如

class A{    …    A(int size); // 建構函式    const int SIZE ;};A::A(int size) : SIZE(size) // 建構函式的初始化表{    …}A a(100); // 對象 a 的SIZE 值為100A b(200); // 對象 b 的SIZE 值為200

怎樣才能建立在整個類中都恒定的常量呢?別指望const 資料成員了,應該用類中的枚舉常量來實現。例如

class A{    …    enum { SIZE1 = 100, SIZE2 = 200}; // 枚舉常量    int array1[SIZE1];    int array2[SIZE2];};

枚舉常量不會佔用對象的儲存空間,它們在編譯時間被全部求值。枚舉常量的缺點是:它的隱含資料類型是整數,其最大值有限,且不能表示浮點數(如PI=3.14159)。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.