今天给大家带来的是移位操作符的详解
首先大家在学习移位操作符之前要明确:移位操作符移动的是二进制位!!!
<< 左移操作符
>> 右移操作符
注意:移位操作符的操作数只能是整数。
为了让大家能更加清晰地认识移位操作符,所以在这之前先给大家插播整数二进制的讲解。
整数的二进制表示形式有3种:原码、反码、补码。
1、原码:按照一个数的正负,直接写出二进制的形式。
2、反码:根据正负判断,下文有解释。
3、补码:根据正负判断,下文有解释。
注意:
1、内存中存储的是补码的二进制,所以在参与移位的都是补码。
2、参与计算的是原码的二进制,所以在算出最终结果都需要将补码转换成原码。
正数的原码、反码、补码是相同的。
整型占4个字节(32bit)
eg:10的二进制
00000000000000000000000000001010 - 原码
00000000000000000000000000001010 - 反码
00000000000000000000000000001010 - 补码
负数的原码、反码、补码要经过计算的:
1、反码是原码的符号位不变,其他位按位取反,就是反码。
2、补码是反码+1 || 补码也可直接到反码,见下图。
eg:-10的二进制,负数的最高位为1
10000000000000000000000000001010 - 原码
11111111111111111111111111110101 - 反码
11111111111111111111111111110110 - 补码
看完上面的解释,相信大家对整数二进制的原码、反码、补码概念与计算都有基本的认识。
下图是负数的原码、反码、补码之间相互转换关系图,方便大家进行梳理。
接下来进入正文-----移位操作符
上文中提到,移位操作符分别有:
<< 左移操作符
>> 右移操作符
再强调一下:参与移位的是补码,参与计算的是原码。
操作符不同移位运算规则也有不同。
左移操作符运算规则:左边丢弃,右边补0
右移操作符运算规则:
1、算术右移(常见):右边丢弃,左边补原来的符号位
2、逻辑右移:右边丢弃,左边补0
先给大家介绍左移操作符,先给大家举个正数的例子:
int main()
{
int a = 10;
int b = a << 1;
//00000000000000000000000000001010 -补码
return 0;
}
左移前:
左移后:
由于a是正数,所以原、反、补码都是一致,可直接运算,故b的结果是20。
需要注意的是:a<<1的结果是移位后的效果,但是a的值是不变的。
eg:
int a = 10;
int b = a+2;
//最终b是12,a还是10
再给大家举个负数的例子:
int main()
{
int a = -10;
//10000000000000000000000000001010 -原码
//11111111111111111111111111110101 -反码
//11111111111111111111111111110110 -补码
int b = a << 1;
return 0;
}
左移前:
左移后:
在左移后得到了b的补码,由于是负数,所以需要根据计算规则算出原码,具体参考上文,我就直接给出过程,有兴趣的朋友可以计算后一起来对一对答案~
接下来给大家介绍右移操作符
int main()
{
int a = -1;
//10000000000000000000000000000001 -原码
//11111111111111111111111111111110 -反码
//11111111111111111111111111111111 -补码
int b = a >> 1;
return 0;
}
右移前(算术右移):
右移后(算术右移):
右移后(逻辑右移):
在右移后得到了b的补码,由于是负数,所以需要根据计算规则算出原码,具体参考上文,我就直接给出过程,有兴趣的朋友可以计算后一起来对一对答案~
警告:
对于移位运算符,不要移动负数位,这个是标准未定义的 。
eg:
int a = 10;
a>>-1;
结语:
移位操作符的内容就此告一段落,希望各位读者阅读后都能有所收获,如果喜欢本篇博客的可以点赞+关注+收藏!!!同时也欢迎各路大神如果在阅读过程中发现文章有错误也可私信指正错误,我们下一篇博客再见~~~