【C++】位域
位域
基础语法:
struct 结构体名 {
数据类型 成员名 : 位数;
数据类型 成员名 : 位数;
};
示例:
#include <iostream>
struct Flags {
unsigned int a : 1; // 占1位
unsigned int b : 2; // 占2位
unsigned int c : 5; // 占5位
};
int main() {
Flags f = {1, 3, 17};
std::cout << f.a << " " << f.b << " " << f.c << std::endl; // 输出:1 3 17
return 0;
}
注意:
- b 占 2 位,只能表示 0~3;
- 如果你赋值超出了可表示的范围,会出现未定义行为。
例子1
#include <stdio.h>
// 1. 基本位域结构
struct BasicBitField {
unsigned int flag1 : 1; // 占用1位,值为0或1
unsigned int flag2 : 1; // 占用1位
unsigned int value : 4; // 占用4位,值范围0-15
unsigned int reserved : 2; // 占用2位,保留字段
};
// 2. 寄存器映射示例
struct Register {
unsigned int enable : 1; // 使能位
unsigned int mode : 2; // 模式选择(0-3)
unsigned int priority : 3; // 优先级(0-7)
unsigned int reserved1 : 2; // 保留位
unsigned int status : 8; // 状态字段
unsigned int reserved2 : 16; // 剩余保留位
};
// 3. 网络协议头部示例
struct IPHeader {
unsigned int version : 4; // IP版本
unsigned int header_length : 4; // 头部长度
unsigned int type_of_service : 8; // 服务类型
unsigned int total_length : 16; // 总长度
unsigned int identification : 16; // 标识
unsigned int flags : 3; // 标志位
unsigned int fragment_offset : 13; // 片偏移
};
// 4. 日期时间压缩存储
struct CompactDateTime {
unsigned int second : 6; // 秒 (0-59)
unsigned int minute : 6; // 分 (0-59)
unsigned int hour : 5; // 时 (0-23)
unsigned int day : 5; // 日 (1-31)
unsigned int month : 4; // 月 (1-12)
unsigned int year : 6; // 年 (相对于某基准年)
};
// 5. 状态标志集合
struct StatusFlags {
unsigned int is_ready : 1;
unsigned int is_busy : 1;
unsigned int has_error : 1;
unsigned int is_connected : 1;
unsigned int debug_mode : 1;
unsigned int test_mode : 1;
unsigned int : 2; // 未命名位域,用于对齐
};
// 6. 混合数据类型位域
struct MixedBitField {
signed int temperature : 12; // 有符号温度值 (-2048 到 2047)
unsigned int humidity : 8; // 无符号湿度值 (0-255)
unsigned int sensor_id : 4; // 传感器ID (0-15)
unsigned int battery_level : 8; // 电池电量 (0-255)
};
int main() {
// 基本使用
struct BasicBitField bf = {0};
bf.flag1 = 1;
bf.flag2 = 0;
bf.value = 12; // 最大15
printf("基本位域示例:\n");
printf("flag1: %u, flag2: %u, value: %u\n",
bf.flag1, bf.flag2, bf.value);
printf("结构体大小: %lu 字节\n\n", sizeof(bf));
// 寄存器操作示例
struct Register reg = {0};
reg.enable = 1;
reg.mode = 2;
reg.priority = 5;
reg.status = 0xFF;
printf("寄存器操作示例:\n");
printf("enable: %u, mode: %u, priority: %u, status: 0x%02X\n",
reg.enable, reg.mode, reg.priority, reg.status);
printf("寄存器大小: %lu 字节\n\n", sizeof(reg));
// 压缩日期时间
struct CompactDateTime dt = {0};
dt.year = 24; // 2024年(假设基准年为2000)
dt.month = 12;
dt.day = 25;
dt.hour = 15;
dt.minute = 30;
dt.second = 45;
printf("压缩日期时间:\n");
printf("日期: 20%02u-%02u-%02u %02u:%02u:%02u\n",
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
printf("日期时间结构大小: %lu 字节\n\n", sizeof(dt));
// 状态标志
struct StatusFlags flags = {0};
flags.is_ready = 1;
flags.is_connected = 1;
flags.debug_mode = 0;
printf("状态标志:\n");
printf("ready: %u, busy: %u, error: %u, connected: %u\n",
flags.is_ready, flags.is_busy, flags.has_error, flags.is_connected);
printf("标志结构大小: %lu 字节\n\n", sizeof(flags));
// 混合数据类型
struct MixedBitField sensor = {0};
sensor.temperature = -50; // 负温度
sensor.humidity = 65;
sensor.sensor_id = 3;
sensor.battery_level = 85;
printf("传感器数据:\n");
printf("温度: %d, 湿度: %u%%, 传感器ID: %u, 电池: %u%%\n",
sensor.temperature, sensor.humidity,
sensor.sensor_id, sensor.battery_level);
printf("传感器数据大小: %lu 字节\n\n", sizeof(sensor));
// 位域的内存布局(平台相关)
printf("内存地址信息:\n");
printf("bf地址: %p\n", (void*)&bf);
printf("reg地址: %p\n", (void*)®);
// 演示位域溢出
printf("位域溢出示例:\n");
bf.value = 20; // 超过4位能表示的最大值15
printf("设置value=20后,实际值: %u (被截断为: %u)\n",
20, bf.value);
return 0;
}
/*
输出说明:
1. 位域会自动进行位打包,节省内存空间
2. 超出位数范围的值会被自动截断
3. 实际内存布局依赖于编译器和平台
4. 位域主要用于底层编程、寄存器操作、协议解析等场景
*/

浙公网安备 33010602011771号