2012-01-18 64 views
3

當我在一個結構中定義一個字符類型時,它似乎需要多於1個字節;實際上它似乎需要4個字節。在一個結構中定義了多少個字節?

下面是我的程序:

#include <stdio.h> 

int main(void) 
{ 
    struct book{ 
     char name; 
     float price; 
     int pages; 
    }; 
    struct book b1={'B',130.00,550}; 
    printf("\nAddress of structure:%u",&b1); 
    printf("\nAddress of character name:%u",&b1.name); 
    printf("\nAddress of float price:%u",&b1.price); 
    printf("\nAddress of integer pages:%u",&b1.pages); 
    printf("\n\n"); 
    return 0; 
} 

當我運行上面的程序,我得到下面的輸出:

Address of structure:557762432 
    Address of character name:557762432 
    Address of float price:557762436 
    Address of integer pages:557762440 

爲什麼,我看到的地址之間的4個字節的區別變量「名稱」和變量「價格」?

運行此程序的系統是運行Fedora-14的x86_64位版本。

+0

編譯器打包結構以便數據成員正確對齊,並且程序可以快速運行。由於對齊不準確,某些芯片(ARM)只會失效,其他(x86)則運行速度較慢。 – Lalaland 2012-01-18 06:20:09

+0

在64位機內存字創建的64位,因爲它是32位的32位地址 x86_64 – 2012-01-18 06:21:56

+0

@RashmiKantShrivastwa感謝您的答覆,將閱讀更多關於填充 – mrashok 2012-01-18 06:37:34

回答

11

C標準允許實現向結構中添加額外的填充位,以便按照該實現的要求將其與字節邊界對齊,從而更快地訪問結構。

這就是着名的Structure Padding

鑑於上述結構的大小可能不同於單個成員的大小的總和。您應始終使用sizeof來確定結構的大小。

此外,上面提到的是,您沒有看到放置在您期望它們在內存地址的結構成員。

+0

謝謝@Als,現在我明白了 – mrashok 2012-01-18 06:36:39

+3

@ user1150645:不,問題:)做[接受一個答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work),你覺得以最好的方式回答你的問題。 – 2012-01-18 07:01:16

3

您正在運行對齊規則。這是一個非常特定於編譯器和系統的東西,但默認情況下(即除非您在代碼中使用編譯器標誌或特殊對齊請求來指定),則x64 Linux上的GCC會將結構的每個字段與其多個尺寸。所以,一個字符的字節沒有什麼特別擔心對齊。但是,int或float總是放在4字節邊界上,而double總是放在8字節邊界上。這就是你在這裏看到的。

正如Ethan在註釋中所述,某些處理器甚至不會訪問未按照某種方式對齊的內存對象,而且如果未對齊,英特爾處理器將訪問內存的速度會更慢。

+0

爲您的答覆,現在我明白了爲什麼我看到這種行爲。非常感謝 – mrashok 2012-01-18 06:38:49

0

嚴格來說,char總是佔用一個字節,但可能會跟着0或更多字節的填充。多少填充取決於編譯器和CPU,以及結構中的char之後的類型對齊以及有效的任何包裝編譯指示。如果存在N個字節的類型必須是N字節對齊,如在SPARC,例如,則:

struct s16 { char c; double d; }; 
struct s8 { char c; long l; }; 
struct s4 { char c; short s; }; 
struct s2 { char c; char b; }; 

char之後是在上述結構7,3,1和0字節上的SPARC機器以及x86_64機器上。

0

C中的「char」通常需要8位(一個字節)。

然而,在一個結構體一個炭「對齊」上的字,雙字或甚四字邊界:

http://en.wikipedia.org/wiki/Data_structure_alignment

存在可用於強制對準到4,2或1個字節編譯器指令(這規避了這種行爲)。

例如,在Visual C++中,可以說「#pragma pack(1)」。

相關問題