概述
C/C++里面位操作符表示为如下:左移位 << ,右移位 >>,位与 &,位或 | ,位异或 ^,按位求反~。
位操作符针对的是补码形式(可参见下面的例子,其实我们给出的字面值常量和以16进制输出均是补码形式),这点必须要清楚。
还有就是位操作符的优先级:按位求反 >移位 > 位与 > 位异或 > 位或 优先级,按位求反具有右即合性,其他均具有左结合性,这点在C++里面需要注意,因为输入输出经常用到移位操作符,注意加括号( std::cout<<(a&b) )。
位与 &,位或 | ,位异或 ^的结果中 某位的值只跟两个操作数中相应位的值相关,这三个位操作均各自符合 结合律和交换律。
移位操作
参见:http://www.cnblogs.com/tenghoo/archive/2008/06/01/1211663.html
c语言的移位操作采取补0还是补符号位依赖于具体的机器,在80x86中采用的是:对无符号数采用逻辑移位方式(即左移最低位补0,右移最高位补0)实现,对符号数的向左移位采用和无符号数相同的方法,对符号数的向右移位采用补符号位的方式。下面是代码实例:
#include <iostream>
#include <cstdlib>
int main(int argc,char**argv){
//for signed
int a=0xff000005;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<std::endl;
for(int i=1;i<=32;++i){
int b=a<<i;
std::cout<<"a<<"<<i<<"="<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
}
std::cout<<"--------"<<std::endl;
for(int i=1;i<=32;++i){
int b=a>>i;
std::cout<<"a>>"<<i<<"="<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
}
//for unsigned
unsigned int au=0xff000005;//这里字面值常量没被认为是符号数,但最好还是0xff000005u
std::cout<<au<<"("<<std::hex<<au<<")"<<std::dec<<std::endl;
for(int i=1;i<=32;++i){
unsigned int b=au<<i;
std::cout<<"au<<"<<i<<"="<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
}
return EXIT_SUCCESS;
}
部分运行结果截图如下,括号内为补码:
符号数左移
符号数右移
无符号数右移
位求反、位与、位或、异或
需要注意的是符号位也参与运算,代码如下:
#include <iostream>
#include <cstdlib>
int main(int argc,char**argv){
int a=-1;
int b=~a;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" ~ "<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
a=-2;
b=~a;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" ~ "<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
a=1;
b=~a;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" ~ "<<b<<"("<<std::hex<<b<<")"<<std::dec<<std::endl;
a=-1;
b=1;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" & "<<b<<"("<<std::hex<<b<<") "<<(a&b)<<std::dec<<std::endl;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" | "<<b<<"("<<std::hex<<b<<") "<<(a|b)<<std::dec<<std::endl;
std::cout<<a<<"("<<std::hex<<a<<")"<<std::dec<<" ^ "<<b<<"("<<std::hex<<b<<") "<<(a^b)<<std::dec<<std::endl;
return EXIT_SUCCESS;
}
以上代码均在gcc下编译