5分钟带你了解位段

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

对于结构体内部的成员来说,有时候一个int成员的取值是非常有限的,比如一个人的年龄最多只要8个比特位就够了。有些成员甚至只要3个比特位就够了。如果给一个整形的空间似乎有点多,这时就可以使用位段。

一、什么是位段

位段又称为位域是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。C语言中没有专门的位段类型,位段的定义要借助于结构体,即以二进制位为单位定义结构体成员所占存储空间。从而就可以按“位”来访问结构体中的成员。

位段中的位指二进制位

位段的声明和结构是类似的,有两个不同:
1. 位段的成员必须是 int unsigned int signed int
2. 位段的成员名后边有一个冒号和一个数字。
比如:
struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};
A 就是一个位段类型。
那么问题来了
1成员名后边有一个冒号和一个数字代表了什么?
2 那位段 A 的大小是多少?

二、位段的内存分配

首先明确:

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以 4 个字节( int )或者 1 个字节( char )的方式来开辟的。
问题一:
成员名后边有一个冒号和一个数字代表这个变量所占的二进制位。
比如:_a占2个二进制位,_b占5个比特位。
这时_a,_b他们的空间开辟不是直接开辟了一个int类型的空间。
让我们来看问题二:
	printf("%d", sizeof(struct A));

答案:8

//一个例子
struct S
{
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空间是如何开辟的?

位段的空间开辟这里全是char型那么就先开辟1个字节也就是8个比特位,那么问题来了a是从左边开始存还是从右边开始存,事实上C语言对此并没有明确的声明。对于vs环境来说从右边开始存储。a存10二进制为1010,而a只有3个空间截断后存入010,b同理存入1100.到c时开始开辟的8的比特位剩下的空间不够所以将剩下的比特位浪费掉,开辟一个新的字节。存完后如下图。

对于vs环境内一个字节内从低位往高位放入数据,当剩下的空间不够所以将剩下的比特位浪费掉,开辟新的空间。以此类推······

 

 

三:位段的作用

1.优点

其实位段设计出来他的作用和结构体是类似的,他的成员通过加上位后使得节省了空间。

2.缺点

 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

位段的跨平台问题

1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。( 16 位机器最大 16 32 位机器最大 32 ,写成 27 ,在 16 位机
器会出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的

总结:

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

四。使用位段所要注意的问题总结

1)位段的类型只能是int,unsigned int,signed int三种类型,不能是char型或者浮点型;

2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,即位段不能跨字节存储,比如在VC中int是占4个字节,那么最多只能是32位;

3)无名位段不能被访问,但是会占据空间;

4)不能对位段进行取地址操作;

5)若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元(这里的位段存储单元经测试在VC环境下是4个字节)开始存放;

6)若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int。

7)对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果。

8)位段不能跨类型存储,类型不同,也存在字节对应。

9)位段不能出现数组的形式。

五.位段的应用

在网络底层的引用:(IP分装包的一种格式)

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值