浅谈C语言位段

[复制链接]
发表于 2026-2-9 07:41:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1、位段的界说

百度百科中是如许表明位段的:
位段,C语言答应在一个布局体中以位为单元来指定其成员所占内存长度,这种以位为单元的成员称为“位段”或称“位域”( bit field) 。使用位段可以或许用较少的位数存储数据。
以下,我们均在VS2022的编译情况下去探究和明白位段
2、位段的声明和使用

A、位段的声明

位段是与布局体相团结的,只有在布局体中才气使用位段,位段使用的根本目标是为了节省不须要斲丧的内存空间。

这是位段的声明,这里有4个点必要留意:
1、上图中的1、2、3均是指比特位,即bit,一个二进制位
2、位段的实用范例只限于整型眷属
3、同一个布局体中,使用位段时最好保持此中成员范例均雷同
4、位段的巨细不能凌驾该范例的实际巨细,比如说对于char范例,最多只能是8个比特位,对于int范例,最多只能是32个比特位
B、位段的使用

以下是位段的简朴使用:

3、位段的内存巨细的盘算

思量到在差别的平台情况下,位段的内存巨细盘算有所差别,以下关于位段内存巨细的盘算是基于VS2022的编译情况:

例1:


在位段中,编译器看到char范例便会向内存中申请1个字节的空间。
a占去5个比特位,还剩3个比特位;b将这3个比特位占掉,此时第1个字节的空间用完。
紧接着的成员是char范例的c,又会开发1个字节的内存空间,c占去4个比特位;
成员d要占去5个比特位,但是之前开发的1个字节中仅剩4个比特位,不敷用,以是将这4个比特位
舍去,重新开发1个字节用以存储d,故终极该位段的巨细为3个字节


例2:


VS编译器看到int范例的成员,便会向内存申请4个字节的空间
a占去1个比特位,还剩31个比特位;b在这剩余的31个比特位中占去30个比特位,还剩1个比特位;
c要占去4个比特位,剩余的1个比特位显然不敷用,以是再开发4个字节的内存空间,在这新开发的4个字节中,c占到4个比特位
d则是在剩下的28个比特位中占20个比特位
以是,该位段的巨细为8个字节.

4、位段在内存中的存储方式

思量到位段在差别的编译器下存储方式有所差别,以下的讨论均基于VS2022。
探究位段在内存中的存储方式,其本质是去探究,在开发的1个字节或4个字节的空间中,各个布局体成员在该空间内部是从左向右(低所在向高所在)存储的,还是从右向左(高所在向低所在)存储的。
我们这里先说结论:位段在内存中是从右向左存储的,即高所在向低所在存储的
以下举行干系验证:
  1. struct S
  2. {
  3.         char a : 1;//1
  4.         char b : 6;//001010
  5.         char c : 4;//0101
  6.         char d : 3;//011
  7. };
  8. //0001 0101     0011 0101
  9. // 1     5       3    5
  10. int main()
  11. {
  12.         struct S s = { 0 };
  13.         s.a = 1;//1
  14.         s.b = 10;//1010
  15.         s.c = 5;//101
  16.         s.d = 11;//1011
  17.         return 0;
  18. }
复制代码
将s初始化为0,则s的2个字节,16个比特位中均为0
在s的第1个字节空间中,从右向左存储,将a存储进去,存储的是1;b在初始化后6位二进制中放的是000000,在赋值后,存储的是001010,故第1个字节中存放的是 00010101
在s的第2个字节空间中,从右向左存储,将c存储进去,存储的是0101
由于d只有3个比特位的空间,故赋值11时会发生截断,实际存储到d中的是011,因此第2个字节中存放的是 00110101
将这2个字节转换为16进制表现则为 : 15  35
接下来我们通过内存窗口举行观察验证:

可以看到内存中存储简直实为15 35,阐明在VS2022的编译情况下,位段在内存中确实是从右向左(高所在向低所在)存储的


5、位段的范围

位段有很多的范围,这些范围也就导致了位段的跨平台性很差:
1、位段中int范例是当作 signed int 还是 unsigned int 这是不确定的
2、位段中最大位的数目不能确定。位段的巨细除了不能凌驾相应范例的实际巨细外,还不能凌驾呆板的位数。在16位的呆板上,位段最大为16个比特位;而在32位的呆板上,位段最大为32个比特位
3、位段在内存中究竟是从左向右存储,还是从右向左存储,这是标准未界说的
4、在1个布局体中,开发的内存空间在容纳完1个位段后,剩余的位无法容纳第2个位段时,这些剩余的位是使用还是不使用,这是不确定的
综上所述,为了包管步伐的可移植性,应只管克制位段的使用。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表