2012-07-29 65 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值的下一个倍数。