比如我们把下面这个叫做位域,类型大小是3个字节
(struct _Record_Struct
{
unsigned char Env_Alarm_ID : 4;
unsigned char Para1 : 2;(前两个放在同一个字节)
unsigned char state;(没说明默认是8个比特位)
unsigned char avail : 1;(新开的这个比特位重新占据一个字节)
}*Env_Alarm_Record;
是一种减少内存存放的语法,比如下面这个需要8个字节
struct egg_hurt
{
int hur : 16;
char who : 2;
};
大小计算原理,内存一次开辟遇到的这个类型的字节,不管放什么类型(只能是整形和字符型)的数据,他的比特位可以自己设计
比如这个位域,第一次开辟4个字节,一个整形数据占用了2个字节,因为后面数据类型不同,剩下2个字节轮空。
之后的新开一个字节其中四个比特位连续放在剩下的两个字符数据。
最后使用了5个字节,但因为存在内存对齐,所以整体大小对齐到
计算规则:
一:下一个类型相同
先放一个数据,再看(为这个数据的开辟的剩下的空间)够不够放下一个数据,够就放,不够就再加4个字节,从新开的4字节起始开始放
二:下一个类型不同
备注:上一个数据开辟的空间所剩下的空间就不用了,直接重复1步骤
三:对齐
不同类型的数据要对齐:
对齐规则与结构体内存对齐规则基本一样
(1):第一个成员放在与偏移量(距离起始地址的字节距离,从0开始)为0的地址处,其他成员要对齐到某个数字(对齐数)的整数倍偏移量处
(2):对其数 == 编译器默认对齐数与该成员的类型大小值(eg:int对齐数为4) 的较小值
(vs2019默认对齐数为8)
(3):总大小为最大对齐数的整数倍
(4):套娃情况下,被嵌套的结构体对齐到自己最大对齐数。整体套娃结构的大小是所有最大对齐数的整数倍
备注内存比特位使用是从右向左如图
00 00 00 00
00 00 00 01
00 00 01 01
...
这样用
如题
int main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0 : 1;
unsigned char ucData1 : 2;
unsigned char ucData2 : 3;
}*pstPimData;
pstPimData = (struct tagPIM*)puc;
memset(puc, 0, 4);
pstPimData->ucPim1 = 2;
pstPimData->ucData0 = 3;
pstPimData->ucData1 = 4;
pstPimData->ucData2 = 5;
printf("%02x %02x %02x %02x\n", puc[0], puc[1], puc[2], puc[3]);
return 0;
}
答案是 02 29 00 00
他是这么用的
先一个字节使用为2
然后第二个字节的
第一个比特位得1:
3 是11
取一位得1
之后是
4是 100
取两位得
00
5是101
取3位得
101
如下图
00 00 00 01
00 00 00 01
00 10 10 01
所以第二个字节是29
后面的字节没用初始为0
综上 02 29 00 00