C语言之位段(详解)

C语言之位段

1. 位段的介绍

位段(bit-field)是C语言中的一种特殊数据类型,它允许将一个字节分成几个部分,并为每个部分指定特定的位数,以便在内存中存储和访问这些部分。

其中位段相较于结构体有两特殊点

  1. 位段的成员必须是 int unsigned intsigned int char(整型家族) ,在C99中位段的成员也可以是其他类型
  2. 位段的成员名后跟一个冒号和数字

例如:

struct A
{
	int a : 5;
	signed int b : 6;
	unsigned int c : 10;
	//int d : 40; 超出了int类型最大的大小
};

数字的含义:表示占多少bit位的大小,且设置的大小不能超过原类型最大的大小,例如int4 字节,设置的数字就不能超过 32 bit

2. 位段的内存分配

  • 1.位段的成员可以是int unsigned int signed int 或者是 char 等类型

  • 2.位段的空间上是按照需要以4个字节( int )或者1个字节( char )的⽅式来开辟的

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

例子:

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;
	printf("%zd", sizeof(s));
	return 0;
}

代码运行结果:>
3

在VS2022中,位段中的成员是从右向左分配空间的,如果遇到不足位段成员大小的空间,则直接丢弃,在开辟一个字节的空间分配

在这里插入图片描述
在内存中
在这里插入图片描述
第一个字节为 0110 0010 转为十六进制为 62
第二个字节为 0000 0011 转为十六进制为 03
第三个字节为 0000 0100 转为十六进制为 04

3. 位段跨平台问题

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

在C语言中规定,int类型的有无符号是由编译器决定的,但它必须至少能存下-32767~32767的值

int类型在16位机器上是2个字节的,这是你位段分配了超过16bit时就会有问题

位段内存分配没有明确规定,取决于编译器,不同编译器实现的方式不同。在VS2022中,位段成员是从右往左分配内存的,并且如果遇到一个字节中的内存不够时,则会抛弃剩余内存,重新开辟一个字节的内存再分配

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

4. 位段的应用

一下是IP数据报的格式图
在这里插入图片描述
在上述图片中可以看到,有些数据只需几bit的内存空间,位段允许几个数据类型合并在一起,节约了存储内存,⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络的畅通是有帮助的

5. 位段使用注意

位段允许几个小的数据类型合并在一起,这样有的成员的起始位置就不是某个字节的起始位置,在内存中为每个字节分配一个地址,一个字节内部的 bit位 是没有地址

TIPS:不能对位段中的某个成员使用&操作符

既然不能使用&操作符,那么怎么对位段中的成员赋值呢
可以值存入一个变量中,再将变量的值赋给位段中的成员

#include <stdio.h>

struct S
{
	char a : 5;
	int b : 16;
};
int main()
{
	struct S s = { 0 };
	//scanf("%d", &s.a); 这是错误的

	//正确示范
	int n = 0;
	scanf("%d", &n);
	s.a = n;
	return 0;
}
  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

4U247

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

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

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

打赏作者

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

抵扣说明:

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

余额充值