C | 结构体实现位段

目录

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

前言

小伙伴们,我们上次学习了C语言中自定义数据类型的结构体,今天我们来学习一个更为深入的问题。

那就是用结构体实现位段。

小提示:如果没有看过结构体相关知识的小伙伴可以点击链接跳转哦!

结构体的相关知识

C | 结构体实现位段_第1张图片

什么是位段

什么是位段呢?

这里要注意啊!!

是位段!!

不是段位!!

千万不要搞混淆了哦~

C | 结构体实现位段_第2张图片

其实我们可以认为,位段就是一种特殊的结构体!

但是也与结构体有所区别。

位段的声明与结构体是相似的

  1. 位段的成员必须是整型家族的,如char、 short、int、unsigned int 或signed int等 。
  2. 位段的成员名后边有一个冒号和一个数字。

比如:

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

上面的代码就是一种位段的类型。

位段的内存分配

下面我们来看看位段的内存分配。

大家认为上面举例子的代码,struct A 的大小是多少呢?

我在VS2019默认的编译环境下,大小为8.

那么这是为什么呢?

以下就是位段内存分配的规则:

位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
定义位段数据大小的时候,不可以超过变量本身的字节数大小。

也就是说,位段开辟空间的时候,会先看第一个数据类型是什么,如上述代码第一个数据类型为int,而int类型默认是4个字节,那么就会直接开辟4个字节,也就是32个bit。

此时int a :2;后面的这个数字2,表示a只会占用32个bit中的2个。

此时剩下30个bit,那么b也会占用5个bit,c也会占用10个bit.

这时候,还剩下15个bit,不够30个,那么就会再一次开辟4个字节,用来存放数据。

需要注意的是

每个变量后面的数字,不可以超过变量类型本身的大小。这个栗子的话,就是后面的数字不能超过32.

位段的跨平台问题

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

位段在实现中的很多细节,C语言的语法并没有做出规定。

如:
一个字节内部8个bit的数据是如何使用的?

先使用低bit还是高bit?

创建的int的32个bit是按照无符号整型还是有符号整型来处理?

如果剩下的bit不够用来存放数据的时候,开辟了新的空间,那么是舍弃原来的不够的空间,直接使用新开的空间,还是先把剩下的空间用完,不够的在使用新的空间?

这些都是未知的,取决于编译环境。

我使用的是VS2019,此时在一个字节内部,位段是先使用低bit再使用高bit,而且如果要输入的数据超过了规定的bit大小,那么就会发生截断,舍弃高位溢出的数据,保留低位。

而且如果剩下的bit不够之后,会开辟新的空间,原来不够的剩下的空间会舍去。

C | 结构体实现位段_第3张图片

此外,除了上面提到的问题,还有就是位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

正是由于这些不确定性,使得位段不具有跨平台性。

所以,再一些情况下, 能够用结构体解决的问题,我们就尽量用结构体的方式来解决。

位段的应用

尽管位段不具有跨平台性,但是在一定的环境下还是有用武之地的。比如在一些内存比较小的运行坏境下,合理的使用位段,可以使得数据利用的更加合理,避免不必要的浪费。

比如,假如我们需要一个变量来表示性别的话,如果女用0表示,男用1表示,那么我们完全可以只用一个来bit,这样就算是定义最小的char还能剩下7个bit。

当然,使用位段的时候,我们要清楚的明白当前环境下位段的使用特点,只有做到了解明白,才不至于使用错误。


补充:

位段的使用,一般是内部的成员变量都是同一类型的情况下使用。

要么全部都用int,要么全部都用char,至于混用的情况,由于我的水平有限,也没了解。如果有了解的小伙伴,欢迎你们能够教教我哦!

结语

由于本人水平有限,难免会有说错或者说的不够好的地方,希望各位能够指出!

今天的学习到这里就结束啦!希望各位能够给我点个关注,点个赞哦!

有什么想说的也欢迎再下面留言哦~

C | 结构体实现位段_第4张图片

你可能感兴趣的:(c语言,开发语言,后端)