• 文章
  • 更清晰的程式碼
釋出
2010年7月21日 (上次更新: 2011年8月6日)

更清晰的程式碼

評分: 3.7/5 (70 票)
*****
我寫這篇文章的原因是,很多人似乎不知道(或不在乎)程式碼的可讀性。可讀性是可移植性、可重用性和可理解性 (!) 的基礎。
如果沒有合適的程式碼,你在這些論壇上尋求幫助時會遭到抱怨,所以仔細閱讀;這裡有一些清理程式碼的技巧和竅門。

這是一個指南,我不是說它是完美的。我只是提供一個好的方法,是否使用它由你決定。

本指南不被認為是完整的,但應該可以很好地幫助你入門,歡迎所有建議。

關於括號 始終將括號放在空行上,並將開始和結束括號放在程式碼中的相同“高度”。兩個括號之間的任何內容都應該向右縮排一定數量的空格,這在你的所有程式碼中都是一致的。(在我的例子中,我使用 4 個空格)這種括號風格稱為 Allman 風格。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    for(int i = 0; i < 9; i++)
    {
        cout << i << endl;
    }
    return 0;
}

當然,還有其他方法可以做到這一點。一種是 Allman 風格的略微變化:Whitesmith 風格。括號與內部語句位於同一級別。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using std::cout;
using std::endl;

int main()
    {
    for(int i = 0; i < 9; i++)
        {
        cout << i << endl;
        }
    return 0;
    }

當看不清楚文字並不重要,而是要了解不同語句之間的關係(主要是 if/else 關係)時,你也可以使用 1TBS(The One True Brace Style,唯一正確的括號風格)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    for(int i = 0; i < 9; i++)
    {
        // Allman, up to now, time to go 1TBS for If/Else
        if (i < 5) {
            cout << i << endl;
        } else {
            cout << i*2 << "\t";
        } // And of if/else clause, the last bracket is the only one that takes up it's own line
        // Allman again
    }
    return 0;
}


關於註釋 添加註釋是為了提高可讀性,但也可以使你的註釋更具可讀性。僅在需要時使用多行註釋,並避免在程式碼行的末尾添加註釋。避免縮排註釋,使用換行符使內容更清晰。有關更多資訊,請參閱關於一致性。

以下注釋可能看起來毫無價值,但我只是想明確我上面所說的內容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    // Count
    for(int i = 0; i < 9; i++)
    {
        cout << i << endl;
    }

    // Program termination
    return 0;
}


關於一致性(常規) 當不同的替代方案達到相同的結果(以相同的速度和相同的程式碼行數)時,請確保你堅持使用單一方法。這適用於後置和前置加法和減法(++ / --),以及函式式和 C 風格的轉換 int() 和 (int)。
無論你做什麼,都要保持一致。

關於函式呼叫(和定義) 為了可讀性,在呼叫和定義函式的方式上保持一致。不僅有很多方法可以做同樣的事情,而且也有很多方法可以編寫相同的語句。當你形成自己的編碼風格時,嘗試堅持一種能夠讓你保持清晰的方法。一般來說,沒有完美的方式來編寫事物,但是,有好的方法來為自己編寫事物。以下所有提到的方法都是合法的。
1
2
3
power(3, 5)
power( 3,5 )
power(3,5)


關於初始化 一致性也適用於初始化
當可以選擇在開始時或稍後初始化時,請使用單一方法。但是,如果你別無選擇,只能使用其中一種,那麼請使用你需要的那個。此外,在建立指標或引用(或指向指標的指標的指標的引用的 blablabla)時,請使用適當的間距。
以下所有操作都相同(建立一個指向稱為 Variable 的整數的指標的引用)。無論哪一種方式能夠最好地向你視覺化這個結構,都是你的“好方法”。(沒有錯誤的方法,只有“更好”的方法。)
1
2
3
4
int**& Variable;
int **& Variable;
int **&Variable;
int** &Variable;


關於命名
以下是一個指導方針,可以更改(只要它是一致的,當然)。

命名對於函式、類、結構體、聯合體、變數、名稱空間等都很重要。
如何進行良好的命名?
1. 確保你根據事物的作用(或是什麼)來命名它們。
2. 可以選擇在它們前面加上一個或兩個小寫字元,描述命名的例項。(c 代表類,s 代表字串,i 代表整數,d 代表雙精度浮點數等)
3. 每個單詞都以大寫字元開頭,其餘字元使用小寫。(一個整數可以變成:iNumber)

這些規則的一個例外是迴圈變數。這些通常用單個小寫字元命名。

(所有這些都只是我對一段時間以來的編碼習慣的觀察。這絕不是一個嚴格的規則集。它更像是一種編碼方式,可以很容易地被任何人閱讀。)

關於運算子 運算子可以被視為“資料”的“編輯器”。在這種情況下,最好建立清晰的部分來組織這些“資料”。這種組織取決於你對語句的看法。
1
2
int iNumber = 6+5;
int iReturnValue = 4*iNumber +3;


關於預處理器指令 所有間距和換行規則都適用於此處。但是,對於 #define,請確保使其與普通變數區分開來(使其名稱完全大寫是一種方法,在其名稱之前和之後新增 _ 是另一種方法。你可以隨意執行任何操作,只需保持清晰即可。)


最後,你的程式設計風格是不應該強加給你的。但是,請記住,要收到你程式碼的反饋,人們需要理解程式碼。如果你希望人們理解你的程式碼,請使你的程式碼清晰易讀。