2015-09-15 107 views
1

我發現了一些類似的問題,但沒有一個幫助很大。 struct名是指向結構第一個元素的指針,類似於數組?結構名稱是指向第一個元素的指針嗎?

struct example { 
    int foo; 
    int bar; 
}; 

struct example e; 
e.foo = 5; 
e.bar = 10; 
printf("%d\n%d\n%d\n%d\n%d\n%d\n", e, e.foo, e.bar, &e, &e.foo, &e.bar); 

輸出:

5 
5 
10 
2033501712 
2033501712 
2033501716 

的答案,其他問題的所有說 「不」,但這種輸出混淆了我。所有的幫助將不勝感激。

回答

4

struct的地址確實是第一個元素的地址,但您需要知道元素的類型才能安全地轉換它。

(C1X§6.7.2.1.13:「A指針的結構對象,適宜地轉換 ,點到它的初始構件...,反之亦然可能 內作爲結構對象是無名填充,但不在 開頭。「)

雖然它是一種醜陋的,很多生產軟件依賴於此。例如,QNX在編寫資源管理器時在開放控制塊(OCB)邏輯中使用這種行爲。 Gtk也類似。

雖然您目前的實施是危險的。如果您必須依賴此行爲,請按照這樣做,並且不要嘗試將指針指向結構作爲參數傳遞給printf(),因爲您有意打破語言特性並且具有最小的類型安全性。

struct example { 
    int foo; 
    int bar; 
}; 

struct example myStruct = { 1, 2 }; 
int* pFoo = (int*)&myStruct; 
printf("%d", *pFoo); 

最後,這隻適用於第一個元素。後續元素可能不是您期望它們的情況,namely due to struct packing and padding

+0

您應該在第一句中更改「指向」一詞,否則某個人可能會將您的答案遺忘。 – GolezTrol

+0

有趣的如何可能適用於你不能有指針的成員。 (例如,一個位域) –

+0

@GolezTrol :)完成。 – DevNull

3

struct名稱不是指向任何東西的指針。您正在調用未定義的行爲,方法是將struct傳遞給printf,其格式說明符%d不兼容。它似乎「工作」,因爲結構的第一個成員具有與struct本身相同的地址。

+0

我真的不知道它是如何「工作」的,結構的大小與int的大小不同應該導致所有其他輸出變成亂碼 –

+0

@ M.M UB?也許參數在OP的平臺上反向讀取。 – juanchopanza

相關問題