2017-07-04 185 views
1

我写了这段代码来了解位移。令我惊讶的是,即使我宣称xunsigned int,输出包含一个负数,即当最左边的位被设置为1.我的问题:为什么?我认为unsigned int从来没有消极。每sizeof(x),x是4个字节宽。为什么一个声明为unsigned int的变量产生一个负值?

以下是代码片段:

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 
+3

因为您将它打印为有符号值。 –

+1

简短的回答是因为'printf()'没有做任何类型检查。 –

+0

https://stackoverflow.com/questions/14181691/why-does-printf-show-negative-values-for-unsigned-int –

回答

4

只要使用正确的转换符号

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

您使用的是%i格式说明,它将其参数打印为int

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

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

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

您必须明白,存储在unsigned int内的内容只是位,不管符号是什么,它们在使用时表现为“无符号”的事实仅仅是对值的解释。

因此,通过使用%i说明符,您将它视为有符号值,无论它是如何声明的。试用%u,它指定你想把它们当作unsigned

1

根据printf上的C++参考页,在传递给printf的字符串中使用%i表示相应的参数将被视为有符号的十进制整数。这意味着你的unsigned int将被转换为一个有符号的int。 在C++中,无符号签名(和反向)只会改变解释,而不是位值。因此,将最左边的位设置为1会使数字为负数,因为这与符号整数解释中的对应关系相同。 要实现预期的编号,请使用%u代替无符号整数解释。

+0

更好地使用C参考的C帖子比C++参考。 – chux

+0

@chux感谢您的建议。我明天会修好一段时间。 – xXliolauXx

相关问题