返回

位段的讲解与计算

发布时间:2023-01-31 14:56:28 256

/*

什么是位段

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

1.位段的成员必须是int、unsigned int、signed int或char(属于整型家族)类型

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

举个例子:

struct A

{

 int _a:2;

 int _b:5;

 int _c:10;

 int _d:30;

};

1

2

3

4

5

6

7

这里的A就是一个位段类型。

那么位段类型中的成员的冒号后的数字代表什么意思呢?

其实冒号后面的数字代表该成员需要用的bit位的位数;所以该数字不能超过该成员的变量类型大小。

如下位段的错误定义:

struct B

{

  int _x:33;//error 因为int型大小为4字节即32个bit,33超过了32

  char _y:9;//error char型大小为1字节即8bit(同上)

}

1

2

3

4

5

知道了位段是是什么,那么如何计算位段的大小呢?是否就是将位段中的每个成员的大小相加?


位段的内存分配

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

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

若成员为int型,则以4个字节的方式开辟,若成员为char型,则以1字节的方式开辟。

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

struct S

{

 char a:3;

 char b:4;

 char c:5;

 char d:4;

};

struct S s = {0};

 s.a:10;

 s.b:12;

 s.c:3;

 s.d:4;

分配方式:

1.因为位段中的成员类型为char型,所以空间上是按照1个字节来开辟的,而位段 S 类型中第一个成员定义的大小为 3 bit, 在赋值时将 a 赋值为10,10的二进制序列为:01010 (后几位),受定义大小的限制,需舍弃一部分序列再存入内存中,所以最终存入内存中的序列为:010,且规定在分配的内存中是从后向前放入序列(如上图蓝色方框)。

2.当成员 a 放入内存中后,第一个字节还剩下5个bit位,而第二个成员占4个bit位,所以剩下的内存能够放下成员 b,放入方式同理,仍为从后向前放入(如上红色方框)。

3.当第一个字节放入成员 a 和 b 后,还剩下1个bit位,很显然不够第三个成员 c 放入,所以再次开辟1个字节的空间,然后再按照以上成员放入的方式依次放入,最终整个位段所占的内存就为3个字节大小。

结果如下:

int main()

{

 struct S s = {0};

 s.a:10;

 s.b:12;

 s.c:3;

 s.d:4;

 printf("%d\n",sizeof(s));//3

}

位段跨平台问题

int 位段被当成有符号数还是无符号数是不确定的。

位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:

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

*/

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
初识C语言随笔 2023-01-31 14:09:54