写点什么

【C 语言深度剖析】深入理解 C 语言中的移位操作符(代码 + 图解)

作者:Albert Edison
  • 2022 年 9 月 12 日
    四川
  • 本文字数:1582 字

    阅读完需:约 5 分钟

【C语言深度剖析】深入理解C语言中的移位操作符(代码+图解)

移位操作符

分为:


左移操作符:<<


右移操作符:>>


其实讲移位操作符之前,先来了解一下计算机中的原码、反码和补码

原码 反码 补码

一个数在计算机内部如果是有符号数,则其最高位作为符号位;


如果符号位为 0,表示该数为正数;如果符号位为 1,表示该数为负数。(0 正 1 负)


如何求原码、反码和补码呢?


原码:最高位作为符号位,其余各位为数值为(0 正 1 负)


反码:正数的反码和原码相同,负数的反码是在原码的基础上:符号位不变,其余各位按位取反


补码:正数的补码与原码相同,负数的补码是在反码的基础上加1


以下求原反补的过程:


例:求+25-25的原码、反码和补码


①不考虑正负,将25转换成二进制 
25D=11001B
② +25 -25
原: 00011001 10011001
反: 00011001 11100110
补: 00011001 11100111
复制代码


再来看一个


例:求+30-30的原码、反码和补码


①不考虑正负,将30转换成二进制
30D=11110B
② +30 -30
原: 00011110 10011110
反: 00011110 11100001
补: 00011110 11100010
复制代码


计算机中使用的是补码,什么是补码,怎么去理解补码?


补码可以理解成一个循环;


这里不过多阐述了,如果还有不懂的可以去百度一下!

左移操作符

移位规则:左边抛弃、右边补 0

正数左移

代码示例:


int main(){  int a = 5;  int b = a << 2;  printf("%d\n", b);
return 0;}
复制代码


运行结果:



那么这个结果是怎么来的呢?


1、首先把十进制的 5 转换成二进制


十进制:5

二进制:00000101

写出原码反码补码:

​ 原码:00000101

​ 反码:00000101

​ 补码:00000101


所以5的补码为:00000101


2、再把补码向左移动 2 位


为什么向左移动 2 位?


因为代码是a<<2



然后:



于是我们就得到了一个新的补码:00010100



3、转换


再把新的补码转换为十进制的数


也就是把00010100转换成十进制,得到了20


明白了吗?

负数左移

代码示例:


int main(){  int a = -5;  int b = a << 2;  printf("%d\n", b);
return 0;}
复制代码


运行结果:



那么这个-20是怎么得来的呢?


1、首先把十进制的-5转换成二进制


但是我们得先求出5的原码


十进制:5

二进制:0000101

所以:-5 的原码、反码、补码为:

原码:10000101

反码:11111010

补码:11111011


所以-5的补码为:11111011


2、再把补码向左移动 2 位



然后:



最后:



于是我们就得到了一个新的补码:11101100


3、回推


这里就不能直接把11101100转换成二进制了,因为这是-5


所以我们得由:补码 ---> 反码 ---> 原码,这样逆序的过程,推算出原码



所以我们得到了新的原码:10010111


4、转换


10010100换算成十进制就是:20


但是因为符号位为:10 正 1 负


所以结果为:-20



这就是左移操作符,懂了吗?

右移操作符

首先右移操作符分为两种:


  • 算术右移

  • 逻辑右移


移位规则:


  • 算术右移:左边用原该值的符号位填充,右边丢弃

  • 逻辑右移:左边用 0 填充,右边丢弃


那么到底是用算术右移还是逻辑右移呢?


主要是取决于编译器的!


我们常见的编译器都是算术右移

算术右移

这里还是拿数字 5 来举例

正数算术右移

代码示例:


int main(){  int a = 5;  int b = a >> 1;
printf("%d\n", b);
return 0;}
复制代码


运行结果:



1、移动


上面我们已经求出了5的补码:00000101


看代码给的是向右移动一位



然后:



所以得到新的补码:00000010


2、转换


因为是正数,所以我们直接把00000010转换成十进制:2

负数算术右移

代码示例:


int main(){  int a = -5;  int b = a >> 1;
printf("%d\n", b);
return 0;}
复制代码


运行结果:



1、移动


上面我们已经求出了-5的补码:11111011


看代码给的是向右移动一位



然后:



所以得到新的补码:11111101


2、回推


我们得以:补码 ---> 反码 ---> 原码,这样逆序的过程,推算出原码



所以我们得到了新的原码:10000011


3、转换


10000011换算成十进制就是:3


但是因为符号位为:10 正 1 负


所以结果为:-3



这就是算术右移的方法,学废了吗?

逻辑右移

逻辑右移的方法和左移操作符有点类似


就是:右边丢弃,左边空的补0


这里就不演示啦!

发布于: 19 小时前阅读数: 23
用户头像

Albert Edison

关注

目前在某大厂担任后端开发,欢迎交流🤝 2022.03.08 加入

🏅️平台:InfoQ 签约作者、阿里云 专家博主、CSDN 优质创作者 🛫领域:专注于C语言、数据结构与算法、C++、Linux、MySQL、云原生的研究 ✨成就:2021年CSDN博客新星Top9,算法领域优质创作者,全网累计粉丝4W+

评论

发布
暂无评论
【C语言深度剖析】深入理解C语言中的移位操作符(代码+图解)_C语言_Albert Edison_InfoQ写作社区