|
发表于 2025-6-2 10:09:00
|
显示全部楼层
C语言位域(位段)详解
位域用于节省内存空间,允许结构体成员按指定位数存储数据。
一、基本定义
定义语法:在结构体成员后加:位数
示例:
-
- struct bs {
- unsigned m; // 默认占4字节
- unsigned n: 4; // 占4位
- unsigned char ch: 6; // 占6位
- };
复制代码
二、取值范围与溢出
位域成员超出位数会被截断:
-
- #include <stdio.h>
- int main() {
- struct bs a = {0xad, 0xE, '$'};
- printf("%#x, %#x, %c\n", a.m, a.n, a.ch); // 输出:0xad, 0xe, $
-
- a.n = 0x2d; // 二进制[backcolor=#eee]101101[/backcolor](超4位) → 截断为[backcolor=#eee]1101[/backcolor](0xd)
- a.ch = 'z'; // 二进制[backcolor=#eee]1111010[/backcolor](超6位) → 截断为[backcolor=#eee]111010[/backcolor](字符':')
- printf("%#x, %#x, %c\n", a.m, a.n, a.ch); // 输出:0xb8901c, 0xd, :
- return 0;
- }
复制代码
三、位域宽度限制
位宽不能超过成员类型的长度:
- unsigned int类型 → 最大32位
- unsigned char类型 → 最大8位
四、可用数据类型
标准支持:
- int, signed int, unsigned int
- C99新增 _Bool
编译器扩展通常支持 char, enum 等。
五、存储规则
1. 相邻同类型成员压缩存储
-
- struct bs {
- unsigned m: 6;
- unsigned n: 12;
- unsigned p: 4; // 总22位 < 32位 → sizeof=4
- };
复制代码
2. 不同类型成员:编译器差异
GCC压缩存储,VC/VS不压缩:
-
- struct bs {
- unsigned m: 12;
- unsigned char ch: 4;
- unsigned p: 4;
- };
- // GCC输出 sizeof=4,VC/VS输出 sizeof=12
复制代码
3. 穿插非位域成员不压缩
-
- struct bs {
- unsigned m: 12;
- unsigned ch; // 非位域成员
- unsigned p: 4; // sizeof恒为12
- };
复制代码
六、位域地址限制
禁止用 & 获取位域成员地址(地址按字节编址)。
七、无名位域
用于占位或对齐,无名称不可访问:
-
- struct bs {
- int m: 12;
- int : 20; // 无名位域,占20位
- int n: 4; // 导致m和n分开存储
- }; // sizeof=8
复制代码
关键点总结:
- 位域节省空间但可能溢出
- 存储规则依赖编译器(尤其类型不同时)
- 无名位域用于内存对齐
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|