C语言之位域

走读代码,再次加深自己对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) = 8
	infoTest.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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值