二:位段
2.1:什么是位段?
位段(bit-field)以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。
位段的声明和结构体十分相似,但同时有两个不同点:
位段的成员必须是int、unsigned int、signed int等整型家族的类型。(大部分平台也支持char类型。一个位段的所有成员类型一般都是相同的)
位段的成员名后边有一个冒号和一个数字(该成员所占内存空间大小,单位为 bit位)。
#include<stdio.h> struct test { int _a : 2; //成员 a 只占用 2 个比特位 signed int _b : 5; //成员 b 只占用 5 个比特位 unsigned int _c : 10; //成员 c 只占用 10 个比特位 char _d : 4; //成员 d 只占用 4 个比特位 }; int main() { printf("%d\n", sizeof(struct test)); return 0; }
采用位段结构的好处是能够节省大量的空间,通过有条件地(根据实际使用需求)限制每个变量所占内存空间的大小,从而减少了整体结构的空间占用.
2.2:位段的内存分配
首先我们需要知道,位段中的"位"指的是二进制位。int _a : 2; 表示给 _a 变量分配2个bit位();int _b : 5; 表示给 _b 变量分配5个bit位,以此类推:给== _c== 变量分配10个bit位,给 _d 变量分配30个bit位。
结构体能干什么位段就能干什么,位段只是比结构体更节省空间而已。
位段的成员可以是 int 、unsigned int 、signed int 或者是 char(属于整形家族)类型
位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
int 的位段的内存分配是逐4字节(一个 int 类型的大小)进行分配的。
当字节内空间不足以放下下一个成员变量时,剩余的空间不再使用,而是再从内存中申请一个字节的空间继续分配。
struct A的位段成员都是int型,所以会按照4个字节来开辟空间,首先开辟第一个4字节的空间(32bit),_a占用其中的两个bit位,_b占用里面的五个bit位,_c占用里面的十个bit位,此时,第一次开辟的4个字节(32bit)只剩下15bit了,而_d需要30bit,因此空间不够,需要再开辟第二个4字节空间(32bit),所以struct A这个类型的大小就是8个字节(64个bit位)。
2.3:验证vs2019上位段的内存分配和使用
2.4:位段的跨平台问题
我们上面说过,位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段,并且在未来位段结构的使用过程中,我们一定要提前仔细地研究好位段在不同编译器下使用时,究竟是如何进行内存分配的,再结合我们的实际需求实现跨平台使用。
而在位段进行跨平台使用时,我们通常需要注意以下四个关键点:
int位段被当成有符号数还是无符号数是不确定的
位段中最大位的数目不能确定。(比如 int 型在16位机器中最大只有16bit,在32和64位机器上最大有64bit)
位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义
当一个结构体包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的 bit 位时,是舍弃剩余的位还是利用,这也是不确定的
总结:
跟结构相比,位段可以达到跟结构相同的效果,并且可以更好的利用空间,但同时存在着跨平台问题
2.5:位段的应用
位段会被应用在网络数据传输中,它可以有效缓解网络“拥堵”。
总结:
今天,我们从结构体的一般声明开始,了解了一种特殊的声明(匿名结构体),学习了结构体变量的定义和初始化,探究了结构体的内存对齐,并介绍了修改默认对齐数方法,最后介绍了一种特殊的结构体——位段,它的最大优点是比普通的结构体更加节省空间。
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕😘😘💕 ~ ~ ~ 你们的点赞和关注对我真的很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!
专栏订阅:
每日一题
c语言学习
算法
智力题
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!