C语言位域(位段)详解
时间:2021-01-19 23:40:52
手机看文章
扫描二维码
随时随地手机看文章
[导读]有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。
位域是什么?
1struct bs{ 2 unsigned m; 3 unsigned n: 4; 4 unsigned char ch: 6; 5};
1#include 2int main(){ 3 struct bs{ 4 unsigned m; 5 unsigned n: 4; 6 unsigned char ch: 6; 7 } a = { 0xad, 0xE, '$'}; 8 //第一次输出 9 printf("%#x, %#x, %c\n", a.m, a.n, a.ch); 10 //更改值后再次输出 11 a.m = 0xb8901c; 12 a.n = 0x2d; 13 a.ch = 'z'; 14 printf("%#x, %#x, %c\n", a.m, a.n, a.ch); 15 system("pause"); 16 return 0; 17}
C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度。
C语言标准还规定,只有有限的几种数据类型可以用于位域。在 ANSI C 中,这几种数据类型是 int、signed int 和 unsigned int(int 默认就是 signed int);到了 C99,_Bool 也被支持了。
位域的存储
- 当相邻成员的类型相同时,如果它们的位宽之和小于类型的 sizeof 大小,那么后面的成员紧邻前一个成员存储,直到不能容纳为止;如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍。
1#include 2int main(){ 3 struct bs{ 4 unsigned m: 6; 5 unsigned n: 12; 6 unsigned p: 4; 7 }; 8 printf("%d\n", sizeof(struct bs)); 9 return 0; 10}
- 当相邻成员的类型不同时,不同的编译器有不同的实现方案,GCC 会压缩存储,而 VC/VS 不会。
1#include 2int main(){ 3 struct bs{ 4 unsigned m: 12; 5 unsigned char ch: 4; 6 unsigned p: 4; 7 }; 8 printf("%d\n", sizeof(struct bs)); 9 return 0; 10}
- 如果成员之间穿插着非位域成员,那么不会进行压缩。例如对于下面的 bs:
1struct bs{ 2 unsigned m: 12; 3 unsigned ch; 4 unsigned p: 4; 5};
无名位域
1struct bs{ 2 int m: 12; 3 int : 20; //该位域成员不能使用 4 int n: 4; 5};
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!





