位运算
优先级 | 运算符 | 功能 | 结合方式 |
---|---|---|---|
2 | ~ | 按位取反 | 由左向右 |
5 | << >> | 左移 右移 | 由左向右 |
8 | & | 按位与 | 由左向右 |
9 | ^ | 按位异或 | 由左向右 |
10 | | | 按位或 | 由左向右 |
左移、右移运算符:
运算规则:将变量的二进制数整体左移/右移一位。
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试左移运算符*/
int main()
{
unsigned short int n=3;
int i;
for(i=0;i<10;i++)
{
printf("%d\n",n);
n<<=1;//作用相当于n=n<<1;
}
return 0;
}
结果:
解析:
1.如上代码所示,左移带来的是变量n的翻倍。这个特性使得左移、右移运算符常用于变量的*2或/2的操作。
2.对于以上n,其值在内存中的二进制表示如图所示:
将其进行一次左移。则其值在内存中的二进制表示如图所示:
可以看到,该二进制数整体左移了一位。将其换算成十进制数,正好是6。
以上即是左移运算的原理,而右移运算同理。
3.>>后面的数组代表移动的位数。比如n>>2代表n右移两位,得到的效果就n=n/2/2.
取反、与、或、异或运算符:
取反运算规则:将变量的二进制数进行反转(0变为1,1变为0)
与运算规则:将进行运算的两变量的二进制数进行逐位比较,进行逻辑中的与运算,只是将1作为真,将0作为假。
或运算规则:和以上与运算相似,只是进行逻辑中的或运算。
异或运算规则:和以上的运算相似,只是判断改为判断各位的数字是否相同,如果相同,则结果中该位为假(0)否则为真(1)。
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试按位与、或、异或三种运算符*/
int main()
{
unsigned short m=0x3A,n=0x02f,t;
t=~m;
printf("%x\n",t);
t=m&n;
printf("%x\n",t);
t=m|n;
printf("%x\n",t);
t=m^n;
printf("%x\n",t);
return 0;
}
结果:
解析:
1.对于以上代码中的m,在内存中的二进制表示如下:
将m按位取反之后,在内存中的二进制表示如下:
将m和n按位与的过程,在内存中的二进制表示如下:
将m和n按位或的过程,在内存中的二进制表示如下:
将m和n按位异或的过程,在内存中的二进制表示如下:
以下为利用位运算实现的跑马灯小程序:
代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/*这个程序用于实现跑马灯效果*/
void show(int m);
int main()
{
unsigned int x=0x1,y=0x10;
while(1)
{
show(x);
x=(x<<2)|(x>>(30));
show(y);
y=(y<<2)|(y>>(30));
Sleep(50);
system("cls");
}
return 0;
}
void show(int m)
{
int i;
for(i=0;i<32;i++)
{
if(m%2==0)
printf("○");
else
printf("●");
m/=2;
}
printf("\n");
}
结果:
解析:使用位运算改变变量的二进制表示中1的位置,再根据0和1的位置输出○和●,实现该程序。