C++ 位域
C++ 位域
C++位域(Bit Field)是一种允许在结构体(struct
)或联合体(union
)中以位为单位分配存储空间的特性,用来节省内存或实现与硬件寄存器的精准映射
基本语法
1
2
3
4
5
strcut Example {
unsigned int a : 3; // a占3位
unsigned int b : 5; // b占5位
unsigned int c : 8; // c占8位
}
在这里,a
占3位,b
占5位,c
占8位
所有成员依然是
unsigned int
类型,只是存储时按照指定的位数压缩
使用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
struct Flags {
unsigned int isVisible : 1;
unsigned int isEnabled : 1;
unsigned int hasFocus : 1;
unsigned int reserved : 5; // 用于对齐或保留
};
int main() {
Flags f = {1, 0, 1, 0};
cout << "Visible: " << f.isVisible << endl;
cout << "Enabled: " << f.isEnabled << endl;
cout << "HasFocus: " << f.hasFocus << endl;
cout << "sizeof f: " << sizeof(f) << endl;
cout << "sizeof Flags: " << sizeof(Flags) << endl;
return 0;
}
输出:
1
2
3
4
5
Visible: 1
Enabled: 0
HasFocus: 1
sizeof f: 4
sizeof Flags: 4
在这个程序中,结构体总共占了8位数,即1个字节,但是unsigned int
的大小为4,所以sizeof(Flags)
的输出结果通常是4
未命名位域与零宽度位域
未命名位域(Unnamed Bit-fields)
1 2
// type : width; int : 8;
这会产生一个指定宽度的匿名位域,主要用于填充,即跳过指定的位数
这些位无法被直接访问
零宽度未命名位域(Zero-width Unnamed Bit-field)
1 2
// type : 0; int : 0;
这是一个特殊命令,它会强制下一个位域成员从下一个基础类型的边界开始对齐
1
2
3
4
5
6
7
struct LayoutControl {
unsigned char a : 3;
unsigned char : 2; // 跳过 2 位
unsigned char b : 3;
unsigned int : 0; // 强制下一个成员在新的 unsigned int 边界开始
unsigned int c : 5;
};
特点
特性 | 说明 | |
---|---|---|
类型 | 位域必须是整型或枚举类型(如 int , unsigned int , signed int )。 | |
宽度 | 宽度由冒号后的常量表达式指定(例如 : 3 )。 | |
取值范围 | 对于 n 位的无符号位域,可表示 0 ~ 2^n - 1 ;有符号则是 -(2^(n-1)) ~ 2^(n-1)-1 。 | |
内存对齐 | 位域通常打包在同一个 int 内存单元中,但实现依赖于编译器。 | |
不可取地址或引用 | 位域成员 不能取地址,例如:&f.isVisible ❌。 | |
不能创建数组 | 不能声明位域数组 | |
不能是static | 位域不能声明为静态成员 | |
跨单元禁止共享 | 如果剩余位不足以容纳下一个位域,编译器会从下一个整型单元开始存放。 |
常见用途
应用场景 | 示例 |
---|---|
节省内存 | 嵌入式系统或通信协议中保存大量布尔标志位。 |
硬件寄存器映射 | 与硬件设备寄存器的一位一位对应。 |
网络协议头 | 如 TCP/IP 报文头结构的位级定义。 |
本文由作者按照 CC BY 4.0 进行授权