位字段

位字段由一个结构体声明建立,通过用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 的实验下的结果,位字段有很强的机器依赖性,对于边界对齐或位顺序往往不一致。因此导致难以移植。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容