移位操作符
左移操作符 << (左边丢弃,右边补0)
右移操作符 >> (分为算术右移和逻辑右移 )一般都使用算术右移
1.算术右移 右边丢弃,左边补原符号位
?
#include<stdio.h>
int main()
{
int a = 16;
int b = a >> 1;
//移动的是二进制位
//00000000000000000000000000010000
//00000000000000000000000000001000
printf("%d\n", b);//输出8
}
?
#include<stdio.h>
int main()
{
int a = -1;
int b = a >> 1;
//整数的二进制表示有:源码、反码、补码
//存储的内存的是补码
//10000000000000000000000000000001 - 源码
//11111111111111111111111111111110 - 反码(反码是符号位不变,其他按位取反)
//11111111111111111111111111111111 - 补码(反码+1)
printf("%d\n", b);//输出-1
}
2.逻辑右移 右边丢弃,左边补0
🔺对于移位运算符,不要移动负数位,这个是标准未定义的。
位操作符
& 按位与
#include<stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = a & b;
//00000000000000000000000000000101 a的补码
//00000000000000000000000000000011 b的补码
//00000000000000000000000000000001 对应的二进制位有一个0就是0,两个1就是1
printf("%d\n", c);//输出1
}
| 按位或
#include<stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = a | b;
//00000000000000000000000000000101 a的补码
//00000000000000000000000000000011 b的补码
//00000000000000000000000000000111 对应的二进制位有一个1就是1,两个0才为0
printf("%d\n", c);//输出7
}
^ 按位异或
#include<stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = a ^ b;
//00000000000000000000000000000101 a的补码
//00000000000000000000000000000011 b的补码
//00000000000000000000000000000110 对应的二进制相同为0,相异为1
printf("%d\n", c);//输出6
}
🔺他们的操作数必须是整数。
列题1:交换两个int变量的值,不能使用第三个变量,即a=3,b=5,交换后a=5,b=3
使用加减法(有可能溢出)
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
a = a + b;
b = a - b;
a = a - b;
printf("%d,%d\n", a, b);
}
使用异或法
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
a = a ^ b;//这里a=6
b = a ^ b;//b=3
a = a ^ b;//a=5
printf("%d,%d\n", a, b);
}
例题二:求一个整数存储在内存中的二进制中1的个数。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = 0;
int i = 0;
int count = 0;
scanf("%d", &a);
for (i = 0; i < 32; i++)
{
if (1 == ((a >> i) & 1))
count++;
}
printf("%d\n", count);
}
|