2010-04-28 74 views
13

C顯示其年齡的一個方面是代碼的封裝。許多現代語言都有類,名稱空間,程序包......組織代碼要比簡單的「包含」方便得多。克服大型項目的C限制

由於C仍然是許多大型項目的主要語言。你如何克服其侷限性?

我想一個主要因素應該是很多紀律。我想知道你如何處理大量的C代碼,你可以推薦哪些作者或書籍。

+0

一個類似的帖子,不是專門爲C,但包含良好的一般建議:http://stackoverflow.com/questions/2025733/coding-pratice-what-are-your-thoughts-on-a-1-7-百萬loc項目 – 2010-04-28 19:38:21

回答

18
  • 將代碼分離爲功能單元。
  • 將這些單元的代碼構建到單獨的庫中。
  • 使用庫中的隱藏符號來減少名稱空間衝突。

想想開源代碼。 Linux內核,GNU C庫,X Window系統和Gnome桌面項目中都有大量的C代碼。但是,這一切都在一起工作。這是因爲大部分代碼沒有看到任何其他代碼。它只通過定義良好的接口進行通信。在任何大型項目中都這樣做。

可以實現一些封裝
2

的一個好方法是聲明一個模塊的內部方法或變量static

1

由於安德烈斯說,static是你的朋友。但是談到朋友......如果你想能夠在兩個文件中分離一個庫,那麼需要在另一個文件中看到的一個文件中的一些符號不能是static。 確定一些命名約定:來自庫foo的所有非靜態符號均以foo_開頭。並確保他們總是遵循:它恰好是它似乎約束的符號(「我需要稱之爲foo_max?!但它只是max!」),會有衝突。

正如Zan所說,一個典型的Linux發行版可以被看作是一個主要用C編寫的巨大項目。有接口,大型子項目實現爲獨立進程。在不同流程中的實現有助於調試,測試和代碼重用,除了鏈接級別上的唯一一個層次之外,它還提供了第二層次結構。當你的項目變得足夠大時,可能開始有意義地將一些功能放在單獨的進程中。已經像C編譯器一樣專用的東西通常被實現爲三個進程:預處理器,編譯器,彙編器。

3

有些人不喜歡它,但我主張將我的結構和相關函數組織在一起,就好像它們是一個明確傳遞此指針的類。例如,結合一致的命名約定來明確命名空間。一個標題可能類似於:

typedef struct foo { 
    int x; 
    double y; 
} FOO_T 

FOO_T * foo_new(); 

int foo_set_x(FOO_T * self, int arg1); 

int foo_do_bar(FOO_T * self, int arg1); 

FOO_T * foo_delete(FOO_T * self); 

在實現中,所有「私有」函數都是靜態的。這個缺點是你不能強制用戶不去和結構體的成員混淆。這只是c中的生活。我發現這種風格雖然可以用於很好的可重用C類型。

+2

風格沒問題,但我更喜歡'FOO_T * x; x-> x = 1;'over'FOO_T * x; foo_set_x(x,1);'。對C程序員來說更清楚一點。 (你可以強制用戶不通過給定一個'struct'的成員來去混淆,只要說'typedef struct foo FOO_T',然後他們可以使用指向你的類型的指針,而不需要在裏面看到。] – 2010-04-28 20:33:03

+0

我同意克里斯 - 要麼提供結構的定義,並期望客戶端代碼改變其成員,或者使用指向typedef慣用語的指針並隱藏內容。 – 2010-05-19 22:08:57

0

如果您可以控制項目(例如內部支付或您向其他人支付),您可以簡單地設置規則並使用評論和工具來執行。這種語言沒有真正的需要,例如,你可以要求在模塊外部使用的所有功能(=一組文件,甚至不需要是單獨的)都必須這樣標記。實際上,你會迫使開發人員考慮接口並堅持使用它們。

如果你真的想表達觀點,你可以定義宏來顯示它,例如,

#define PUBLIC 
#define PRIVATE static 

或其他一些。

所以你是對的,紀律是關鍵。它涉及制定規則並確保遵守規則。

+0

大多數面嚮對象語言的公共和私有不等於靜態和自動。 – 2010-05-19 22:10:06

+0

我同意,紀律是重要的,並且重要的步驟是實現它的規則,評論和工具,但我認爲重寫是很好的例子 - 設置時不遵守規則。早期評論(代碼未完成時)可以降低重寫所產生的額外成本。重寫決定可能由某人「正式決定」正式決定,並進一步強調要遵循規則。 – 2011-02-26 00:53:03

+0

只要在多個文件包含的頭文件中沒有使用PRIVATE ... :-) – paercebal 2011-05-11 20:10:51