不常见的小知识点-位段
【摘要】 位段 什么是位段位段的声明和结构是类似的,但是有两点不相同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呢?
我们要知道位段的内存分配!
位段的内存分配
- 1.位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
-
- 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
-
- 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
int类型一次开辟4个字节,不够保存下一个成员则再开4个字节,char类型一次开辟1个字节,不够保存下一个成员则再开辟1个字节
所以上述:
struct A
{
int a:2;
int b:5;
int c:10;
int d:30;
};
举例子:
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;
}
//空间是如何开辟的?
假设从左到右使用空间,剩下的空间不够保存下一个成员,则再开辟下一个空间
此时对应的16进制位:620304
验证:
初始化:
s只占3个字节
赋值后:
对应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,错误
- 位段中的成员在内存中从左向右分配还是从右向左分配尚未定义
- 当一个结构包含两个位段,第二个位段成员所占位比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,是不确定的
总结:
跟结构体相比,位段同样达到同样的效果,但是可以很好的节省空间,但是又跨平台问题
位段的应用
枚举比结构体更节省空间
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)