(C语言进阶)位段

位段是C语言中一种节省内存的结构,它将变量存储在同一个字节的多个位上。位段的内存分配通常基于int或char类型,但不保证跨平台兼容性。在VS环境下,位段分配从低位开始,不足的部分会被浪费。位段在数据传输封装中用于高效利用空间,如在网络协议中定义字段。然而,由于跨平台问题和不确定性,位段在可移植性要求高的代码中应谨慎使用。
摘要由CSDN通过智能技术生成

本节重点内容: 

  • 什么是位段
  • 位段的内存分配
  • 位段的跨平台问题
  • 位段的应用

1.什么是位段

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

1.位段的成员大多是 int、unsigned int 或signed int 也可以是char类型的(属于整形家族)。

2.位段的成员名后边有一个冒号和一个数字。

struct A
{
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
};

位段的“位”其实指的是二进制位 。

位段到底是如何分配空间的呢?位段到底占多大空间呢?(1个字节是8个bit位)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct A
{
    int _a : 2;
    int _b : 5;
    int _c : 10;
    int _d : 30;
};//47bit

int main()
{
    struct A sa = { 0 };
    printf("%d\n", sizeof(sa));
    return 0;
}

输出结果如下: 

本身没有优化之前应该是4个int型16个字节,共16*8=64bit位 ,经过优化之后只占8个字节。相较于原来的16个字节省了8个字节,如果只按位段的需求只需要47位,只浪费了(8*8-47=)17个bit位。其实已经节省了很多空间了。

2.位段的内存分配

  1. 位段的成员可以是 int、 unsigned int、 signed int 或者是 char (属于整形家族)类型。
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
     

需要注意的是第三点,C语言并没有规定说申请剩余的空间并不能够下一个成员进行使用,虽然分配了空间,但是该空间要不要被利用掉,这种事情是不确定的,取决于编译器。同时开辟空间后申请的比特位,到底是从高向低使用还是从低向高使用?因为存在多种不确定的因素,因此位段是不跨平台的,同时注意可移植的程序避免使用位段。

”剩余的15bit位“

 那么我们在vs的环境下进行实验位段是如何开辟空间的:

//vs环境下位段的内存分配
#define _CRT_SECURE_NO_WARNINGS
#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;
}

 在vs的环境下通过内存调试得到结果:

(内存中每4个二进制位为1位十六进制位) 

分析:

 0110=6 0010=2 0000=0 0011=3 0000=0 0100=4

首先为char类型的也就是申请空间时,应该申请1个字节,共1*8个bit位,然后分别计算出abcd的二进制表示,分配到的内存中的比特位是从右向左使用,根据申请多大位段再放入多少二进制位(二进制位长度大于位段长度的只取位段长度,二进制位长度小于位段长度的在前面进行补0填充二进制位长度),之后对于分配的内存剩余比特位不够使用时,浪费掉,再从新的空间进行分配。

注意:这里仅仅是vs的环境下位段的开辟空间,不同编译器会有不同的结果。

3.位段的跨平台问题

  1. int 位段被当成有符号数还是无符号数是不确定的。(不同的编译器会有所差异)
  2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。(16位机器上整形int大小为2个字节有16个bit位,如果位段申请30,可能编译不过去)
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:

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

4.位段的应用

数据传输的格式封装:

 应用场景分析:例如我们在网上聊天时,A想发送一条信息“hello”给B。

为了保证信息能更够准确的传输给B而不是其他人,不仅仅是把数据传给另一方,而且也需要很好的格式的分装。而这些分装中包含了4位版本号,8位服务类型,16位总长度等等。如果不考虑大小,随意设置成int大小,char大小,会存在了浪费空间的情况。这样整个数据包的大小变小了,这样网络传输数据就变小了。

想象一下网络高速公路上全是很大的数据传输,那么传输速度肯定会受影响。如果我们将数据进行合理的分装,这样大的“汽车”就会少一些,而且能够容纳更多的”汽车“。而且告诉“网络高速公路”的状态也会更好一些,“汽车变小”意味着数据传输更快,网络传输数据的负载下降了,可以容纳更多。

因此,我们在分装的时候把数据变小就行,所以把这些结构体成员设置成位段,这样让我们的使用效率更高。

 (本节完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值