#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)
}
为什么会发生这种情况?由于这两个语句执行相同的操作,除了!运算符(operator)。为什么第二个 printf 不给出 1 作为输出? 据我所知,逻辑不超过 0 给出 1,逻辑不超过其他数字给出 0。我在这里做错了什么吗?
最佳答案
您在这里看到的是 undefined behavior 的表现由有符号整数溢出引起。
假设使用二进制补码的 32 字节 int
,值 0x80000000 超出了 int
的范围,因此它会经历实现定义的转换。最有可能的是,它会转换为值 -2147483648,这是系统上 int
可以保存的最小值。
在这两种情况下,您接下来要做的就是从此值中减去 1。这不保证能够环绕。这被认为是溢出并且是未定义的行为。这就是您看到所看到的结果的原因。一旦出现未定义的行为,就无法保证程序会做什么。
关于c - 为什么这两个 C 语句产生相同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64364307/