背景
在 C 语言中,位域的宽度指的是用于存储位域成员的二进制位数。它定义了一个位域成员所占用的位数,限制了该成员可以表示的取值范围。
定义方式
位域的宽度可以使用冒号 : 后面的数字来指定。这个数字表示了位域成员的位数,即所需的二进制位数。
小小代码
例如,
uint8_t command: 2;中的2表示command位域成员的宽度为 2 位,因此该成员只能存储 2 位二进制数。uint8_t checksum: 8;中的8表示checksum位域成员的宽度为 8 位,可以存储 8 位二进制数。
指定位域的好处
通过指定位域的宽度,我们可以有效地控制结构体成员所占用的内存空间,并限制它们可以表示的取值范围。这对于在嵌入式系统或需要节省内存的环境中非常有用。但需要注意的是,位域的宽度不能超过其所属数据类型的位数,否则行为将是未定义的。
我来研究一下
例子
按照位域宽度定义 DataPacket
typedef struct {
uint8_t header;
uint8_t command: 2;
uint8_t speed: 2;
uint8_t pressure: 2;
uint8_t alarm: 2;
uint8_t clear: 2;
uint8_t checksum: 8;
} DataPacket;
没有指定位域的宽度DataPacket2
typedef struct {
uint8_t header;
uint8_t command;
uint8_t speed;
uint8_t pressure;
uint8_t alarm;
uint8_t clear: 2;
uint8_t checksum;
} DataPacket2;
使用sizeof 比较大小
std::cout << "指定位域的宽度: DataPacket size is :" << sizeof(DataPacket) << std::endl;
std::cout << "没有指定位域的宽度DataPacket2 size is :" << sizeof(DataPacket2) << std::endl;
- 结果
指定位域的宽度: DataPacket size is :4
没有指定位域的宽度DataPacket2 size is :7
完整代码
typedef struct {
uint8_t header;
uint8_t command: 2;
uint8_t speed: 2;
uint8_t pressure: 2;
uint8_t alarm: 2;
uint8_t clear: 2;
uint8_t checksum: 8;
} DataPacket;
typedef struct {
uint8_t header;
uint8_t command;
uint8_t speed;
uint8_t pressure;
uint8_t alarm;
uint8_t clear: 2;
uint8_t checksum;
} DataPacket2;
uint8_t calculateChecksum(const DataPacket *packet) {
uint8_t checksum = packet->command + packet->speed + packet->pressure + packet->alarm + packet->clear;
return checksum;
}
/**
*
* @param packet
* @param command 命令
* @param speed
* @param pressure
* @param alarm
* @param clear
*/
void
packDataPacket(DataPacket *packet, uint8_t command, uint8_t speed, uint8_t pressure, uint8_t alarm, uint8_t clear) {
const uint8_t MASK = 0x03;
packet->header = 0xAA;
packet->command = command & MASK;
packet->speed = speed & MASK;
packet->pressure = pressure & MASK;
packet->alarm = alarm & MASK;
packet->clear = clear & MASK;
packet->checksum = calculateChecksum(packet);
}
int main() {
std::cout << "指定位域的宽度: DataPacket size is :" << sizeof(DataPacket) << std::endl;
std::cout << "没有指定位域的宽度DataPacket2 size is :" << sizeof(DataPacket2) << std::endl;
return 0;
}