1:移位操作符
1.1移位操作符的概念
移位操作符是编程中用于对二进制数进行位移动的运算符,分为左移和右移两种基本类型。它们直接操作整数的二进制表示,通过移动位来改变数值。
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
1.2:左移操作符(<<)
左移操作符将二进制数的所有位向左移动指定的位数,右侧空出的位用0填充。每左移一位相当于原数乘以2(在不溢出的情况下)。
int a = 5; // 二进制: 00000101
int b = a << 2; // 左移2位: 00010100 (十进制20)
#include <stdio.h>
int main()
{
int num = 10;
int n = num<<1;
printf("n= %d\\n", n);
printf("num= %d\\n", num);
return 0;
}
左移操作符常用于快速计算 2 的整数幂。例如:
1 << 3 结果为 8(即 (2^3))。
1 << 5 结果为 32(即 (2^5))。
1.3:右移操作符(>>)
右移操作符将二进制数的所有位向右移动指定的位数。分为逻辑右移(无符号数,左侧补0)和算术右移(有符号数,左侧补符号位)。
int a = -8; // 二进制(补码): 11111000
int b = a >> 2; // 右移2位: 11111110 (十进制-2)
- 左移n位:等价于乘以 ( 2^n )(无溢出时)。
- 右移n位:等价于除以 ( 2^n )(向下取整)。
#include <stdio.h>
int main()
{
int num = 10;
int n = num>>1;
printf("n= %d\\n", n);
printf("num= %d\\n", num);
return 0;
}
警告⚠️:对于移位运算符,不要移动负数位,这个是标准未定义的
例如:
int num = 10;
num>>-1;//error
2:位操作符
2.1:位操作符的概念
位操作符直接对二进制数的位进行操作,常用于底层编程、性能优化和硬件交互。
2.2:按位与(&)
规则:两位均为1时结果为1,否则为0。
5 & 3 = 1 // 二进制:0101 & 0011 = 0001
2.3:按位或(|)
规则:两位至少有一个为1时结果为1。
5 | 3 = 7 // 0101 | 0011 = 0111
2.4:按位异或(^)
规则:两位不同时结果为1,相同时为0。
5 ^ 3 = 6 // 0101 ^ 0011 = 0110
2.5:按位取反(~)
规则:单目操作符,将所有位取反(0变1,1变0)。
~5 = -6 // 假设8位系统:~00000101 = 11111010(补码表示)
通过合理使用位操作符,可以显著提升代码效率和灵活性。接下来我给出一些代码来帮助大家更好的理解
代码实现:
#include <stdio.h>
int main()
{
int num1 = -3;
int num2 = 5;
printf("%d\\n", num1 & num2);
printf("%d\\n", num1 | num2);
printf("%d\\n", num1 ^ num2);
printf("%d\\n", ~0);
return 0;
}
经典面试题:
不能创建临时变量(第三个变量),实现两个数的交换。
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\\n", a, b);
return 0;
}
交换过程解析:
这里补充一下:
- 任何数与自身异或结果为 0:x ^ x = 0
- 任何数与 0 异或结果为自身:x ^ 0 = x
练习题:
这里我们再来完成一个练习题:求⼀个整数存储在内存中的⼆进制中1的个数。
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
while(num)
{
count++;
num = num&(num-1);
}
printf("⼆进制中1的个数 = %d\\n",count);
return 0;
}
num = num & (num – 1);
每次执行这行代码时,都会将num的二进制表示中最右边的1变为0。例如:
- 若num为12(二进制1100),num-1为11(二进制1011)
- 1100 & 1011 = 1000(最右边的1被消除)
大致思路就是这样,感谢您的观看。
评论前必须登录!
注册