2011-06-10 52 views
12

儘管具有已讀k & R,且還教Ç班,我發現自己尷尬無法全面瞭解一個可以稱之爲「現代」 C.什麼我在哪裏可以找到關於「現代」C編程的資源?

似乎是在現代編程許多不成文的慣例,以據我所知,沒有記錄在任何地方。

以SQLite源代碼爲例。其中我發現,例如:

SQLITE_API int sqlite3_close(sqlite3 *); 

SQLITE_API代表什麼?這甚至在句法上是正確的?

或者這樣:

#ifndef _SQLITE3_H_ 
#define _SQLITE3_H_ 

是否有一個公認的慣例某處時,用下劃線前綴宏?有時我會看到以兩個下劃線爲前綴的宏。

或者如何使用固定大小的類型,如uint32等等。什麼時候應該使用這種做法,什麼時候不使用?什麼是新的ish bool類型,什麼時候它應該比簡單的整數更受歡迎?

這些是我在閱讀其他人的源代碼時所提出的一些問題。有沒有可能幫助我回答這些問題的參考?

+3

閱讀http://c-faq.com/然後獲得ISO C99標準並閱讀。 – cnicutar 2011-06-10 14:08:30

+0

這些也被稱爲Ansi C,你也可以查看GNU編碼標準或者非常具體的東西,將會是linux內核編碼風格。伯克利也有一些編碼準則。所有這些都有優點和缺點。另外還有更多。 – 2011-06-10 14:19:02

回答

4

SQLITE_API這樣的代碼很可能是一個預處理器的定義,它擔心會暴露例如一個DLL庫構建。這很常見。

如果C語言全是大寫字母,那很可能是預處理符號,而且一個好主意通常是通過預處理器運行遊戲並讀取出來的內容。

2

#ifndef _SQLITE3_H_ 
#define _SQLITE3_H_ 

只是針對多種列入保護。

它防止在xxx.h包含此文件以及yyy.h的情況下發生錯誤,並且yyy.h也包含此文件。

+1

他並沒有問包括警衛(教人C必須知道這些 - 至少我真的希望如此),而是關於使用下劃線前綴(嚴格來說,這些保留供實施使用)。 – delnan 2011-06-10 14:11:33

+1

「所有以下劃線和大寫字母或其他下劃線開頭的標識符總是保留用於任何用途。」 (C99,§7.1.3¶1) – 2011-06-10 14:21:55

1

我不認爲這個東西有一個很好的參考。你目睹的是一系列慣例,一些慣例在業界廣泛使用,一些可能更加具體到你自己的代碼庫,這些慣例已經出現在處理C(和衍生產品)中的大型軟件項目中的標準挑戰或情況)。如您所知,K & R是一個很好的教學工具,但沒有涉及這些大型項目慣例,這些大型項目慣例大多出現在工業領域。

你給出了兩個很好的例子。第一個是#defined某處來裝飾一個函數,以便它可以正確導出或只記錄它將被導出。第二種模式稱爲「include guard」(請參閱​​鏈接),常規下劃線是可選的,但是避免與常規幻數定義衝突的好方法。

這裏有很多約定,其中許多涉及預處理器的定義和宏。你最好的選擇可能是單獨查詢和詢問每種模式。你可能會在這裏得到有關基本原理和良好討論的深思熟慮的回答。

0

Expert C Programming是一個很好的後續K & R.不要被稱號。如果你知道C的基本知識,那麼這本書是一本非常容易理解的書。它涵蓋了許多現實世界的代碼情況,其中K & R很短。

就是這樣說,讀寫代碼確實沒有替代品。大多數現代公約都不是真正的標準,並且在不同的代碼基礎上經常被不同地遵守。它們只是常見的解決方案,解決了人們在語言中面臨的問題和限制。我認爲最重要的是瞭解這些問題和侷限性。

2

SQLITE_API是我稱之爲「呼叫類型成語」的一個例子。這是一個預處理指令,用於提高頭文件的可移植性,其中頭文件需要定義一些特定的調用模式,通常在主代碼和DLL或類似文件之間。

根據所用SQLITE_API的平臺和編譯器通常會擴大到可用的調用約定的某種組合,如cdecl,__stdcall or similar.

你會發現在頭文件中定義它。

0

首先,您應該認識到,實際上禁止定義「_SQLITE3_H_」 - 保留所有以下劃線開頭,後跟另一個下劃線或大寫字母的名稱。當你這樣做時,最簡單的答案是,最好避免在你定義的任何東西上使用任何的前導下劃線。讓他們執行。

就SQLLITE_API去說吧,它的可能是在不同的平臺上有不同的定義。如果你正在建立它在Windows DLL中,例如,它可能會被定義是這樣的:

#define SQLLITE_API __declspec(dllexport) __stdcall 

在另一方面,當你使用你的代碼的頭,它可能被擴大到是這樣的:

#define SQLLITE_API __declspec(dllimport) __stdcall 

這些大致看出,當你正在構建的DLL你想要的功能導出的編譯器(因此它的可見世界的其餘部分)。當您在自己的代碼中使用它時,它會告訴編譯器該問題的函數將來自DLL。

3

Afaik GNU編碼標準正在不斷修訂/更新,因此可能是「現代」風格的一個很好的快照。

http://www.gnu.org/prep/standards/

回覆:具體單人或雙人undercores,以我的經驗,從我經常閱讀;它被接受爲更安全以避免雙下劃線前綴,因爲這些前綴通常對於框架/系統/編譯器特定和編譯器相關的元素是「保留」的,因此宏在模塊/包/單元/項目中使用soley他們被定義應該避免被不必要地加上前綴。

大多數實例都有自己的語言編碼標準和準則,這些標準和準則可能會有很大差異。一如既往,一致性是關鍵。

+0

你在這裏?歡迎! – lindelof 2011-06-10 22:16:58

0

我會推薦David R.Hanson的「C接口和實現:創建可重用軟件的技巧」。我認爲這是關於使用C語言的最好的書之一。

相關問題