位段

什么是位段?

位段的声明和结构体是类似的,但有两个不同之处:

  1. 位段的成员必须是int、unsigned int、signed int或char(属于整型家族)类型。
  2. 位段的成员名后面有一个冒号和一个数字。

举个例子:

struct A
{
	int a : 2;//a只需要2个比特位
	int b : 5;//b只需要5个比特位
	int c : 10;//c只需要10个比特位
	int d : 30;//d只需要30个比特位
};

这里的A就是一个位段类型。

注:冒号后面的数字代表该成员需要用的bit位的位数,所以该数字不能超过该成员变量的变量大小,单位为bit。

int e : 33;//error

位段大小的计算

知道了什么是位段,那么位段的大小是如何计算的呢?
规则:位段的空间是按照需要,以4个字节(int)或1个字节(char)的方式来开辟的。
举个例子:

struct S
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
};

首先,该位段类型的成员类型是char类型,我们一次开辟1个字节(即8个bit位)的内存大小(不够再继续开辟)。

第一次开辟的8个bit位中,成员a用去了3个bit位,成员b用去了4个bit位,此时剩下1个bit位,而成员c需要5个bit位,于是又新开辟8个bit位,到这里便有两种情况:

  • 情况一:成员c先把上次开辟的8个bit位中剩下的一个bit位用去,再在新开辟的8个bit位中用去4个bit位。
  • 情况二:成员c之间使用新开辟的8个bit位中的5个bit位,而上次开辟的8个bit位中剩下的那个bit位被浪费。

关于这一点,C语言标准并没有定义,于是不同编译器就可能按照不同的方式来计算。我当前使用的VS2013是按照第二种情况进行计算的,所以此时成员c用去了新开辟的8个bit位中的5个bit位,剩下3个bit位,不够成员d使用,所以又新开辟8个bit位供成员d使用,一个开辟了3次,即24个bit位,即3个字节,所以该位段类型的大小在VS2013编译器下的大小为3个字节。

位段的内存分配

#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;
	s.b = 12;
	s.c = 3;
	s.d = 4;
	return 0;
}

上面我们已经计算了该位段类型在VS2013编译器下的大小为3个字节,那么当我创建一个该位段类型的变量并对齐赋上一些值时,这些值在内存中是如何分配的呢?

在内存分配的过程中又可能遇到一个问题:当开辟好8个bit位,我们使用这8个bit位的时候,是从左向右使用还是从右向左使用的呢?
这又是一个C语言标准尚未定义的规则,所以不同编译器下又可能不一样,在VS2013编译器下经测试是按照从右向左使用的。

于是在VS2013编译器下是这样分配的:
在这里插入图片描述
当把赋的值分配进去时就是这样的:
在这里插入图片描述
因为在赋值之前已经将创建的位段类型的s变量赋初值为0了,所以白色区域(即浪费了的区域)代表的数字就是0。
于是把赋的值分配进去后,这3个字节的内容用二进制表示就是:
01100010 00000011 00000100
将其化为十六进制就是:62 03 04
在这里插入图片描述

位段的跨平台问题

在上面我们已经看到了,关于位段的很多问题都是C语言标准未定义的,所以在不同编译器中的情况就会不一样,造成位段跨平台问题的主要原因有以下几点:

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

所以在考虑是否使用位段时要十分小心,因为跟普通的结构体相比,位段虽然可以达到同样的效果,并且可以很好地节省空间,但是存在跨平台的问题。

位段的应用

当我们用微信或是QQ向好友发送消息时,只需将要发送的内容写入对话框并点击发送即可,但你以为这其中的过程真的就那么简单吗?

其实比你想象的要复制得多,当你要发送一条消息给某人时,系统必须知道这条消息从哪里来,要到那里去以及这条消息的生存时间等等,如下图:
在这里插入图片描述
这时,我们运用位段就能节省大量空间,而且当我们发消息时,因为发出去的数据包越小,我们的信息传输效率就会越高,这好比在高速公路上如果全是小汽车(位段类型将空间运用到极致),那么交通会很流畅,而如果全是大卡车(普通结构体类型占用空间较大),那么就会造成交通堵塞。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021dragon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值