不常见的小知识点-位段

举报
芒果_Mango 发表于 2022/03/28 10:22:09 2022/03/28
【摘要】 位段 什么是位段位段的声明和结构是类似的,但是有两点不相同1.位段的成员必须是int unsigned int(size_t),signed int,char (即为整形家族的类型)2. 位段的成员名后面有一个冒号和一个数字(表示占多少比特位)如:struct A{ int a:2; int b:5; int c:10; int d:30;};//此时A就是一个位段...

位段

什么是位段

位段的声明和结构是类似的,但是有两点不相同

  • 1.位段的成员必须是int unsigned int(size_t),signed int,char (即为整形家族的类型)

  • 2. 位段的成员名后面有一个冒号和一个数字(表示占多少比特位)


如:

struct A
{
    int a:2;
    int b:5;
    int c:10;
    int d:30;
};
//此时A就是一个位段类型
int main()
{
    printf("%d\n",sizeof(struct A));//8
}

为什么位段类型A的大小为8?

位段的位:二进制位

2+5+10+30 = 47bit ->6byte即可保存,为什么要8byte呢?

我们要知道位段的内存分配!

image-20220310222700851


位段的内存分配

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

int类型一次开辟4个字节,不够保存下一个成员则再开4个字节,char类型一次开辟1个字节,不够保存下一个成员则再开辟1个字节


所以上述:

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

image-20220310222712863


举例子:

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;
}
//空间是如何开辟的?

假设从左到右使用空间,剩下的空间不够保存下一个成员,则再开辟下一个空间

image-20220310222726579


image-20220310222801430


此时对应的16进制位:620304

image-20220310222811675

验证:

初始化:

image-20220310222838076

s只占3个字节

赋值后:

image-20220310222847721

对应16进制结果确实为 :620304


VS下位段内存空间存放规则:

  • 从右边向左边使用空间,但如果左边空间不够保存下一个成员,则再开辟下一个空间,原来的空间浪费掉

位段不可以使用offsetof()计算位段成员与起始位置的偏移量

位段的跨平台性

  • 1.int位段被当成有符号数还是无符号数是不确定的
  • 2.位段中最大位的数目不能确定(16位机器最大16,2位机器最大32)
struct A
{
  int a :2;
  int b:5;
  int c :30; 	//err
};
//16位机器, int占2个字节-16位  
//c要占位30 > 16,错误
  • 位段中的成员在内存中从左向右分配还是从右向左分配尚未定义
  • 当一个结构包含两个位段,第二个位段成员所占位比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,是不确定的

总结:

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


位段的应用

image-20220310222923493

枚举比结构体更节省空间


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。