文章目录
- 思维导图:
- 一. 什么是位段
- 二.位段的内存分配
- 三.位段的跨平台问题
- 四.位段的应用
- 结语:
思维导图:
一. 什么是位段
位段的声明和结构体类似,但是有2个不同:
位段的成员必须是int、unsigned int 或 signed int(在很多平台上char类型也没问题)。
位段的成员名后边有一个冒号和数字。
比如:
struct A
{
//成员名:数字
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
那么冒号后面的数字代表的是什么意思呢?
我们发现,通过操作符sizeof求的这个位段式结构体是8个字节,我们明明放的是4个整型,应该是16个字节,那为什么是8呢?
其实是位段中的位,表示的二进制位。
注意,这里的位不能超过类型的位数。
比如int占32个比特位,那么后面的位数就不能超过32。
struct A
{
//成员名:数字
int _a : 2; //2表示a占2个二进制位
int _b : 5; //5表示b占5个二进制位
int _c : 10; //10表示c占10个二进制位
int _d : 30; //30表示d占30个二进制位
};
实际上在外面定义结构体类型的时候,结构体类型里面的成员,有一些取值是十分有限的,并不需要太大的空间,可能只有2bit或者3bit,但如果定义成char类型或者int类型,直接分配了32bit,那这样就会造成空间的浪费。
位段的作用和结构体一样,但比结构体会更节省空间。
二.位段的内存分配
既然位段比结构体更节省空间,那么是不是以后就一直用位段就可以了呢?凡事没有绝对,有好就会有坏。
- 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型。
- 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
- 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
我们还是已上面的那段代码为例:
那么第一次开辟空间剩余15个比特位到底有没有被利用呢?这个其实C语言标准本身并没有定义,这是取决于编译器的,现在以VS2022为例,来验证位段的内存开辟和使用。
通过调试,我们发现在VS2022中,不足的空间,就会重新开辟,不会再利用。
三.位段的跨平台问题
- int 位段被当成有符号数还是无符号数是不确定的。
- 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
- 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
- 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。
总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。
四.位段的应用
在网络的底层,会使用到位段,把网络比作一条高速公路,如果都是大卡车,那势必会造成拥堵,在网络中也是如此,所以会采用位段将数据进行压缩,那么负载就会小很多,速度就会更快。
结语:
~~
相信通过本篇文章的讲解,会对位段有一个更加全面的认识,位段是结构,实现结构体的一种,在写程序的时候是用空间换时间还是时间换空间,这需要做出一定的取舍。
~~
那么本次的分享就到这里,如果对同志们有帮助的话,不妨点赞、评论、关注支持一下,不定期分享干货内容,下期再见!