C语言位操作
2017年06月04日 16:51:00
阅读数:1553
此文将花费您8~15分钟时间,带您对嵌入式中常用的位操作有个了解。和数字电路有点相似!感谢阅读!
位操作符
1.位与&
1、注意:位与符号是一个&,两个&&是逻辑与。
2、真值表:1&0=01&1=10&0=00&1=0
3、从真值表可以看出:位与操作的特点是,只有1和1位与结果为1,其余全是0.
4、位与和逻辑与的区别:位与时两个操作数是按照二进制位彼次对应位相与的,逻辑与是两个操作数作为整体来相与的。(举例:0xAA&0xF0=0xA0,0xAA && 0xF0=1)
2.位或|
1、注意:位或符号是一个|,两个||是逻辑或。
2、真值表:1|0=11|1=10|0=00|1=1
3、从真值表可以看出:位或操作的特点是:只有2个0相位或才能得到0,只要有1个1结果就一定是1.
4、位或和逻辑或的区别:位或时两个操作数是按照二进制位彼次对应位相与的,逻辑或是两个操作数作为整体来相或的。
3.位取反~
1、注意:C语言中位取反是~,C语言中的逻辑取反是!
2、按位取反是将操作数的二进制位逐个按位取反(1变成0,0变成1);而逻辑取反是真(在C语言中只要不是0的任何数都是真)变成假(在C语言中只有0表示假)、假变成真。
实验:
include
include
include
include
include
define SET_NTH_BIT(x, n) (x | (1<<(n-1)))
define CLEAR_NTH_BIT(x, n) (x & ~(1<<(n-1)))
2.截取变量的部分连续位。例如:变量0x88, 也就是0b10001000,若截取第2~4位,则值为:0b100 = 4
define GETBITS(x, n, m) ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))
分析:这个题目相当于我们位运算实战演练1中5.做的事情,只不过要用宏来实现。
这个题目相当于是要把x的bit(n-1)到bit(m-1)取出来
注:优先级~ 高于 <<高于&
define GETBITS(x, n, m) ((x & (~(~(0U)<<(m-n+1))<<(n-1))) >> (n-1))
U表示unsigned int-32
复杂宏怎么分析:
((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))
第一步,先分清楚这个复杂宏分为几部分:2部分
@(x & ~(~(0U)<<(m-n+1))<<(n-1))
@>>(n-1)
分析为什么要>>(n-1),相当于是我们5.中的第二步(第二步,再将其右移3位得到结果。)
第二步,继续解析剩下的:又分为2部分
@x&
@~(~(0U)<<(m-n+1))<<(n-1)
分析为什么要&,相当于我们5中的第一步 (第一步:先将这个数bit3~bit8不变,其余位全部清零。)
第三步,继续分析剩下的:
~ (~(0U)<<(m-n+1))<<(n-1)
这个分析时要搞清楚第2坨到底应该先左边取反再右边<<;还是先右边<<再左边取反。
解法:第一,查C语言优先级表;第二,自己实际写个代码测试。
说明这个式子应该是 ~(~(0U)<<(m-n+1))<<(n-1) ,这就又分为2部分了
0x88:10001000
例如:变量0x88, 也就是0b10001000,若截取第2~4位,则值为:0b100 = 4
~(~(0U)<<(m-n+1))<<(n-1)):00001110
(x & ~(~(0U)<<(m-n+1))<<(n-1)):00001000
(x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1):00001000