2016-10-12 68 views
0
#include <stdio.h> 

union mix { 
    unsigned char a1:1; 
    unsigned char a2:4; 
    unsigned char a3:4;  
    unsigned char a4:1; 
    unsigned char a5:4; 
    unsigned char a6:4;  
    unsigned char a7:1; 
    unsigned char a8:4; 
    unsigned char a9:4;  
    unsigned char a10:1; 
    unsigned char a11:4; 
    unsigned char a12:4;  
}; 

int main() { 

    printf("Sizeof mix = %d bytes\n", sizeof(union mix)); 

    return 0; 
} 

输出是1字节具有比其大小更多成员的比特场联合的大小

位字段成员超过8位会发生什么?显然我仍然可以为任何位域成员设置并获取正确的值。

UPDATE

感谢您对我的清理混乱。一方面的问题:这些位以什么顺序存储在内存中?假设它是小端存储器,所以0xabcd将作为0xd,0xc,0xb,0xa存储在内存中。

  1. m.a1是否会成为0xd或oxa的一部分?
  2. 它是第3位还是第0位0xd(或0xa)?
+4

没有超过8位的成员。 'union'!='struct'。 – tkausl

+0

@tkausl明白了..我混淆了struct/union/bit-fields .. :)谢谢。 – justanotherguy

+1

你似乎把工会的规模与工会成员的规模混为一谈。通常,联合的大小等于其最大成员的大小 - 在这种情况下,它是一个字节,因为所有成员都是字符(四舍五入为字节大小,因为它是实际大小的最小单位) – SomeWittyUsername

回答

5

@tkausl是正确的。在union中,每个成员与内存中的所有其他成员重叠。因此,根据每个字段中的比特数和平台的字节顺序,位字段中的每个字段与其他字段重叠。例如,a1a10可能始终具有相同的值。由于所有的字段在内存中都是重叠的,因此只需要保存最长的9字段所需的字节数。由于一个字节可以做到这一点,这就是union的大小。

3

这些位以什么顺序存储在内存中?

那就是实现定义的。

6.7.2.1结构和联合说明,第11段the C Standard的:

实现可分配任何可寻址存储单元大 到足以容纳一个比特字段。如果剩余足够的空间,紧接在结构中的另一个比特字段之后的比特字段 应该被打包到相同单元的相邻比特中 。如果剩余空间不足 ,则将不匹配的位字段放入 ,则下一单元或与相邻单元重叠的位是 实现定义的。 单位内的位域 的分配顺序是由实现定义的(从高位到低位或从低位到高位)。未指定可寻址的 存储单元的对齐方式。

不同的编译器可以不同地实现位域。请注意,高阶和低阶与大端或小端并不相同。 8位unsigned char的低位是在打开和关闭时增加1的值。相同的8位unsigned char的高位是在其翻转时增加128的值。所以位字段有两个级别的实现定义的顺序:平台/硬件定义的字节顺序和编译器定义的高位或低位赋值。您还可以在位字段之间填充以及是否将相邻单元跨越到实现定义的位字段细节。