C++ 位域及其内存分布

本文中的代码,插图来自:

https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?redirectedfrom=MSDN&view=msvc-160

在C++的结构体或者类中,我们可以通过位域运算符来进一步限定成员变量占几个bit,比如

// bit_fields1.cpp
// compile with: /LD
struct Date {
   unsigned short nWeekDay  : 3;    // 0..7   (3 bits)
   unsigned short nMonthDay : 6;    // 0..31  (6 bits)
   unsigned short nMonth    : 5;    // 0..12  (5 bits)
   unsigned short nYear     : 8;    // 0..100 (8 bits)
};

在上面的结构体中,我们通过位域运算符限定:nWeekDay占3个比特位,nMonthDay占6个比特位,nMonth占5个比特位。

那么当我们使用了位域运算符后,各个数据成员在内存中时怎么分配的呢,还是以上面的结构体为例,它的内存分布如下图所示:

由于unsigned short 类型是2个字节,16位比特,在内存排布的时候是以sizeof(unsigned short)= 16 bits为单位,当放完nWeekDay,nMonthDay,nMonth后,第一个unsigned short只剩下2 bits的空间,nYear占8 bits,如果从第一个unsigned short剩余的2bits开始放nYear,那nYear就溢出了,这时候,我们就舍弃这两个bits,从第二个新的unsigned short的开始处开始存放nYear。

未命名域

有时候,我们也可用未命名域来填充一个分配单元中剩下的bit,比如下面的例子:

// bit_fields2.cpp
// compile with: /LD
struct Date {
   unsigned nWeekDay  : 3;    // 0..7   (3 bits)
   unsigned nMonthDay : 6;    // 0..31  (6 bits)
   unsigned           : 0;    // 未命名域,unamed field, Force alignment to next boundary.
   unsigned nMonth    : 5;    // 0..12  (5 bits)
   unsigned nYear     : 8;    // 0..100 (8 bits)
};

上面这个struct的内存分布如下所示:

一个unsigned 类型,占4个字节(32 bit),nWeekDay, nMonthDay 共占用9 bits, 还剩下23 bits, unsigned    :0 是一个未命名域,它的作用就是占用剩下的23 bits,这样nMonth 就可以从一个新的unsigned 类型的起始地址开始排布了 。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值