2.9 按位运算符
C 语言提供了 6 个位操作运算符,这些运算符只能作用于整型操作数
即只能作用于带符号或无符号 char
、short
、int
、long
类型:
运算符 | 描述 |
---|---|
& | 按位与(AND) |
| | 按位或(OR) |
^ | 按位异或(XOR) |
<< | 左移 |
>> | 右移 |
~ | 按位求反(一元运算符) |
按位与运算符 &
经常用于屏蔽某些二进制位(与 1
按位与,值不变)
如 n = n & 0177
,该语句将 n
中除 7 个低位外的其它各位均置为 0
按位或运算符 |
常用于将某些二进制位置为 1
(与 0
按位或,值不变)
如 x = x | SET_ON
,该语句将 x
中对应于 SET_ON
中为 1
的那些二进制位置为 1
按位异或运算符 ^
当两个操作数的对应位不相同时将该位设置为 1
,否则,将该位设置为 0
我们必须将位运算符 &
、|
同逻辑运算符 &&
、||
区分开来,后者用于从左至右求表达式的真值
例如,如果 x
的值为 1
,Y
的值为 2
,那么,x & y
的结果为 0
,而 x && y
的值为 1
移位运算符 <<
与 >>
分别用于将运算的左操作数左移与右移,移动的位数则由右操作数指定(右操作数的值必须是非负值)
因此,表达式 x << 2
将把 x
的值左移 2 位,右边空出的 2 位用 0
填补,该表达式等价于对左操作数乘以 4
在对 unsigned
类型的无符号值进行右移位时,左边空出的部分将用 0
填补
当对 signed
类型的带符号值进行右移时,某些机器将对左边空出的部分用符号位填补(即 “ 算术移位 ”)
而另一些机器则对左边空出的部分用 0
填补(即 “ 逻辑移位 ”)
一元运算符 ~
用于求整数的二进制反码,即分别将操作数各二进制位上的 1
变为 0
,0
变 为 1
例如:x = x & ~077
将把 x
的最后 6 位设置为 0
注意,表达式 x & ~077
与机器字长无关,它比形式为 x & 0177700
的表达式要好,后者假定 x
是 16 位的
这种可移植的形式并没有增加额外开销,因为 ~077
是常量表达式,可以在编译时求值
为了进一步说明某些位运算符,我们来看函数 getbits(x, p, n)
,它返回 x
中从右边数第 p
位开始向右数 n
位的字段
这里假定最右边的一位是第 0
位,n
与 p
都是合理的正值
例如,getbits(x, 4, 3)
返回 x
中第 4
、3
、2
三位的值
/* getbits: get n bits from position p */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p + 1 - n)) & ~(~0 << n);
}