2012-07-29 50 views
1

我已經使用#pragma指令編寫了一個代碼來對齊,但我無法理解對齊是如何發生的。 我在Ubuntu上使用gcc。在c中使用#pragma pack但無法理解

#include<stdio.h> 

#define MALE 0; 
#define FEMALE 1; 
#define SINGLE 0; 
#define MARRIED 1; 
#pragma pack(3); 

int main() 
{ 
    struct emp 
    { 
     unsigned gender :1; 
     unsigned mar:1; 
     unsigned hobby:1; 
     unsigned scheme :1; 
    }; 
    struct emp e; 
    e.gender=MALE; 
    e.mar=SINGLE; 
    e.hobby=1; 
    e.scheme=1; 
    printf("size of %d",sizeof(e)); 
    return 0; 
} 
當我使用#pragma pack爲1

,大小出來是1的#pragma包作爲2大小出來爲2和3是4

你能告訴我發生了什麼事?如果我不使用它,仍然有4個來。

那麼#pragma pack(1)#pragma pack(2)之間有什麼區別?

+0

3對'pragma pack'無效。看看[這裏](http://msdn.microsoft.com/en-us/library/2e70t5y1(v = vs.80).aspx) – pmr 2012-07-29 15:12:34

+0

我想知道,當我寫#pragma pack(1)它設置第一位,然後從第二位開始第二位如果我編寫#pragma(2),怎麼區別 – 2012-07-29 15:28:34

+0

你不希望'#define'行末尾有分號。您可能不希望在'#pragma'行末尾使用分號。 – 2012-07-29 16:17:55

回答

2

3不是#pragma pack指令的有效參數。

有效值是124816,根據this page例如。

0

`#pragma'指令是由C標準指定的方法,用於向編譯器提供額外信息,超出了語言本身傳達的內容。

#pragma pack指定結構,聯合和類成員的打包對齊方式。

有效值是1,2,4,8和16.成員的對齊將位於邊界上,該邊界可以是上述任何值的倍數或成員大小的倍數,以較小者爲準。

有關更多詳細信息,請參閱MSDN pagehere

此外,在結構從here

什麼是結構填料下方包裝一些信息?

有時候必須避免結構成員之間的填充字節。例如,讀取ELF文件頭或BMP或JPEG文件頭的內容。我們需要定義一個類似於頁眉佈局的結構並映射它。但是,在訪問這些成員時應該小心。通常逐字節讀取是避免錯位異常的一種選擇。表現會受到打擊。

大多數編譯器提供非標準擴展來關閉缺省填充,如pragmas或命令行開關。有關更多詳細信息,請參閱相應編譯器的文檔

i want to know that when i write #pragma pack(1) it set first bits and atart second from next one what if i write #pragma(2) , whats the difference 

要回答這個問題,當你設置的#pragma 2,如果居住在結構中的數據是不到2個字節,它對準保持不變。但是,如果它超過2個字節(例如4個字節的整數),它將在2個字節的邊界處被拆分並對齊。

+0

當我在我的代碼中應用並檢索答案時,#pragma pack(1)和#pragma pack(2)之間的區別是什麼,因爲struct emp的哪個大小發生了變化,所發生的位或字節發生了什麼 – 2012-07-29 15:31:25

0

#pragma pack(1)#pragma pack(2)之間的區別在於,在第一種情況下,您說您的結構可以在任何地址開始。

With #pragma pack(2)你說起始地址必須能被2整除(偶數地址)。編譯器通過這樣做來表示結構的大小爲2(通過填充一些未使用的空間)。

如果您創建了emp的數組,例如emp a[10],則sizeof(emp)也是數組中每個元素之間的距離。這就是爲什麼編譯器將尺寸舍入到#pragma pack值的下一個倍數。