位域字段超过1的情况下的位域内存布局


void fnTestMultiBitsStruct()
{
    int iTmp = 0;
    typedef struct _tag_bits_struct
    {
        int bit_0_2 : 3;
        int bit_3_6 : 4;
        int bit_7_11 : 5;
    }TAG_BITS_STRUCT;

    TAG_BITS_STRUCT bitsStruct;

    /// 位域变量使用前, 要先清0. 防止人工分析错误
    ZeroMemory(&bitsStruct, sizeof(bitsStruct));
    bitsStruct.bit_0_2 = (1 & 0x7);
    bitsStruct.bit_3_6 = (3 & 0xf);
    bitsStruct.bit_7_11 = (7 & 0x1f);

    // 位域的内存布局
    // 低地址 => 高地址
    // 字节0, 字节1, 字节2, 字节3
    // 99 03 00 00
    // 10011001, 00000011, 00000000, 00000000
    // 001, 0011, 00111, 00000, 00000000, 00000000
    // 通过位域的测试, 发现了小端方式在字节内或双字节内存放数据时, 也是按照小端方式存放的.

    // bit_0_2 存放在字节0的bit5~bit7, 共3位
    // bit_3_6 存放在字节0的bit1~bit4, 共4位
    // bit_7_11 遇到了跨界的问题
    // bit_7_11 的bit0存放在字节0的bit7
    // bit_7_11 的bit1~4存放在字节1的bit4~bit7
    // 最终 bit_7_11 组合为 0011, 1 => 00111

    iTmp = bitsStruct.bit_0_2; ///< 1
    iTmp = bitsStruct.bit_3_6; ///< 3
    iTmp = bitsStruct.bit_7_11; ///< 7
}

为了防止人工数位域不好理解, 可以采用无名位域来占位的做法.

void fnTestMultiBitsStruct_noname()
{
    int iTmp = 0;
    typedef struct _tag_bits_struct
    {
        int bit_0_2 : 3;
        int bit_3_6 : 4;
        int : 1; ///< 为了防止人工取位域时数错, 在位域面临跨界时, 采用无名位域来填充跨界部分
        int bit_7_11 : 5;
    }TAG_BITS_STRUCT;
    
    TAG_BITS_STRUCT bitsStruct;
    
    /// 位域变量使用前, 要先清0. 防止人工分析错误
    ZeroMemory(&bitsStruct, sizeof(bitsStruct));
    bitsStruct.bit_0_2 = (1 & 0x7);
    bitsStruct.bit_3_6 = (3 & 0xf);
    bitsStruct.bit_7_11 = (7 & 0x1f);
    
    // 位域的内存布局
    // 低地址 => 高地址
    // 字节0, 字节1, 字节2, 字节3
    // 19 07 00 00
    // 00011001, 00000111, 00000000, 00000000
    // 0, 0011, 001, 000, 00111, 00000000, 00000000
    // 通过位域的测试, 发现了小端方式在字节内或双字节内存放数据时, 也是按照小端方式存放的.
    
    // bit_0_2 存放在字节0的bit5~bit7, 共3位
    // bit_3_6 存放在字节0的bit1~bit4, 共4位
    // 字节0的bit0用来占位, 防止bit_7_11跨界不好数
    // bit_7_11 的bit0~4存放在字节1的bit3~bit7, 共5位
    
    iTmp = bitsStruct.bit_0_2; ///< 1
    iTmp = bitsStruct.bit_3_6; ///< 3
    iTmp = bitsStruct.bit_7_11; ///< 7
}

如果某个位域变量不是第一个位域变量, 且位域长度 > 24 && <= 32, 可以采用0位域来规避跨界存放问题.

void fnTestMultiBitsStruct_0()
{
    // 0位域的应用场合
    int iTmp = 0;
    typedef struct _tag_bits_struct
    {
        int bit_0_2 : 3;
        int bit_3_6 : 4;

        /// 0位域, 如果一个位域长度 > 24 <= 32, 为了避免跨界问题, 采用0位域
        /// 使 bit_7_31 存到下一个int位置中, 避免跨界
        int : 0;
        int bit_7_31 : 25;
    }TAG_BITS_STRUCT;
    
    TAG_BITS_STRUCT bitsStruct;
    
    /// 位域变量使用前, 要先清0. 防止人工分析错误
    ZeroMemory(&bitsStruct, sizeof(bitsStruct)); ///< 00 00 00 00 00 00 00 00
    bitsStruct.bit_0_2 = (1 & 0x7);              ///< 01 00 00 00 00 00 00 00
    bitsStruct.bit_3_6 = (3 & 0xf);              ///< 19 00 00 00 00 00 00 00
    bitsStruct.bit_7_31 = (7 & 0x1f);            ///< 19 00 00 00 07 00 00 00
    
    // 位域的内存布局
    // 低地址 => 高地址
    // 字节0, 字节1, 字节2, 字节3, 字节4, 字节5, 字节6, 字节7
    // 19 00 00 00 07 00 00 00
    // 00011001, 00000000, 00000000, 00000000, 00000111, 00000000, 00000000, 00000000
    // 0, 0011, 001, 00000000, 00000000, 00000000, 00000111, 00000000, 00000000, 0, 0000000
    // 通过位域的测试, 发现了小端方式在字节内或双字节内存放数据时, 也是按照小端方式存放的.
    
    // bit_0_2 存放在字节0的bit5~bit7, 共3位
    // bit_3_6 存放在字节0的bit1~bit4, 共4位
    // 0位域占位, 防止bit_7_31跨界不好数, 从下一个int开始
    // bit_7_31 的bit0~24存放在字节4的bit7~bit31, 共25位
    
    iTmp = bitsStruct.bit_0_2; ///< 1
    iTmp = bitsStruct.bit_3_6; ///< 3
    iTmp = bitsStruct.bit_7_31; ///< 7
}


没有更多推荐了,返回首页