我不明白为什么unsigned int的输出对于以下代码是否定的。 就像签名的int。
uint32_t yyy=1<<31;
printf("%d\n",yyy);
输出结果为:
-2147483648
是-2^31
。
答案 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
。