C++ 位域详解

今天做EA的笔试最后一道题考到了

struct Mystruct{
	int a:2;
	int b:3;
};
int main()
{
	MyStruct m{ 2,2 };
	cout << m.a<<" "<< m.b;
}

问输出是啥?
当时我就懵逼了,不会。
后来查了一下,微软官网是这么讲的:
https://docs.microsoft.com/zh-cn/cpp/cpp/cpp-bit-fields?view=msvc-160

C++ 位域

类和结构可包含比整型类型占用更少存储空间的成员(由此可见主要作用是节省内存啊)。 这些成员被指定为位域。
位字段 成员声明符 的语法如下所示:
声明符 :常量表达式
a:2;
其中声明符不是必须有,是在程序中访问该成员时所依据的名称。 它必须是整型类型(包括枚举类型)。
常量表达式指定成员在结构中所占用的位数。上面a占2bits,b占3bits。
匿名位域 — 即不带标识符的位域成员,可用于填充。

ex:

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)
};

内存结构示意图如下:声明为位域的数据从低位到高位进行排序
内存结构示意图

struct Date {
   unsigned nWeekDay  : 3;    // 0..7   (3 bits)
   unsigned nMonthDay : 6;    // 0..31  (6 bits)
   unsigned           : 0;    // 匿名位域变量.作用是强制对齐到下一个unsigned区域
   unsigned nMonth    : 5;    // 0..12  (5 bits)
   unsigned nYear     : 8;    // 0..100 (8 bits)
}

内存结构示意图如下:
在这里插入图片描述
ok知道位域是什么了,来解那道题
int a:2;
int b:3;
的意思就是a占两个bits,b占3个bits。

MyStruct m{ 2,2 };

之后,m共占4个字节,其中0~1bits为10,2 ~4bits为010;这样

cout << m.a<<" "<< m.b;

的结果是-2,2了。
可以看到这种结果一般不是我们想要的,明明给a赋值了2,再次访问时居然变成了-2。原因是int用补码表示,2应该是010,但是只给a分配了2个bits,最高位的被舍弃,所以变成了10,10补码表示其实是-2。如果这里int换成unsigned int,就不会出现这种情况了。所以一般声明为位域的变量类型最好用unsigned int。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值