C语言移位操作、联合体总结

(1)用|置1,例如P1_flag |= 0x01;//置1 0000 0001,把bit0置1;
(2)用&置0,例如P1_flag &= 0xFE;//置0 1111 1110,把bit0置0;
(3)把一个字节对应位数据提取出来,例如light_control[0][0] = (data & 0x08)>>3;//把data指向的一字节数据保留bit3,右移3位,赋值给light_control[0][0]
(4)把一个字节对应位数据提取出来,保留赋值目标的其他位,修改对应位,例如P2_flag = P2_flag |(CANRxBuf.Data[5] & 0x04)<<1;//这种方式能置1,但是不能置0;被赋值数据一开始应该置0;
改进后:先提取对应bit判断,再手动给要赋值的bit置1或者置0;

if((CANRxBuf.Data[6] & 0x04)>>2)
{
	P1_flag |= 0x20;//手动置1 0010 0000
}
else 
	P1_flag &= 0xDF;//手动置0 1101 1111

(5)两个8位数赋值到16位数;
ret = (high<<8)| low;

16位数拆分为两个8位数;
high = (ret>>8)&0xFF;
low = ret&0xFF;

(6)两个8位数组合后进行大小比较
if(((Set_H<<8)|Set_L) >= ((High<<8)|Low))

(7)两个8位数组合后进行大小比较,同时最高一位作为标志位
DataH = ((((Set_H<<8)|Set_L) - ((High<<8)|Low)) >> 8) | 0x80; //最高位置1
或者
DataH = (((Set_H<<8)|Set_L) - ((High<<8)|Low)) | 0x8000;

DataH = ((((Set_H<<8)|Set_L) - ((High<<8)|Low)) >> 8) & 0x7F; //最高位置0
或者
DataH = (((Set_H<<8)|Set_L) - ((High<<8)|Low)) | 0x7FFF;

(8)位域与联合体
位域:是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
联合体:在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体。
联合体位域结合起来定义数据类型:

typedef union
{
	u8 value;	
	//位域定义部分 
	struct  
	{
		u8  lowbit:2;
		u8  middlebit:3;
		u8  highbit:3;
	}byte;
}test_data;

说明:
1、value和byte共用一个字节的内存空间;
2、改变value的值,那么byte的值随着改变,同样改变byte中的位(lowbit占两位, middlebit占3位,highbit也占3位;)value的值也改变;
3、联合体这个原理,在某些场合可以替代位操作

下面以多个字节的联合体为例:

typedef union
{
	u8 value[2];	
	//位域定义部分 
	struct  
	{
		u8 lowbit:2;
		u8 middlebit:3;
		u8 highbit:3;
		u8 b1:3;
		u8 b2:3;
		u8 b3:2;
	}byte;
}test_data;

test_data test_data_main;

test_data_main.byte.lowbit=3;
test_data_main.byte.middlebit=3;
test_data_main.byte.highbit=3;
test_data_main.byte.b1 = 4;
test_data_main.byte.b2 = 4;
test_data_main.byte.b3 = 0;
SEGGER_RTT_printf(0,"lowbit = %d\r\n",test_data_main.byte.lowbit);				
SEGGER_RTT_printf(0,"middlebit = %d\r\n",test_data_main.byte.middlebit);		
SEGGER_RTT_printf(0,"highbit = %d\r\n",test_data_main.byte.highbit);		
SEGGER_RTT_printf(0,"b1 = %d\r\n",test_data_main.byte.b1);		
SEGGER_RTT_printf(0,"b2 = %d\r\n",test_data_main.byte.b2);		
SEGGER_RTT_printf(0,"b3 = %d\r\n",test_data_main.byte.b3);	
SEGGER_RTT_printf(0,"value[0] = 0x%x\r\n",test_data_main.value[0]);		
SEGGER_RTT_printf(0,"value[1] = 0x%x\r\n",test_data_main.value[1]);			

程序运行结果:
在这里插入图片描述
从中也可以看出,是低位对齐。

//20190616 更新//
位域操作问题:一般不能夸字节填充数据,需要按照组合起来8bit一个字节形式填充数据。

发布了97 篇原创文章 · 获赞 135 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/weixin_37787043/article/details/87780665