我不明白为什么 unsigned int 的输出对于以下代码是负数。就像一个有符号的整数。
uint32_t yyy=1<<31;
printf("%d\n",yyy);
输出是:
-2147483648
这是-2^31
。
我不明白为什么 unsigned int 的输出对于以下代码是负数。就像一个有符号的整数。
uint32_t yyy=1<<31;
printf("%d\n",yyy);
输出是:
-2147483648
这是-2^31
。
的格式说明符%d
需要一个int
,而不是一个unsigned int
,因此代码具有未定义的行为。来自 C99 标准第7.19.6.1 节的 fprintf 函数:
如果任何参数不是相应转换规范的正确类型,则行为未定义。
用于:%u
_unsigned int
uint32_t yyy=1u<<31;
printf("%u\n",yyy);
输出:
2147483648
这是因为您的 printf 参数,如 %d,正在将您的数字隐式转换为 int。
请改用 %u。
用于%u
输出无符号数:
printf("%u\n", yyy);
正如许多人所说,使用%u
标识符。
这样做的原因是,printf
无法告诉任何额外参数是什么类型(它们以 a 形式给出va_list
),因此程序员必须使用格式字符串提供该信息。当您然后提供%d
时,printf
将调用此:
int val;
val = va_arg(va_list, int);
并隐式地将您的 unsigned int 转换为有符号的。
整数以二进制补码格式存储。这意味着无法仅通过查看值来判断数字是有符号还是无符号。您必须告诉机器您希望它使用哪种表示并自己跟踪它。
在您的示例中,您告诉机器jjj
未签名(用于类型检查),然后要求printf()
通过%d
在格式字符串中使用将其视为已签名(它无法获取类型信息)。如果要打印 unsigned int ,请%u
改用。
您需要使用unsigned int
格式说明符:
printf("%u\n",yyy);
^^
使用错误的格式说明符printf
是未定义的行为,C99 草案标准部分中7.19.6.1
对此进行了介绍。 fprintf 函数也涵盖printf
了格式说明符说:
如果转换规范无效,则行为未定义。248)如果任何参数不是相应转换规范的正确类型,则行为未定义。
cppreference页面有一个很好的printf
表格,指定了可用的格式说明符。
因为您将其打印为签名。改为使用%u
。
printf
接受可变数量的参数。当您调用它时,编译器会尽职尽责地将它们全部放入堆栈中。因为它是 C,所以没有反射——printf
不能随后推断它收到的东西的类型。在位级别上,您无法初步区分有符号整数和无符号整数或浮点数、适当小的结构、较大结构的一部分等。
这就是为什么您还必须提供格式字符串的原因。它告诉printf
从堆栈中读取的类型和顺序。它完全取决于该格式字符串,无法验证它。
因此,根据已经发布的单行答案,如果您告诉它将字段解释为已签名数量,那么它将被打印为已签名数量。