You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中带等号与无等号的位位移结果为何不同?01与02案例差异原因?

关于C语言位位移操作的两个疑问解答

先把你的代码贴出来方便对照分析:

char c=0xAB; 
printf("01:%x\n", c<<2); // 输出fffffeac
printf("02:%x\n", c<<=2); // 输出ffffffac
printf("03:%x\n", c<<=2);

疑问一:带等号和不带等号的位位移结果不同?

这核心是整数提升规则和赋值截断行为在起作用:

  • 当你用c<<2时,c是char类型(默认带符号),在表达式里会自动提升为int类型。0xAB作为有符号char是负数(最高位为1),提升成int后会做符号扩展,变成32位的0xFFFFFFAB。对这个完整的32位值左移2位,得到的就是0xFFFFFEAC,也就是你看到的01的输出。
  • 而c<<=2是复合赋值操作,它会先执行左移,但结果会被强制截断回char的8位长度(因为c的类型是char)。0xAB左移2位后超出8位的部分直接丢掉,剩下的是0xAC,然后把这个值赋值给c。当printf输出时,c再次被提升为int,0xAC作为有符号char是负数,符号扩展后就是0xFFFFFFAC,这就是02的输出。

疑问二:01和02案例的输出差异?

本质就是两个操作的计算逻辑完全不同:

  • 01是先把char提升为int,再在32位范围内左移,全程没有截断,结果保留了完整的32位数值。
  • 02是先对8位的char做左移,截断后赋值给c,再把c提升为int输出,左移后的结果被砍成8位,再扩展成32位int,自然和01的结果不一样。

顺便提一句,03的输出会是0xFFFFFF28——此时c已经是0xAC,再左移2位截断成8位是0x28,扩展成int后就是这个结果啦。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:37:55