C语言之位域

来源:互联网 发布:ios10越狱软件源 编辑:程序博客网 时间:2024/06/04 19:45

走读代码,再次加深自己对C语言位域理解。

typedef struct _STRUCT_INFO_TEST{uint8_t u8HeaderType : 2;uint8_t u8ServType : 2;uint8_t u8Priority : 3;uint8_t u8Extend : 1;uint8_t u8Rsv[3];uint32_t u8Len;}STRUCT_INFO_TEST;

定义的结构体如上,此处定义的u8Rsv数组,作用仅是位了内存按照4字节对齐。

1)一个位域必须存储在同一个字节,不能跨字节存储。

2)位域在内存中的位置是从低位向高位放的。

3)取地址符不能用在位域上。

直接上代码,简洁明了:

int main(){STRUCT_INFO_TEST infoTest;memset((void *)&infoTest, 0, sizeof(STRUCT_INFO_TEST));printf("sizeof(infoTest) = %d\n", sizeof(STRUCT_INFO_TEST)); //sizeof(infoTest) = 8infoTest.u8HeaderType = 3;infoTest.u8ServType = 2;infoTest.u8Priority = 6;infoTest.u8Extend = 1;infoTest.u8Len = 32;uint8_t *pu8Data = (uint8_t *)malloc(sizeof(STRUCT_INFO_TEST));memset(pu8Data, 0, sizeof(STRUCT_INFO_TEST));memcpy(pu8Data, &infoTest, sizeof(STRUCT_INFO_TEST));uint8_t u8HeaderType = *pu8Data  & 0x03;uint8_t u8ServType = (*pu8Data & 0xC) >> 2;uint8_t u8Priority = (*pu8Data & 0x70) >> 4;uint8_t u8Extend = *pu8Data >> 7;uint32_t u32Len = *(pu8Data + sizeof(uint32_t));printf("u8HeaderType u8ServType u8Priority u8Extend u32Len:\n");printf("%-12u %-10u %-10u %-8u %-6d\n", u8HeaderType, u8ServType, u8Priority, u8Extend, u32Len);return 0;}
在VS下,可以看到pu8Data在内存中的布局如下图所示:


即对应的二进制为:

1110 1011 -------->最后两位11对应u8HeaderType字段,中间10对应u8ServType字段,110对应u8Priority字段
0000 0000-------序:,首位1对应占1位的u8Extend字段
0000 0000
0000 0000

0010 0000
0000 0000
0000 0000
0000 0000

在取值时,最后连续几位,可以bit mask。比如对于u8HeaderType,可以直接&0x03。

要前面连续几位,可直接位移。例如对于u8Extend,可以直接右移7位。

要中间某几位,可以先bit mask再位移。例如对于u8Priority字段, (*pu8Data & 0x70) >> 4。

原创粉丝点击