【C语言】位段详解

简介: 【C语言】位段详解

前言

上一篇文章,我们学习了结构体的相关知识,今天我们来学习和结构体很像的位段

自定义类型:结构体

位段

位:指的是二进制位

位段的声明

位段与结构体的声明有两个不同:

1.位段的成员必须是 int、unsigned int 或signed int 。

成员类型是固定的:char类型也可以,但不要char和int类型混用,类型要保证一致

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

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

第三点在“位段的不跨平台性”会详细介绍

例子

struct A
{
  int a : 2;
  int b : 3;
};

位段的大小

下面代码的运行结果是什么

struct S
{
  int a : 2;
  int b : 5;
  int c : 10;
  int d : 30;
};
int main()
{
  struct S s;
  printf("%zd\n", sizeof(s));
  return 9;
}

结果:8byte

解释

位,在开始时.提到了,是二进制位(bit位)

我们假设a的范围是0~4,不会更大也不会更小,那么a就不需要用那么大的空间(32个bit位)去存储,它只需要2个bit位就能存储

所以,成员名冒号后面的数字指的就是:用多少个bit位去存储这个成员(数字不能超过类型的最大bit位数)

按照这么算

2+5+10+30 == 48,但结果不对

下面就来介绍位段的内存分配

位段的内存分配

struct S
{
  int a : 2;
  int b : 5;
  int c : 10;
  int d : 30;
};

还是这段代码

我们都知道,int类型是32个bit位

a、b、c共占用了17个bit位,剩下15个bit位,存不下d(30个bit位)

就开辟新的整型空间存储d

所以,总大小就是8个字节

这样就很节省空间了

例题

下面通过这段代码,来讲解一下是如何存储的

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;
}
开辟空间

根据上面的规则,开辟出三个字节存储a、b、c、d

(如何存储后面会做说明)

赋值

a是10,二进制表示就是:1010

但a只能存储三个bit位,所以此处存的是010

b是10100,只能存四个bit位,是0100

c是011,c有5个bit位,

不够,那就高位为0

d存储的是0100

所以最终存储的就是:

0010 0010 0000 0011 0000 0100(二进制)

22 03 04 cc cc(十六进制)(后面的没开辟,不用管)

位段不跨平台性

  1. int 位段被当成有符号数还是无符号数是不确定的。
  2. 位段中最大位的数目不能确定。

16位机器最大16,32位机器最大32,当写成27个bit位时,在16位机 器会出问题。

  1. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  2. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的

位段的应用

我们在网络上传输信息的时候,需要先将信息进行封装,

上图解释了需要封装进哪些信息,如果使用位段就能很好的存储进每个数据,如果不用位段,那数据包大小就会很大(现阶段,了解即可)

结语

位段的介绍和学习到这里就结束了

下篇文章我们会学习自定义类型中的枚举和共用体

我们下篇文章见~


相关文章
|
6月前
|
存储 编译器 C语言
C语言位域
C语言位域
48 0
|
6月前
|
存储 编译器 C语言
C语言共用体
C语言共用体
43 0
|
6月前
|
存储 C语言
c语言中的共用体
c语言中的共用体
48 0
|
存储 C语言
20 C语言 - 共用体
20 C语言 - 共用体
42 0
|
3月前
|
编译器 程序员 Linux
【C语言篇】结构体和位段详细介绍
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
43 3
|
6月前
|
存储 网络协议 C语言
C语言——详解位段
C语言——详解位段
49 0
C语言——详解位段
|
6月前
|
C语言
【C语言】结构体实现位段
对位段进行介绍,什么是位段,位段如何节省空间,位段的内存分布,位段存在的跨平台问题,及位段的应用。
43 0
|
存储 编译器 C语言
21 C语言 - 位域
21 C语言 - 位域
34 0
|
编译器 C语言 C++
C语言之位段
C语言之位段
|
编译器 C语言 C++
C语言【位段篇】
前言:相信大家写题的时候,都会遇到这种问题:这个专业名词是什么?不知道,算了,不做了(反正也不是能力问题) 位段这个名词就很常见,接下来,砸门来聊一聊有关位段的这些事