0

我不明白为什么 unsigned int 的输出对于以下代码是负数。就像一个有符号的整数。

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

输出是:

-2147483648

这是-2^31

4

8 回答 8

6

的格式说明符%d需要一个int,而不是一个unsigned int,因此代码具有未定义的行为。来自 C99 标准第7.19.6.1 节的 fprintf 函数

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

用于:%u_unsigned int

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

输出:

2147483648
于 2013-05-24T15:12:24.327 回答
4

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

请改用 %u。

于 2013-05-24T15:12:10.317 回答
1

用于%u输出无符号数:

printf("%u\n", yyy);
于 2013-05-24T15:12:18.407 回答
1

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

这样做的原因是,printf无法告诉任何额外参数是什么类型(它们以 a 形式给出va_list),因此程序员必须使用格式字符串提供该信息。当您然后提供%d时,printf将调用此:

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

并隐式地将您的 unsigned int 转换为有符号的。

于 2013-05-24T15:13:59.007 回答
0

整数以二进制补码格式存储。这意味着无法仅通过查看值来判断数字是有符号还是无符号。您必须告诉机器您希望它使用哪种表示并自己跟踪它。

在您的示例中,您告诉机器jjj未签名(用于类型检查),然后要求printf()通过%d在格式字符串中使用将其视为已签名(它无法获取类型信息)。如果要打印 unsigned int ,请%u改用。

于 2014-07-11T13:38:06.840 回答
0

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

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

使用错误的格式说明符printf是未定义的行为,C99 草案标准部分中7.19.6.1 对此进行了介绍。 fprintf 函数也涵盖printf了格式说明符说:

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

cppreference页面有一个很好的printf表格,指定了可用的格式说明符。

于 2013-05-24T15:12:23.953 回答
0

因为您将其打印为签名。改为使用%u

于 2013-05-24T15:12:53.417 回答
0

printf接受可变数量的参数。当您调用它时,编译器会尽职尽责地将它们全部放入堆栈中。因为它是 C,所以没有反射——printf不能随后推断它收到的东西的类型。在位级别上,您无法初步区分有符号整数和无符号整数或浮点数、适当小的结构、较大结构的一部分等。

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

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

于 2013-05-24T15:17:47.677 回答