位域的规则
- 位数限制:每个位域字段的位数不能超过其基本数据类型所能表示的位数。例如,
unsigned int
通常是 32 位,因此不能定义一个超过 32 位的位域字段。 - 默认类型:位域通常使用整数类型(
int
或unsigned int
),但可以使用其他整型类型,如char
或short
,不过要注意,位域的大小要适应目标类型的大小。 - 顺序问题:位域的排列顺序通常依赖于机器的字节顺序(即大端或小端),这可能会影响跨平台的可移植性。
- 填充:如果位域字段之间的空隙较大,编译器可能会在结构体内填充一些额外的空位来对齐内存,从而影响结构体的大小。
- 结构体内存对齐:位域字段会影响结构体的内存对齐。例如,定义两个字段占用 3 位和 5 位,可能会在它们之间填充额外的位来保证字节对齐。
联合体
通过联合体将位域结构体和其他变量配合,这样可以方便地通过位域访问按位分配的标志位,同时也可以通过u16类型变量来访问完整的 16 位数据。
//错误案例
typedef union{
struct{
u8 ConvReady: 1;
u8 InWorkArea: 1;
u8 Parallel: 1;
u8 GenSw1On: 1;
u8 GenSw2On: 1;
u8 TorqueReduction: 1;
u8 EmergencyOFF: 1;
u8 res: 3;
u8 Msc120K: 1;
u8 Msc340K: 1;
u8 GeneratorON: 1;
u8 MotorMode: 1;
u8 ControlMode: 1;
u8 ToggleBit: 1;
}st;
u16 u;
}GenSta;
//正常案例
typedef union{
struct{
u8 ConvReady: 1;
u8 InWorkArea: 1;
u8 Parallel: 1;
u8 GenSw1On: 1;
u8 GenSw2On: 1;
u8 TorqueReduction: 1;
u8 EmergencyOFF: 1;
u8 res: 1;
u8 res1: 2;
u8 Msc120K: 1;
u8 Msc340K: 1;
u8 GeneratorON: 1;
u8 MotorMode: 1;
u8 ControlMode: 1;
u8 ToggleBit: 1;
}st;
u16 u;
}GenSta;
//结果正确的案例
typedef union{
struct{
u8 ConvReady: 1;
u8 InWorkArea: 1;
u8 Parallel: 1;
u8 GenSw1On: 1;
u8 GenSw2On: 1;
u8 TorqueReduction: 1;
u8 EmergencyOFF: 1;
u8 res: 1;
u8 res1: 1;
u8 res2: 1;
u8 Msc120K: 1;
u8 Msc340K: 1;
u8 GeneratorON: 1;
u8 MotorMode: 1;
u8 ControlMode: 1;
u8 ToggleBit: 1;
}st;
u16 u;
}GenSta;
//结果正确的案例
typedef union{
struct{
u16 ConvReady: 1;
u16 InWorkArea: 1;
u16 Parallel: 1;
u16 GenSw10n: 1;
u16 GenSw20n: 1;
u16 TorqueReduction: 1;
u16 EmergencyOFF: 1;
u16 res: 3;
u16 Msc120K: 1;
u16 Msc340K: 1;
u16 GeneratorON: 1;
u16 MotorMode: 1;
u16 ControlMode: 1;
u16 ToggleBit: 1;
}st;
u16 u;
}GenSta;
好复杂,看不懂。