位操作是程序设计中对位模式或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加法运算相同(仍然快于乘法运算).
1.按位与"&"
eg1
将int型变量n的低8位全置成0,其余位不变,则可执行:
n = n & 0xffffff00;
n &= 0xffffff00;
如果n是short型,只需执行:
n &= 0xff00;
eg2
判断一个int型变量n的第7位(从右往左)是否是1,只需看表达式"n & 0x80"的值是否等于0x80即可
0x80 二进制 0000 0000 0000 0000 0000 0000 0100 0000
2.按位或"|"
按位或运算通常用来将变量某些位置为1或保留某些位不变。
eg1
将int型变量n低8位全置成1,其余位不变,可以执行:
n |= 0xff;
3.按位异或"^"
仅当两个二进位不同时,结果对应的二进位才是1,否则为0。
运算特点:如果a^b=c,那么有c^b==a及c^a==b,可用来快速加密或解密。
a ^ b = c
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
4.按位非"~"
将二进制位0变为1,1变为0
/********************
21二进制 : 0000 0000 0000 0000 0000 0000 0001 0101
按位非 : 1111 1111 1111 1111 1111 1111 1110 1010
********************/
#include
int main()
{
printf("%d, %u, %x", ~21, ~21, ~21);
return 0;
}
/**********output************
-22, 4294967274, ffffffea
****************************/
5.左移"<<"
左操作数:二进制数;右操作数:左移位数;低位补0;移出舍弃。
eg1
9有32位,二进制表示为:
0000 0000 0000 0000 0000 0000 0000 1001
表达式"9 << 4"将上面二进制数左移4位,得到:
0000 0000 0000 0000 0000 0000 1001 0000
即十进制的144
实际上,左移n位就等于乘以2^n。左移操作比乘法快的多。
#include
int main()
{
int n1 = 15;
short n2 = 15;
unsigned n3 = 15;
unsigned char c = 15;
n1 <<= 15;
n2 <<= 15;
n3 <<= 15;
c <<= 6;
printf("n1=%x, n2=%d, n3=%d, c=%x, c<<4=%d",n1,n2,n3,c,c<<4);
return 0;
}
/**********output*************
n1=78000, n2=-32768, n3=491520, c=c0, c<<4=3072
*****************************/
6.右移">>"
左操作数:二进制数;右操作数:右移位数;高位补0;移出舍弃。
有符号数,如long、int、short、char,右移时,符号位即最高位将一起移动,如果原符号位为1,右移时最高位补1;如果原符号位为0,右移时最高位补0。
无符号数,如unsigned long、unsigned int、unsigned short、unsigned char,右移时最高位补0。
#include
int main()
{
int n1 = 15;
short n2 = -15;
unsigned n3 = 0xffe0;
unsigned char c = 15;
n1 = n1 >> 2;
n2 >>= 3;
n3 >>= 4;
c >>= 3;
printf("n1=%x, n2=%d, n3=%x, c=%x",n1,n2,n3,c);
return 0;
}
/**********output*************
n1=3, n2=-2, n3=ffe, c=1
*****************************/