这篇文章主要介绍了C语言中移位操作符,文章中通过详细的代码以及有关计算机中零碎的知识点对移位操作符进行了一个更好的解释,需要的小伙伴们可以一起学习学习吖~
移位操作符:移动的是补码的二进制序列。
在C语言当中,有两种移位操作符:
(1)左移操作符:<<
(2)右移操作符:>>
是不是符号很容易混淆啊,大家记住它们的时候就想着箭头的方向朝哪边,就是什么操作符。
在进入正题之前,先给大家普及一下关于整数在内存中存储的相关基础知识吧
大家要知道,在C语言中整型是四个字节,也就是32bite,在内存中就是一个32位的二进制数字。
那原码,反码,补码分别是什么呢,它们又是如何求的呢?
这三种二进制表示方法,都由符号位和数值位两部分组成,当是正数时,符号位为0;当是负数时,符号位为1;
原码:就是将一个整数转换成二进制的形式,通俗的讲,原码就是一个整数原有的不做任何改变的二进制形式。
反码:在原码的基础上,将原码的符号位不变,其他位按位取反,就可以得到反码。
补码:在反码的基础上,反码加1,就可以得到补码。
举个例子吧:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int m = 10; //00000000000000000000000000001010 //正数的原码,反码,补码是相同的; int m = -10; //10000000000000000000000000001010 -- 原码 //11111111111111111111111111110101 -- 反码 //11111111111111111111111111110110 -- 补码 return 0; }
在计算机内部,整数的存储采用的是以补码的方式进行存储,那么,当读取整数时,还需要采用逆向转换的思想,通俗的讲,就是要将补码转换成原码。
使用补码的原因:
因为使用补码。可以将符号位和数值域统一处理,与此同时,加法和减法也可以统一处理,这里需要注意,CPU只有加法器,除此之外,在补码与原码相互转换的过程中,它的运算过程是相同的。在内存中存放的是补码,但打印出来,也就是我们所看到的可是原码吆。如果大家原码转化成补码已经很熟悉,那么也应该具有逆向思维,掌握补码如何转化为原码哦~
一. 左移操作符
移位规则:左边抛弃,右边补0;
举个例子最好说明了:
假如,我们定义一个整型变量n,给n赋初值为5,将n左移,即n<<1,那结果是什么呢?
前面已经介绍了整型在内存中的存储方式,那么我们就知道整型5在内存中的存储方式是以补码的形式存在的,那么将5左移1位,也就是将5的二进制位向左移动1位,并且将移动的这一位抛弃,右边补0,所得到的就是5<<1 位的结果了。
运行结果:
二.右移操作符
右移运算分为两种:
(1)逻辑移位:左边用0填充,右边丢弃;
(2)算数移位:左边用该原值的符号位填充,右边丢弃;
还是举例子吧,哈哈:
假如,我们定义一个整型变量n,给n赋初值为5,将n右移,即n>>1,那结果是什么呢?
分情况讨论:
a:假如说右移是算数移位:
通俗的讲,就是将5在内存中存储的二进制位右移1位,把右边移动的这位抛弃,左边用该值存储的二进制位的符号位填充 ,所得到的结果就是5>>1位的结果了。
运行结果:
b:假如说右移是逻辑移位:
通俗的讲,就是左边用0填充,右边丢弃,因为在内存中,当整数为正数时,其符号位是用0表示的,所以,对于正整数来说,两种移位方法所得到的结果都是相同的。
那么,如果是对于负整数呢?接下来试试吧:
a:假如说右移是算数移位:
b:假如说右移是逻辑右移:
咦,怎么出现不一样的结果了呢?
这里就有个小注意:在C语言标准中,并没有明确定于对于有符号数应该使用哪种类型的右移,但是,实际上几乎所有的编译器/机器组合都对有符号数使用算术右移,不过,对于无符号数,右移必须是逻辑的。
警告⚠:
对于移位运算符,不要移动负数位,这个是为标准定义的。
比如:
int num = 10; num >> -1; error
好啦,关于C语言移位操作符就介绍到这里啦,如有不足之处,欢迎各位小伙伴们指点吖~