C语言中移位操作符那点事

最近碰到几个有意思的移位操作符的题目,下面先来看看这几个题目(32bit-CPU架构):

1.     int i = 1;

        printf("%d\n",i<<32);

2.     printf("%d\n",1<<32);

3.     int i=-1;

        printf("%d,%d\n",i<<32,  i<<31, i>>32, i>>31);

这几个题目看起来都很简单,但很容易中招哦,不信自己先给个答案,再来验证下吧!

第一题:

      和编译器的处理有关,正整数1在计算机中按照补码存储形式为0x 00 00 00 01,编译器默认将移位操作符的右边数对32取余,因此左移32位等同于左移0位,答案仍为1,对于右移也适用。

第二题:

      这个常数的移动操作编译器的处理略有不同,如果按照第一题来解,答案应该为1,可是编译后执行发现结果却为0,说明这里的1<<32编译器并没有对32取余,左移补0,因此,左移32位后则为0,这里再通过 printf("%d\n",1<<33); 验证,发现结果仍为0,说明33并没有对32取余(如果取余的话结果应该为1<<1=2)。

第三题:

      有符号负整数-1,在内存中补码形式存储为0xFFFFFFFF,因为有符号位1的存在,变量的右移都补1,而左移仍补0,变量的左右移右操作数会对32取余,则左移32位和右移32位均等同于不移动,结果仍为-1,而左移31位补零,补码0xFFFFFFFF左移31位为0x80000000,可以自己手动还原为原码检验,打印到屏幕上为-2147483648,而右移31位,补码0xFFFFFFFF右移补1,因此右移任何位都不变,仍为-1。


总结:1. 编译器对常数的左右移位操作与变量略有不同,常数左右移位不会将右操作数对32取余,而变量的左右移会将右操作数对32取余。

            2.左移均补0,有符号数的负数的右移补1,正数的右移补0。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值