可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。在以下例子中,我们将使用二进制计数法写出值,以便您可以了解对位发生的操作。
5.1位逻辑运算符
4个位运算符用于整型数据,包括char。将这些位运算符称为位运算的原因是它们对每位进行操作,而不影响左右两侧的位。请不要将这些运算符与常规的逻辑运算符(&& 、||和!)相混淆,常规的位的逻辑运算符对整个值进行操作。
5.1.1按位取反 ~一元运算符~将每个1变为0,将每个0变为1,如下面的例子:
5.1.2 按位与 &~(10011010)
01100101
二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都是1时结果才为1。
(10010011)
& (00111101)
= (00010001)
C也有一个组合的位与-赋值运算符:&=。下面两个将产生相同的结果:
val &= 0377
val = val & 0377
5.1.3 按位或 |
二进制运算符|通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为1,那么结果位就为1.
5.1.4 按位异或 ^(10010011)
| (00111101)
= (10111111)
二进制运算符^对两个操作数逐位进行比较。对于每个位,如果操作数中的对应位不同,那么结果是1.如果都是0或者都是1,则结果位0.
5.1.5用法(10010011)
^ (00111101)
= (10101110)
5.1.5.1 打开位
- 将位2打开
(10011010)
| (00000100)
=(10011110)
2.将所有位打开
(10011010)
| (01100101)
=(11111111)
5.1.5.2 关闭位
(10011010)
&(01100101)
= (00000000)
5.1.5.3 转置位
转置一个位表示如果该位打开,则关闭该位;如果该位关闭,则打开。
(10010011)
^(11111111)
=(01101100)
5.1.5.4 交换两个数不需要临时变量
a ^ b = temp;
a ^ temp = b;
b ^ temp = a
5.2 移位运算符
现在让我们了解一下C的移位运算符。移位运算符将位向左或向右移动。同样,我们仍将明确地使用二进制形式来说明该机制的工作原理。
5.2.1 左移 <<
左移运算符<<将其值的每位向左移动。空出来的位用0填充,并且丢弃移出末端的位。
(10001010) << 2
(00101000)
左移一位相当于原值*2.
1 << 1 = 2;
2 << 1 = 4;
4 << 1 = 8;
8 << 2 = 32
5.2.2 右移 >>
右移运算符>>将其值每位向右移动。并且丢弃移出末端的位。对于unsigned类型,使用0填充左端空出的位。对于有符号类型,结果依赖于机器。空出的位可能用0填充,或者使用符号(最左端)位的副本填充。
//有符号值
(10001010) >> 2
(00100010) //在某些系统上的结果值
(10001010) >> 2
(11100010) //在另一些系统上的结果
//无符号值
(10001010) >> 2
(00100010) //所有系统上的结果值
5.2.3 用法:移位运算符
移位运算符能够提供快捷、高效(依赖于硬件)对2的幂的乘法和除法。
| number << n | number乘以2的n次幂 |
| number >> n | 如果number非负,则用number除以2的n次幂 |



