学习目标:
- 运算符:~、&、|、^、 > &=、|=、^=、>>=、<<=
学习内容:
1.C按位运算符
- 二进制反码或按位取反:~
一元运算符~把1变为0,把0变为1。
~(10011010) // 表达式
(01100101) // 结果值
int a = 5;
int result = ~a;//结果为-6
- 按位与:&
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个 位,只有两个运算对象中相应的位都为1时,结果才为1(从真/假方面看, 只有当两个位都为真时,结果才为真)。
10010011
& 00111101 // 表达式
----------------
00010001 // 结果值
int a = 5;
int b = 3;
int result = a & b ;
- 按位或:|
二元运算符|,通过逐位比较两个运算对象,生成一个新值。对于每个 位,如果两个运算对象中相应的位为1,结果就为1(从真/假方面看,如果 两个运算对象中相应的一个位为真或两个位都为真,那么结果为真).
10010011
| 00111101 // 表达式
---------------------
10111111 // 结果值
int a = 5 ;
int b = 3 ;
int result = a | b ;
- 按位异或:^
二元运算符^逐位比较两个运算对象。对于每个位,如果两个运算对象 中相应的位一个为1(但不是两个为1),结果为1(从真/假方面看,如果两 个运算对象中相应的一个位为真且不是两个为同为1,那么结果为真)。
10010011
^ 00111101 // 表达式
--------------------------
10101110 // 结果值
int a = 5;
int b = 3;
int result = a ^ b ;
用法1:掩码表示
用&=运算符可以简化前面的代码,如下所示: flags &= MASK;
用法2:打开位或者设置位
有时,需要打开一个值中的特定位,同时保持其他位不变。这种情况可以使用按位或运算符(|)
用法3:关闭位或者清空位
需要在不影响其他位的情况下关闭指定的 位。
flags = flags & ~MASK;
计算(00001111) & ~(00000110)
~(10110110)为01001001
00001111
& 11111001
----------------
00001001 //结果值
2.移位运算符
- 左移:<<
左移运算符(<<)将其左侧运算对象每一位的值向左移动其右侧运算 对象指定的位数。左侧运算对象移出左末端位的值丢失,用0填充空出的位 置。
(10001010) << 2 // 表达式
(00101000) // 结果值
- 右移:>>
右移运算符(>>)将其左侧运算对象每一位的值向右移动其右侧运算 对象指定的位数。左侧运算对象移出右末端位的值丢。对于无符号类型,用 0 填充空出的位置;对于有符号类型,其结果取决于机器。空出的位置可用 0填充,或者用符号位(即,最左端的位)的副本填充
(10001010) >> 2 // 表达式,有符号值
(00100010) // 在某些系统中的结果值
(10001010) >> 2 // 表达式,有符号值
(11100010) // 在另一些系统上的结果值
移位运算符还可用于从较大单元中提取一些位。例如,假设用一个 unsigned long类型的值表示颜色值,低阶位字节储存红色的强度,下一个字 节储存绿色的强度,第 3 个字节储存蓝色的强度。随后你希望把每种颜色的 强度分别储存在3个不同的unsigned char类型的变量中。那么,可以使用下面 的语句:
#define BYTE_MASK 0xff
unsigned long color = 0x002a162f;
unsigned char blue, green, red;
red = color & BYTE_MASK;
green = (color >> 8) & BYTE_MASK;
blue = (color >> 16) & BYTE_MASK;
参考C primer plus