C中的unsigned int表现为负数

时间:2013-05-24 15:11:07

标签: c printf undefined-behavior

我不明白为什么unsigned int的输出对于以下代码是否定的。 就像签名的int。

  uint32_t yyy=1<<31;
  printf("%d\n",yyy);

输出结果为:

  

-2147483648

-2^31

8 个答案:

答案 0 :(得分:6)

%d的格式说明符需要int,而不是unsigned int,因此代码具有未定义的行为。从C99标准部分 7.19.6.1 fprintf函数

  

如果任何参数不是相应转换规范的正确类型,则行为未定义。

%u使用unsigned int

uint32_t yyy=1u<<31;
printf("%u\n",yyy);

输出:

2147483648

答案 1 :(得分:4)

这是因为你的printf参数,如%d,是隐式地将你的数字转换为int。

改用%u。

答案 2 :(得分:1)

使用%u输出无符号数字:

printf("%u\n", yyy);

答案 3 :(得分:1)

正如许多人所说,使用%u标识符。

原因是,printf无法告知任何额外参数的类型(它们是va_list),因此程序员必须提供该信息使用格式字符串。当您提供%d时,printf会将其称为:

int val;
val = va_arg(va_list, int);

并隐式将unsigned int转换为signed。

答案 4 :(得分:0)

您需要使用unsigned int格式说明符:

printf("%u\n",yyy);
        ^^

使用printf的错误格式说明符是未定义的行为,C99草案标准部分7.19.6.1 fprintf函数中涵盖了该行为,其中也包含{{1}关于格式说明符说:

  

如果转换规范无效,则行为为   undefined。 248)如果任何参数不是正确的类型   相应的转换规范,行为未定义。

printf的{​​{3}}页面有一个很好的表格,用于指定可用的格式说明符。

答案 5 :(得分:0)

因为您要将其打印为已签名。请改用%u

答案 6 :(得分:0)

printf采用可变数量的参数。当你调用它时,编译器将尽职尽责地将它们全部放在堆栈中。因为它是C,所以没有反映 - printf无法随后推断它收到的事物的类型。在位级别,你不能初步证明无符号整数或浮点数的有符号整数,适当小的结构,更大结构的一部分等。

这就是为什么你还必须提供格式字符串。它告诉printf从堆栈中读取什么类型以及以什么顺序读取。它完全取决于格式字符串,无法验证它。

因此,根据已发布的单行答案,如果您告诉它将字段解释为签名数量,那么它将被打印为签名数量。

答案 7 :(得分:0)

整数以Two's Complement格式存储。这意味着只能通过查看值来判断数字是已签名还是无符号。您必须告诉机器您希望它使用哪种表示形式并自行跟踪。

在您的示例中,您告诉计算机jjj是无符号的(用于类型检查),然后让printf()在格式字符串中使用%d将其视为已签名(它可以得到类型信息)。如果要打印unsigned int,请改用%u