C语言移位与加法运算符混合运算为何输出512而非预期结果
表达式运算顺序与输出512的原因
首先明确C语言中涉及该表达式的两条核心运算规则:
- 运算符优先级从高到低:加法运算符
+> 移位运算符>>/<< - 同优先级的移位运算符遵循左结合规则,即同优先级运算从左向右依次执行
隐式括号的实际位置
你预期的运算逻辑对应括号划分是(a>>2) + (b<<2),但因为加法优先级高于移位运算符,编译器实际添加隐式括号后的表达式等价于:
(a >> (2 + b)) << 2
分步计算过程
代入a=512、b=32的初始值,运算步骤如下:
- 先计算最高优先级的加法子表达式:
2 + b = 2 + 32 = 34,此时表达式简化为a >> 34 << 2 - 按左结合规则先计算右移运算:C标准中规定移位位数大于等于操作数类型位宽的行为属于未定义行为,但主流x86平台的编译器对32位int类型做移位时,通常会将移位位数对32取模(等价于和31做按位与),因此34 mod 32 = 2,实际执行的是
512 >> 2 = 128 - 最后计算左移运算:
128 << 2 = 512,这就是程序最终输出的结果
修正方法
如果要得到你预期的256结果,必须手动为移位运算添加括号,强制指定运算顺序,修改后的核心代码为:
int c = (a>>2) + (b<<2);
注意:不要依赖编译器对超位宽移位的处理逻辑,这类未定义行为在不同平台、不同编译选项下可能产生完全不同的结果,写代码时要保证移位位数小于操作数的位宽。
内容的提问来源于stack exchange,提问作者RCane
相关产品推荐
相关产品推荐

