使用格式说明符 %d 和 %u 将 ~0 类型转换为 (unsigned int) 和 (unsigned short) 会为 short 产生相同的结果,但为 int 产生不同的结果
Type casting ~0 to (unsigned int) and (unsigned short) with format specifier %d and %u produces same result for short but different result for int
在计算 char、short、int 和 long 变量(有符号和无符号)的范围时,我求助于以下解决方案:
根据解决方案 1,我希望下面代码中的 (unsigned short)~0
输出 -1 和 65535,假设其行为与两个格式说明符的 (unsigned int)~0
代码相同。
// the two statements below produce different results
printf("Value of unsigned int is %d\n", (unsigned int)~0); // outputs -1
printf("Value of unsigned int is %u\n", (unsigned int)~0); // outputs 4294967295
// whereas, the two statements below produce the same result. Why?
printf("Value of short unsigned int is %d\n", (unsigned short)~0); // outputs 65535, expected -1
printf("Value short unsigned int is %u\n", (unsigned short)~0); // outputs 65535
为什么 (unsigned short)~0
和 (unsigned int)~0
的行为不同?
简单 - 因为您使用了错误的 printf 格式。
int main(void)
{
printf("Value of short unsigned int is %hd\n", (unsigned short)~0);
printf("Value short unsigned int is %hu\n", (unsigned short)~0);
printf("Value of short unsigned int is %hhd\n", (unsigned char)~0);
printf("Value short unsigned int is %hhu\n", (unsigned char)~0);
}
记得
使用 printf 系列函数时始终使用正确的格式!!!。使用错误的可能会导致未定义的行为
Why is there a difference in the behaviour of (unsigned short)~0
and (unsigned int)~0
?
这些表达式的行为是类似的。假设 int
类型的补码表示,每个计算其(无符号)类型的最大可表示值。
但是,printf
等可变参数函数的可变参数受默认参数提升的影响。这会影响 unsigned short
,如果 int
可以代表所有 unsigned short
值,则将其提升为 int
,就像您的示例中的情况一样(否则为 unsigned int
)。它不影响类型 int
或 unsigned int
或更宽的整数类型的参数。
所提供代码的关键问题是...
printf("Value of unsigned int is %d\n", (unsigned int)~0);
... 由于 %d
指令未正确类型匹配到相应的参数而表现出未定义的行为。 %d
必须与 签名 int
匹配,但您已将其与 unsigned int
相关联。实际上,UB 表现为将参数的位模式解释为 signed
int
而不是无符号的,但原则上,该程序可以在其范围内做任何事情电源。
请注意,由于类型不匹配,这也有未定义的行为:
printf("Value short unsigned int is %u\n", (unsigned short)~0);
指令 %hu
将是与相应实际参数的最佳匹配,但 %d
是可以接受的,因为前面提到的自动类型提升。 %u
不匹配 。然而,在这种情况下,显示的 UB 与您预期的行为相同——至少就输出所指示的而言。实际上,non-negative signed int
参数的位模式被解释为 unsigned int
.
在计算 char、short、int 和 long 变量(有符号和无符号)的范围时,我求助于以下解决方案:
根据解决方案 1,我希望下面代码中的 (unsigned short)~0
输出 -1 和 65535,假设其行为与两个格式说明符的 (unsigned int)~0
代码相同。
// the two statements below produce different results
printf("Value of unsigned int is %d\n", (unsigned int)~0); // outputs -1
printf("Value of unsigned int is %u\n", (unsigned int)~0); // outputs 4294967295
// whereas, the two statements below produce the same result. Why?
printf("Value of short unsigned int is %d\n", (unsigned short)~0); // outputs 65535, expected -1
printf("Value short unsigned int is %u\n", (unsigned short)~0); // outputs 65535
为什么 (unsigned short)~0
和 (unsigned int)~0
的行为不同?
简单 - 因为您使用了错误的 printf 格式。
int main(void)
{
printf("Value of short unsigned int is %hd\n", (unsigned short)~0);
printf("Value short unsigned int is %hu\n", (unsigned short)~0);
printf("Value of short unsigned int is %hhd\n", (unsigned char)~0);
printf("Value short unsigned int is %hhu\n", (unsigned char)~0);
}
记得
使用 printf 系列函数时始终使用正确的格式!!!。使用错误的可能会导致未定义的行为
Why is there a difference in the behaviour of
(unsigned short)~0
and(unsigned int)~0
?
这些表达式的行为是类似的。假设 int
类型的补码表示,每个计算其(无符号)类型的最大可表示值。
但是,printf
等可变参数函数的可变参数受默认参数提升的影响。这会影响 unsigned short
,如果 int
可以代表所有 unsigned short
值,则将其提升为 int
,就像您的示例中的情况一样(否则为 unsigned int
)。它不影响类型 int
或 unsigned int
或更宽的整数类型的参数。
所提供代码的关键问题是...
printf("Value of unsigned int is %d\n", (unsigned int)~0);
... 由于 %d
指令未正确类型匹配到相应的参数而表现出未定义的行为。 %d
必须与 签名 int
匹配,但您已将其与 unsigned int
相关联。实际上,UB 表现为将参数的位模式解释为 signed
int
而不是无符号的,但原则上,该程序可以在其范围内做任何事情电源。
请注意,由于类型不匹配,这也有未定义的行为:
printf("Value short unsigned int is %u\n", (unsigned short)~0);
指令 %hu
将是与相应实际参数的最佳匹配,但 %d
是可以接受的,因为前面提到的自动类型提升。 %u
不匹配 。然而,在这种情况下,显示的 UB 与您预期的行为相同——至少就输出所指示的而言。实际上,non-negative signed int
参数的位模式被解释为 unsigned int
.