分配负值时无符号变量的意外行为

时间:2013-11-14 16:11:25

标签: c printf output unsigned signed

以下是代码段:

unsigned short a=-1;
unsigned char b=-1;
char c=-1;
unsigned int x=-1;
printf("%d %d %d %d",a,b,c,x);

输出是这样的:

65535 255 -1 -1

有人可以分析一下吗?

2 个答案:

答案 0 :(得分:6)

您正在使用%d打印值,这是用于签名的数字。该值被“转换”为有符号数(它实际上保持相同的位,但第一位的解释不同)。

对于unsigned char和short - 它们也被转换为32位int,因此值适合它。

您是否使用%lld(并将值转换为long long,否则可能是未指定的行为),即使最后两个数字可能会被打印为无符号。

无论如何,使用%u表示无符号数字。

它是如何工作的?

位值255为11111111。如果将其视为无符号数,则为255.如果将其视为有符号数 - 它将为-1(第一位通常确定符号)。 将值传递给printf中的%d时,该值将转换为32位整数,如下所示:00000000000000000000000011111111。由于第一位为0,因此该值仅打印为255.它与short类似。

32位整数的情况不同。它会立即被赋予一个11111111111111111111111111111111值,在singed表示法中代表-1。由于您在printf中使用了%d,因此将其解释为-1

答案 1 :(得分:0)

基本上,您不应将负值分配给“无符号”变量。你试图在编译器上玩弄技巧,谁知道它会做什么。现在,“char n = -1;”没问题,因为“n”可以合理地接受负值,编译器知道如何对待它。