分享

UC头条:结构体位段问题

 cnzrp 2023-06-06 发布于山西

什么是位段

位段的详细解释

位段其实也是一种结构体的类型

1.位段的成员是int,shortintunsignedint,signedint,short,char类型

2.位段的成员名后有一个冒号和一个数字

看一个例子:

structS{inta:2;intb:5;intc:10;intd:30;};intmain{structSs={0};printf('%zd\n',sizeof(s));//%zd--打印无符号整型}

或许你猜的是47,我们来看一下结果

点击加载图片

打印出8的原因,在于下面:

其实,位段-----位----二进制位

也就是说,冒号后面的数字,表示的是二进制数

我们先看整体,结构体中所有的成员都是int类型,而int类型是4字节,1字节是8个比特位,4字节就是32比特位,

进入结构体内部,先创建了一个int类型的空间,

a占用2个比特位,b占用5个比特位,c占用10个比特位

abc在内存中的分布如下图:

点击加载图片

但此时这4字节中,剩下的比特位不够30个,存放不了b,所以还需再开辟一个int类型的空间,即4个字节,来存放d

(因为成员类型是int类型,刚才一次性开辟了4个字节的空间)

点击加载图片

在内存中从右向左存储

所以,总体成员内存布局如上图:

这里你可能会有个疑惑,为什么不是在c的后面开始占用空间?

因为第一次开辟了4个字节(一个int类型)的空间,存放了a,b,c后,发现剩下的空间不够存放d,所以另外再开辟4个字节的空间,从这新开辟的空间中存放d。所以灰色的区域就是浪费了。

还有一个问题,位段后面的数字能大于32吗?

其实是不行的,一个int类型是4字节,32比特位,不能大于32,如果强行大于32呢?

点击加载图片

强行大于32就会报错。

所以位段是用来节省空间的

这里可能又有疑惑了,刚刚明明说浪费了灰色区域的空间,现在又说是节省空间,自相矛盾了。

你可以想想,如果不使用位段,那么就会开辟4个int类型的空间,就会开辟16字节的空间,但是使用位段,只开辟了8字节的空间,你说是不是节省空间呢?

再来看一个例子:

structT{chara:3;charb:4;charc:5;chard:4;};intmain{structTt={0};printf('%zd\n',sizeof(t));t.a=10;t.b=20;t.c=3;t.d=4;printf('%d%d%d%d',t.a,t.b,t.c,t.d);}

请问输出的结果分别是什么呢?

第二个printf可能你脱口就说出,分别打印102034嘛

这么简单,而第一个printf,有了第一个例子的参照,我们可以计算t的空间大小

点击加载图片

a和b在内存中的布局如图,由于c占5个比特位,剩余空间不足c使用,再开辟一个char的空间

如下图:

点击加载图片

剩下的3个比特位又不足够d使用,d需要4个比特位,故再开辟一个char类型的空间

点击加载图片

所以t的总大小是3个字节,第一个printf打印的是3,但是第二个printf真的是打印刚才说的

102034吗?

来看答案:

点击加载图片

为什么会出现2434呢?好像毫不相干。

先听我解释:

t.a=10,我们知道,a只需占用3个比特位,而10的二进制表示形式是1010

占用3比特位,从右往左拿3个,那就拿010,放入内存中。

如下图:

点击加载图片

同理,t.b=20,20的二进制表示形式是10100,从右往左,取4个,即0100,放入内存中,

t.c=3,3的二进制表示形式是011,从右往左,取5个,可是011不够五个呀,不够的那就补0就好了,所以就取00011,放入内存中,

t.d=4,4的二进制表示形式是0100,放入内存中,所以,内存中的布局如图:

点击加载图片

如何观察到这个现象呢?内存中是以16进制展现出来的,我们就先分析一下

点击加载图片

每4个二进制数就是一个16进制数,那么16进制数就是220304,来验证结果:

点击加载图片

完美符合预期:

打印出来是2434的原因是:

点击加载图片

a,b,c,d的二进制序列化为十进制后就如上图,故打印的是2434。

看到这里,你应该明白了位段是什么

不过,位段这个东西,是没有官方的标准规定的,在不同的平台,位段的使用也不同。

总结:跟结构相比,位段可以达到同样的效果,可以很好地节省空间,但是有跨平台问题的存在。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多