为什么声明为 unsigned int 的变量会生成负值?

Why is a variable declared as an unsigned int generating a negative value?

我写这段代码是为了学习位移。令我惊讶的是,即使我将 x 声明为 unsigned int,输出中包含一个负数,即当最左边的位设置为 1 时。我的问题:为什么?我认为 unsigned int 从来都不是负面的。根据 sizeof(x)x 是 4 个字节宽。

这是代码片段:

int main(void)
{
    unsigned int x;

    x = 1;

    for (int i = 0; i < 32; i++)
    {
        printf("2^%i = %i\n", i, x);
        x <<= 1;
    }


    return 0;
}

这是输出:

2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
2^8 = 256
2^9 = 512
2^10 = 1024
2^11 = 2048
2^12 = 4096
2^13 = 8192
2^14 = 16384
2^15 = 32768
2^16 = 65536
2^17 = 131072
2^18 = 262144
2^19 = 524288
2^20 = 1048576
2^21 = 2097152
2^22 = 4194304
2^23 = 8388608
2^24 = 16777216
2^25 = 33554432
2^26 = 67108864
2^27 = 134217728
2^28 = 268435456
2^29 = 536870912
2^30 = 1073741824
2^31 = -2147483648

只要使用正确的转换符号

printf("2^%u = %u\n", i, x);

您正在使用 %i 格式说明符,它将其参数打印为带符号的 int

如果要打印为无符号,请使用 %u 格式说明符。

printf("2^%i = %u\n", i, x);

当您谈论 C(C++ 和许多其他编程语言)中整数值的符号时,您只是在谈论您如何解释某些数据。

您必须明白,存储在 unsigned int 中的只是位,与符号无关,它们在使用时表现为 "unsigned" 的事实仅仅是对值的解释。

因此,通过使用 %i 说明符,您将其视为有符号值,而不管它是如何声明的。尝试使用 %u 指定您要将它们视为 unsigned.

根据 printf 上的 C++ 参考页,在传递给 printf 的字符串中使用 %i 意味着相应的参数将被视为 signed 十进制整数。这意味着您的 unsigned int 将被转换为 signed int。 在 C++ 中,将无符号转换为有符号(和反转)只会改变解释,不会改变位值。因此,将最左边的位设置为 1 会使数字为负数,因为这就是它在带符号整数解释中对应的内容。 要达到预期的数量,请改用 %u 进行无符号整数解释。