1.1 什么是位段
1.2 位段的内存分配
1.3 位段的跨平台问题
位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 int、unsigned int 或signed int(当然,位段也可以是char类型,但是如果一个是char类型,其它就都得是char类型) 。
2.位段的成员名后边有一个冒号和一个数字。
比如:
struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
A就是一个位段类型。 那位段A的大小是多少?
上面的位段A输出结果为8!
注意:位段中的位是二进制位!
注意:像上面的_a后面的数字最大只能是32,不能超过32,因为我们在进行开辟空间时是以4个字节位单位进行开辟的。
1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
解释struct A为什么占据8个内存空间?
首先开辟一个整型内存空间。一共可以放32个比特位,_a,_b,_c总共占据17个比特位,此时这个整型空间只剩15个比特位了,无法将_d的30个比特位存放进去,此时就要把刚才剩下的15个比特位浪费掉,重新开辟一个整型的内存空间,存放_d中的30个比特位,此时一共占据了2个整形空间,即8个比特位!
举例说明在内存中的详细布局:
#include<stdio.h>
struct S
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct S s = { 0 };//下面的数据从左向右依次是原数据----二进制位----在内存中存储的数据
s.a = 10;//10----1010----010
s.b = 20;//20----10010----0010
s.c = 3;//3----11----00011
s.d = 4;//4----100----0100
//下面是在内存中真正存储的数据
//在VS中默认是从右向左存的,但是其它平台不确定,所以位段不具有较好的移植性
//第一个char型空间:0 0010 010----2 2(16进制的形式)
//第二个char型空间:000 00011(c)----0 3(16进制的形式)
//第三个char型空间:0000 0100(d)----0 4(16进制的形式)
//所以在内存中的布局应为22 03 04
return 0;
}
运行截图:
1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机 器会出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的。
总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/m0_57304511/article/details/122460735
内容来源于网络,如有侵权,请联系作者删除!