位操作符:
(1)按位与—— &
(2)按位或—— |
(3)按位异或—— ^
注意:位操作符只能用于整数!!!
左右移操作符:
(1)左移操作符—— <<
(2)右移操作符—— >>
注意:左右移操作符只能用于整数!!!
1、按位与——&
如果比较的两个位中有一个为0则结果为0,
如: int a=2; a的二进位为 000000000000000000000000000000010
int b=11; b的二进位为 000000000000000000000000000010011
则 a&b=2; 其二进制表示为000000000000000000000000000000010
此处a&b恰好为a实属偶然
2、按位或—— |
如果比较的两个位中有一个为1则结果为1
如: int a=2; a的二进位为 000000000000000000000000000000010
int b=11; b的二进位为 000000000000000000000000000010011
则 a | b=11; 其二进制表示为000000000000000000000000000010011
此处a|b恰好为b实属偶然
3、按位异或—— ^
如果比较的两个位相同则为0,不同则为1。
如: int a=2; a的二进位为 000000000000000000000000000000010
int b=11; b的二进位为 000000000000000000000000000010011
则 a ^ b=9; 其二进制表示为000000000000000000000000000010001
4、左移操作符—— <<
左侧(最高位)丢弃,右边补0;其作用相当于 *2
如:
a 的二进制位表示为: 000000000000000000000000000000001
a<<1
5、右移操作符——>>
右移操作的过程有两种可能:
(1)算术右移:右边丢弃,左边补符号位
(2)逻辑右移:右边丢弃,左边补0
这两种可能是取决于编译器的,在VS中是采用算术右移的
例如
a 的原码为 100000000000000000000000000000101
a 的反码为 11111111111111111111111111111010
a 的补码为 11111111111111111111111111111011
(对于整形在内存中的存储形式还不明白的朋友,可以查看我的上篇的博客,写的很全)
发生右移操作后
b的补码为:11111111111111111111111111111101
b的反码为:11111111111111111111111111111100
b的原码为:10000000000000000000000000000000011
因此b的值为 -3
左右移操作并不影响a本身的值!!!
6、用到按位操作符的一些编程(有点巧妙)
例题1 求一个数的二进制位中1的个数
方法一:
//方法一:
void Number1()
{
int a,count=0,i;
printf("求一个数二进制位中1的个数,请输入该数:");
scanf("%d", &a);
for (i = 0; i < 32; i++)
{
//a>>i不改变a的值,只有a=a>>i才会改变a的值
if ((a >> i) & 1 == 1)
{
count++;
}
}
printf("%d\n",count);
}
方法二:
//方法二:
//注意!!这个方法有一个关键点,就是n要为unsigned int
//当n为有符号负数,n%2要么为0要么为-1,最终count始终为0,所以要把它当成无符号整形
void Number2()
{
int count=0;
unsigned int n;
printf("求一个数二进制位中1的个数,请输入该数:");
scanf("%u", &n);
while (n)
{
if (n % 2 == 1)
{
count++;
}
n = n / 2;
}
printf("%d\n", count);
}
方法三:
//方法三:
//非常神奇!!!
//n=n&(n-1)
// n=13 1101 - n 1100 - n-1
// 1100 - n 1011 - n-1
// 1000 - n 0111 - n-1
// 0000 - n 停止
void Number3()
{
int count = 0,n;
printf("求一个数二进制位中1的个数,请输入该数:");
scanf("%d", &n);
while (n)
{
n = n & (n - 1);
count++;
}
printf("%d\n",count);
}
例题二 判断一个数是不是2的幂次方
//n&(n-1)的另一种应用
//用来判断n是不是2的幂次方
//如果n是2的幂次方(正数),则它的补码中只有一个1,此时n^(n-1)==0
void especial()
{
int n;
printf("求一个数是不是2的幂次方,请输入该数:");
scanf("%d", &n);
if ((n & (n - 1) )== 0)
{
printf("是\n");
}
else
printf("不是\n");
}
例题三 求两个数中不同位的个数
方法一:
//方法一:
void Diff1()
{
int m, n,diffcount=0,i;
printf("求两个数二进制位不同位的个数,请输入这两个数:");
scanf("%d%d", &m, &n);
for (i = 0; i < 32; i++)
{
if (((m >> i) & 1) != ((n >> i) & 1))
diffcount++;
}
printf("%d\n", diffcount);
}
方法二:
//方法二:
//^(异或操作符),如果位相同则取0,不同取1
void Diff2()
{
int m, n, diffcount = 0;
printf("求两个数二进制位不同位的个数,请输入这两个数:");
scanf("%d%d", &m, &n);
int tmp = m ^ n;//相同则为0,不同则为1,接下来就是求tmp补码中1的个数
while (tmp)
{
tmp = tmp & (tmp - 1);
diffcount++;
}
printf("%d\n", diffcount);
}
例题四 不创建第三个变量就可以交换两个数的值
//不创建第三个变量就可以交换两个数的值
void Exchange()
{
int a, b;
printf("不需要引入第三个变量就可以交换两个数的值,请输入这两个数:");
scanf("%d%d", &a, &b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d", a, b);
}
例题五 打印一个数二进制形式的奇数位和偶数位
//打印一个数二进制中奇数位的数,偶数位的数,设最右边的为第一位
//如15打印的效果为:
//奇数位:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
//偶数位:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
void Printodd()
{
int n,i;
printf("打印一个数的奇数位和偶数位,请输入这个数:");
scanf("%d", &n);
printf("奇数位:");
for (i = 30; i >= 0; i-=2)
{
printf("%d ", (n >> i) & 1);
}
printf("\n");
printf("偶数位:");
for (i = 31; i >= 1; i-=2)
{
printf("%d ", (n >> i) & 1);
}
printf("\n");
}
例题六 不使用乘法运算完成2的n次方功能;例如:输入2,则输出4;输入10,则输出1024
int main()
{
int n;
scanf("%d",&n);
printf("%d",(1<<n));
return 0;
}
左右移操作符和位操作符的介绍到这里就结束啦!!!希望这篇博客对你有帮助!