位操作符使用整型的操作数.位操作符将其整型操作数视为二进制位的集合,为每一位提供检验和设置的功能.另外,这类操作符还可用于bitset类型的操作数,该类型具有这里所描述的整型操作数的行为.
~ 位求反 ~expr
<< 左移 expr1 << expr2
>> 右移 expr1 >> expr2
& 位与 expr1 & expr2
^ 位异或 expr1 ^ expr2
| 位或 expr1 | expr2
位操作符操纵的整数的类型可以是有符号的也可以是无符号的.如果操作数为负数,则位操作符如何处理其操作数的符号依赖于机器.于是它们的应用可能不同:在一个应用环境中实现的程序可能无法用于另一应用环境.
-------------------------------------------------------我是华丽的分割线-------------------------------------------------------
实践告诉你:对于位操作符,由于系统不能确保如何处理其操作数的符号位,所以强烈建议用unsigned整型操作数.
-----------------------------------------------------我是华丽无比的分割线----------------------------------------------------
在下面的例子中,假设unsigned char类型有8位.
位求反操作符(~)的功能类似于bitset的flip操作:将操作数的每一个二进制位取反:将1设置为0、0设置为1,生成一个新值:
unsigned char bits=0227; //10010111
bits=~bits; //01101000
>>和<<操作符提供移位操作,其右操作数标志要移动的位数.这两种操作符将其左操作数的各个位向左(<<)或向右(>>)移动若干个位(移动的位数由其右操作数指定),从而产生新的值,并丢弃移出去的位.
unsigned char bits=1; //10011011
bits<<1; //left shift 00110110
bits<<2; //left shift 01101100
bits>>3; //right shift 00010011
左移操作符(<<)在右边插入0以补充空位.对于右移操作符(>>),如果其操作数是无符号数,则从左边开始插入0;如果操作数是有符号数,则插入符号位的副本或者0值,如何选择需依据具体的实现而定.移位操作的右操作数不可以是负数,而且必须是严格小于左操作数位数的值.否则,操作的效果未定义.
位与操作(&)需要两个整型操作数,在每个位的位置,如果两个操作数对应的位都为1,则操作结果中该位为1,否则为0.
------------------------------------------------------我是等待的分割线------------------------------------------------
小心:常犯的错误是把位与操作(&)和逻辑与操作(&&)混淆了.同样地,位或操作(|)和逻辑或操作(||)也很容易搞混
-----------------------------------------------------我是望穿秋水的分割线--------------------------------------------
下面我们来说明两个unsigned char类型值的位与操作,这两个操作数均用八进制字面常量初始化:
unsigned char b1=0145; //01100101
unsigned char b2=0257; //10101111
unsigned char result=b1 & b2; //00100101
result-b1^b2; //11001010
result-b1|b2; //11101111
位异或(互斥或,exclusive or)操作符(^)也需要两个整型操作数.在每个位的位置,如果两个操作数对应的位只有一个(不是两个)为1,则操作结果中该位为1,否则为0.
位或(包含或,inclusive or)操作符(|)需要两个整型操作数.在每个位的位置,如果两个操作数对应的位有一个或者两个都为1,则操作结果中该位为1,否则为0.