我只是试图将unsigned int降低到0以下。令我惊讶的是它有效!
#include<stdio.h>
int main(void)
{
unsigned int foo = 5;
foo -= 10;
printf("%d", foo);
return 0;
}
编译
clang -Weverything main.c
这个节目回归
-5
正如this帖子和我的个人知识所述,这是不可能的。但为什么它会起作用呢?我错过了什么吗?是因为未定义的行为?还是printf?或其他什么?
答案 0 :(得分:7)
此程序使用printf
将unsigned int
的值重新解释为有符号整数。虽然当unsigned int
的值也适合int
时,这不是问题,但它是未定义的行为:
如果任何参数不是相应转换规范的正确类型,则行为未定义
说明:从五个“回绕”中减去十个,因此根据系统的unsigned int
表示得到一个大数字。事实证明,这个大数字的位表示对应于系统上负五的表示,因此当printf
将值重新解释为有符号时,将显示负五。
为什么编辑器没有任何通知?
有关可能的解释,请参阅this Q&A。
答案 1 :(得分:4)
printf()将foo的值解释为有符号整数。尝试用%u替换%d。
编辑:正如dasblinkenlight所说,这是未定义的行为。编程语言规范没有说明如果发生这种情况应该怎么做,所以它由实现来决定。有时这可能会产生不同的结果,但在这种情况下,它可能会赢得
。答案 2 :(得分:0)
计算机上的数字以两种形式存储。并且在2的补码中表示的负数是无符号数范围内的有效数。处理器核心巧妙地实现加法/减法/乘法/除法,使得它不需要知道数字的符号来执行这些操作。利用该核心的C语言将这些数字传递给执行请求操作并返回结果的处理器的算术单元。这就是你在整数上得到预期结果的原因。