关于位域的大小计算与对齐规则

比如我们把下面这个叫做位域,类型大小是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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值