#include<stdio.h>
int main() {
int x = 0x80000000;
printf("%i\n",(((x - 1) >> 31) & 1)); //shows 0 as output
printf("%i\n",!(((x - 1) >> 31) & 1)); //shows 0 as output(expected 1)
}
为什么会这样?由于两个语句都执行相同的操作,所以!操作员。为什么第二个printf没有给出1作为输出? 据我所知,逻辑不超过0给出1,逻辑不超过其他数给出0。我在这里做错了吗?
答案 0 :(得分:3)
您在这里看到的是由有符号整数溢出引起的undefined behavior的体现。
假设一个32字节的int
使用二进制补码,则值0x80000000超出int
的范围,因此它进行了实现定义的转换。很有可能,它将转换为值-2147483648,这是系统int
中可以保留的最小值。
在两种情况下,您要做的下一步都是从该值中减去1。这不是不保证可以解决的问题。这被视为溢出,是未定义的行为。这就是为什么您看到自己看到的结果的原因。一旦您具有未定义的行为,就无法保证程序将执行的操作。