You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言中移位操作的正确顺序?三段移位代码为何输出不同结果?

三段C语言移位代码的输出差异解析

咱们来逐个拆解这三段代码,看看为啥输出不一样——核心都是C语言里的整数提升移位规则在搞事情!

代码1:b = 66 << 2 >> 8; 输出1

首先,66是C语言默认的int类型字面量,所以整个表达式66 << 2 >> 8都是在int层面完成计算的:

  • 66 << 2:66的二进制是000...01000010,左移2位后变成000...100001000,对应十进制264;
  • 264 >> 8:因为是正数的int右移,高位补0,264右移8位后剩下000...00000001,也就是十进制1;
    最后把这个int类型的1赋值给signed char b,完全在signed char的范围(-128~127)内,所以输出1

代码2:分步移位输出0

这段代码把移位拆成了两步,中间的赋值截断是关键:

  1. b = 66 << 2;:先计算66 << 2得到int类型的264,但要赋值给8位的signed char时,超出范围的部分会被截断——264减去256(2^8)后得到8,所以此时b的值是8;
  2. b = b >> 8;bsigned char类型,在参与移位运算前会触发整数提升,自动转换成int类型(值还是8)。对int类型的8右移8位,高位补0后结果就是0,赋值给b后输出0

代码3:移位位数为0输出66

这里的关键是移位位数变成了0:

  1. b = 2 >> 8;2int类型,右移8位后所有有效位都被移出,结果是0,赋值给bb的值为0;
  2. 66 << b:也就是66 << 0,根据C语言规则,任何数左移0位都等于它本身,所以结果还是66,赋值给b后输出66

核心差异总结

这三段代码的本质区别在于:

  • 运算的类型阶段:代码1的两次移位都在int上完成后再赋值;代码2是先截断到char,再以提升后的int做第二次移位;
  • 移位位数的有效性:代码3的移位位数为0,直接返回原数;
  • 整数提升与截断:C语言中,char/short这类小于int的类型,参与运算时会先提升为int,赋值时又会截断回原类型,这两个步骤直接左右了最终结果。

内容的提问来源于stack exchange,提问作者homior

火山引擎 最新活动