位字段

2017-04-09  本文已影响0人  tarzipc

位字段由一个结构体声明建立,通过用signed int 或 unsigned int 中的一组相邻的位表示。
这里假定int = 4字节,事实上大部分也是4字节--

按4字节对齐的话
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0001
    unsigned bld:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0010
    unsigned und:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0100
} duct;
sizeof(duct) = 4

通过pragma 改变对齐字节,高位没有用到的字节被截断
#pragma pack(2)
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;; 0000 0000 0000 0001
    unsigned bld:1;     // = 1;; 0000 0000 0000 0010
    unsigned und:1;     // = 1;; 0000 0000 0000 0100
} duct;
#pragma pack()
sizeof(duct) = 2

#pragma pack(1)
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;; 0000 0001
    unsigned bld:1;     // = 1;; 0000 0010
    unsigned und:1;     // = 1;; 0000 0100
} duct;
#pragma pack()
sizeof(duct) = 1

匿名字段
可以通过匿名字段填充位


#pragma pack(2)
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;; 0000 0000 0000 0001
    unsigned    :2;     //           下一个位将从(↓)4开始
    unsigned bld:1;     // = 1;; 0000 0000 0000 1000
    unsigned und:1;     // = 1;; 0000 0000 0001 0000
} duct;
#pragma pack()
sizeof(duct) = 2

另外将匿名字段宽度设置为0,将会强制下一个字段与一个整数对齐
#pragma pack(2)
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;; 0000 0000 0000 0000  0000 0000 0000 0000 0000 0000 0000 0001
    unsigned    :0;     //              下一个位将从(↓)33开始
    unsigned bld:1;     // = 1;; 0000 0000 0000 0001  0000 0000 0000 0000 0000 0000 0000 0000
    unsigned und:1;     // = 1;; 0000 0000 0000 0010  0000 0000 0000 0000 0000 0000 0000 0000
} duct;
#pragma pack()
sizeof(duct) = 6

若剩下的位数不足以放下下一个字段要求的位宽度,将会自动补齐,如以下例子中all要求15位,而剩下的仅13位
#pragma pack(2)
struct {                //unsigned int = 4byes = 0000 0000 x 4
    unsigned aut:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0001
    unsigned bld:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0010
    unsigned und:1;     // = 1;;0000 0000 0000 0000 0000 0000 0000 0100
                        //                     从(↓)结束         从(↓)开始
    unsigned all:15;    // = 1;;0000 0000 0000 0000 0000 0000 0000 1000
                                └────填充的位──────┘
} duct;
#pragma pack()
sizeof(duct) = 4;

以上这些是在windows cygwin clion 的实验下的结果,位字段有很强的机器依赖性,对于边界对齐或位顺序往往不一致。因此导致难以移植。

上一篇 下一篇

猜你喜欢

热点阅读