为什么无符号变量存储负值?

时间:2019-06-24 10:48:06

标签: c unsigned-integer

我已将-1分配给unsigned int,并假定它将产生错误,所以我编译了代码,但令我惊讶的是,没有这样做。我不明白其背后的原因。

我尝试打印这些值以手动检查它们,但它始终显示-1。


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(int argc, char *argv[]) {
    unsigned int x = -1;
    printf("%u\n", x);
    int y = -1;
    printf("%d\n", y);
    if (x == y) {
        printf("\nsame");
    } else {
        printf("n s");
    }
    return 0;
}

预期结果可能是错误或警告 但它按原样编译。

2 个答案:

答案 0 :(得分:2)

它之所以有效,是因为:

unsigned int x = -1;

使类型为int的文字-1转换为unsigned int,这是一种标准的,规范的转换。 C11规范草案说:

  

6.3.1.3有符号和无符号整数

     

1将整数类型的值转换为除   _Bool,如果该值可以用新类型表示,则它保持不变。

     

2否则,如果新类型是无符号的,则该值将被重复转换   添加或   比新的最大值减去一个   键入,直到该值在新类型的范围内。 60)

后者就是这里发生的情况,因此假设要添加32位整数2 32 ,结果为0xffffffff

我不认为带有printf()的{​​{1}}会显示%u,这将是一个相当大的错误。

答案 1 :(得分:0)

这是标准允许的。至少在概念上将-1分配给-1类型时,该值将转换为一个数字,该数字可以通过重复加 2 n < / em>,其中 n 是该类型的位数。

此转换也发生在比较unsigned中的signed类型(由于变量之一是x == y类型,因此比较以unsigned算术进行)。