云计算百科
云计算领域专业知识百科平台

移位操作符和位操作符

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;
}

交换过程解析:

  • a = a ^ b:存储 a 和 b 的差异信息到 a。
  • b = a ^ b:等价于 b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a,此时 b 被赋值为原 a 的值。
  • a = a ^ b:等价于 a = (a ^ b) ^ a = b ^ (a ^ a) = b ^ 0 = b,此时 a 被赋值为原 b 的值。
  • 这里补充一下:

    • 任何数与自身异或结果为 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被消除)

    大致思路就是这样,感谢您的观看。

    ​​​​​​​

    ​​​​​​​

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 移位操作符和位操作符
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!