如何解决使用格式说明符%d和%u将类型转换〜0转换为unsigned int和unsigned short,对于short产生相同的结果,但对于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
的行为有所不同?
解决方法
为什么
(unsigned short)~0
和(unsigned int)~0
的行为有所不同?
这些表达式的行为是相似的。假设类型为int
的二进制补码表示形式,则每个计算出其(无符号)类型的最大可表示值。
但是,可变参数(例如printf
)的可变参数要接受默认参数提升。这会影响unsigned short
,如果int
可以代表所有int
的值,则将其提升为unsigned short
,就像您的示例一样(否则为unsigned int
)。它不会影响int
或unsigned int
类型的参数,也不会影响更宽的整数类型。
所提供的代码的关键问题是...
printf("Value of unsigned int is %d\n",(unsigned int)~0);
...由于%d
伪指令的类型与相应的自变量不正确匹配,因此表现出未定义的行为。 %d
必须与 signed int
匹配,但是您已将其与unsigned int
关联。实际上,UB表现为将参数的位模式解释为好像是signed
int
而不是无符号的,但是原则上,程序可以在其内部完成任何操作力量。
请注意,由于类型不匹配,这也具有未定义的行为:
printf("Value short unsigned int is %u\n",(unsigned short)~0);
伪指令%hu
将是与相应实际参数的最佳匹配,但是%d
可以接受,因为上述自动类型提升。 %u
不匹配。但是,在这种情况下,显示的UB与您预期的行为相同-至少在输出指示的范围内。实际上,非负signed int
参数的位模式已被解释为unsigned int
。
简单-因为您使用了错误的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系列功能时始终使用正确的格式!!!使用错误的行为可能导致不确定的行为
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。