2011-07-25 51 views
8

我有一個關於C風格struct的簡單問題。我是通過一些示例代碼挖掘,發現通過以下方式宣佈一個結構:C風格struct聲明

typedef struct _STRUCTNAME 
{ 
    // struct contents 
} STRUCTNAME; 

請注意,缺乏對第二次STRUCTNAME下劃線的顯示出來。我的理解是,這將聲明一個名爲STRUCTNAME的_STRUCTNAME,並且沒有更多此結構的對象可以被實例化。

但是,這似乎並非如此。這種類型的結構是從來沒有真正的代碼實例化,除了在一個地方:在這種對象的全局陣列在隨機的地方使用:

const struct STRUCTNAME ARRAYNAME[] = 
{ 
    // various STRUCTNAMEs declared here 
}; 

注意缺少下劃線的再次(我認爲是實例化對象的名稱?)

我的理解是完全關閉的嗎?

有人能解釋一下嗎?

回答

4

STRUCTNAME是typedef名稱。

_STRUCTNAME是結構的'標記',它位於不同的名稱空間中。

在ANSI標準化之前,結構標記命名空間在許多編譯器中並沒有分開,所以爲了防止與typedef名稱發生名稱衝突,它必須有所不同。但是,由於標準化,不需要標籤名稱不同。

您可以看到這個在Windows代碼中經常使用的習慣用法,毫無疑問,因爲在SDK的許多示例中都是這樣。雷蒙德陳寫了一篇博客文章關於它一會兒回來:

而且,我敢肯定會有關於_STRUCTNAME標識如何保留用於執行一些意見,所以它不是在任何情況下使用該表單都是一個好主意。

+0

你能解釋一下你所說的「標籤」是什麼意思? – Klauss

+2

「標籤」僅僅是C標準用於提供給struct,union或enum的名稱/標識符的術語。 –

7
typedef struct _STRUCTNAME 
{ 
    // struct contents 
} STRUCTNAME; 

這段代碼做兩兩件事:

  1. 定義了一個名爲struct _STRUCTNAME
  2. 結構創建名爲STRUCTNAME該結構的一個typedef

這樣做的原因是,在適當的C代碼,你的方式,否則聲明struct(如以上)將是以下幾點:

struct _STRUCTNAME structInstance; 

然而,在地方typedef,您可以簡單地使用以下內容:

STRUCTNAME structInstance; 

對於enum聲明也是如此。

0

我相信你的困惑是爲什麼struct定義末尾的標識符列表沒有實例化實例。原因是因爲你已經包含了typedef關鍵字。

考慮syantax爲typedef

typedef type-definition identifier; 

您所做的一切提供的是你struct作爲類型定義。您不需要創建實例,而是定義一個類型。 Constrast這實例的實例,其中結構被簡單地定義類型在線:

struct STRUCTNAME 
{ 
    // struct contents 
} myStruct, *ptr, alsoMyStruct; 

當你不包括typedef關鍵字,標識只是指定實例如常。

2

Michael Burr說:

而且,我敢肯定會有關於_STRUCTNAME標識如何保留用於執行一些意見,所以它不是用這種形式在任何情況下,一個好主意。

OK,我的遊戲(但我想一些格式,所以你得到,而不是一個答案):

語言標準是編譯器的作家和編譯器用戶之間的合同,其中每一個承諾,做而不是做某些事情。

_開始大部分名稱均用於實施 - 包括_跟着是一個大寫字母開頭的所有標識符。這意味着編譯器 - 編寫器可以用於任何目的,因爲編譯器用戶已經承諾不使用它們。

違反承諾的編譯器用戶會得到奇怪的結果。相反,由於編譯器 - 編寫者已經承諾不使用它們,所以[適用的]標準不保留用於實現的所有標識符都可以保證可供編譯器用戶使用。

當有效的代碼得到奇怪的結果時,違反承諾的編譯人員會得到退款要求。

我的首選方法是在標籤名稱上加上尾部_,包括警衛等,確保我不在實施空間內;因此:

typedef struct STRUCTNAME_ 
{ 
    // struct contents 
} STRUCTNAME; 

(有些純粹主義者不贊成typedef S作爲只是語法糖,但是C需要一點糖在這裏和那裏,否則就顯得相當乏味)

0
const struct STRUCTNAME ARRAYNAME[] = 
{ 
    // various STRUCTNAMEs declared here 
}; 

上面的代碼不會針對數組的不完整類型進行編譯。我認爲thers錯字應該是

const struct _STRUCTNAME ARRAYNAME[] = ... 

或者您可以使用typedef不指定關鍵字struct

const STRUCTNAME ARRAYNAME[] =