位操作
基础概念
位与&、位或|、位取反~、位异或^ (位操作都是按位操作的)
逻辑与&&、逻辑或||、逻辑取反! (逻辑操作是整体操作的)
左移位<< 、右移位>>
C语言的移位要取决于数据类型。
对于无符号数,左移时右侧补0, 右移时左侧补0
对于有符号数,左移时右侧补0,右移时左侧补符号位。
为什么要学习位运算?
在嵌入式中我们常常要操作寄存器即改变特定的位的状态来控制外设。
譬如:a的初始值为0x00001000;我们要将它的bit2置1。
第一种方法:直接把数写进去。 实现方法:把0x00001100直接写进去
第二种方法:运用位操作的方式。 实现方法:a = a | (1<<2);
当我们不知道初始值时,第一种方法就不能直观的从代码获悉改动了哪些位、怎么改的,所以我们倾向于第二种方法。
位运算详解?
特定位清0用&、特定位置1用|、特定位取反用^。 譬如说:a = a & (0x11<<3) b = b|(0x1<<6)
通过移位取反的方式构建特定的二进制数。 譬如说:0x00101001<==>(0x1<<0)|(0x1<<3)|(0x1<<5)
为什么要使用宏来实现位运算?
有时候我们常常需要反复用到第N位清0或者置1等操作。那么使用宏定义来帮助我们完成就显得很有必要了。
举例子:第N位置一:#define SET_NTH_BIT(x, n) (x | ((1U)<<(n-1)))
第N位清零:#define CLEAR_NTH_BIT(x, n) (x & ~((1U)<<(n-1)))
截取变量的n~m位:#define GETBITS(x, n, m) ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))
(本文参考了朱有鹏C语言高级专题)