C语言中进行位移和加法运算后变量取值不正确

3

我有这段代码,基本上是取两个整数并进行移位后相加。然而,在加法之后,我得到了一个不正确的值。

我已经找到了一种解决方法(即通过将移位后的值存储在新的无符号整数变量中并将它们相加),但我想要理解为什么这个方法没有起作用:

void change(uint8_t in[3], uint16_t out[2]){
    out[0] = in[0]<<2 + in[1]>>2;
    printf("%u\n",in[0]<<2 ); // outputs 48  --- correct
    printf("%u\n",in[1]>>2 ); // output 1 --- correct
    printf("%u\n",out[0] ); // output 768 --- wrong, I expected 49
}

int main(int argc, char const *argv[])
{
    uint8_t in[3] = {12,6,9};
    uint16_t out[2];
    change(in,out);
    return 0;
}

2
使用括号 out[0] = (in[0]<<2) + (in[1]>>2); 进行编程。 - Vaibhav
2
puts("hello, operator precedence"); - Lundin
@Vaibhav,那解决了我的问题。非常非常感谢。 - Aven Desta
1个回答

5

运算符+比移位运算符优先级更高。你需要编写:

out[0] = (in[0]<<2) + (in[1]>>2);

没有括号,它被评估为

out[0] = in[0] << (2 + in[1]) >> 2;

编译器GCC在开启警告模式时,会对你的代码进行编译并显示以下警告信息:
test.c:5:23: warning: suggest parentheses around ‘+’ inside ‘<<’ [-Wparentheses]
     out[0] = in[0]<<2 + in[1]>>2;
                       ^

这是一个例子,说明我们应该始终注意编译器警告的原因。

2
@Babydesta 这是一个警告,而不是错误。请查阅您编译器的文档以了解如何打开警告。对于GCC,我总是使用“-Wall -Wextra”。 - taskinoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接