给定,
unsigned short y = 0xFFFF;
当我打印时
printf("%x", y);
我得到:0xFFFF;
但是当我打印时
printf("%x", (signed short)y);
我得到:0xFFFFFFFF
整个程序如下:
#include <stdio.h>
int main() {
unsigned short y = 0xFFFF;
unsigned short z = 0x7FFF;
printf("%x %x\n", y,z);
printf("%x %x", (signed short)y, (signed short)z);
return 0;
}
当我们将低字节数据类型转换为高字节数据类型时,会发生符号扩展,但这里我们将short类型转换为有符号short。 在这两种情况下, sizeof((signedshort)y) 或 sizeof((signedshort)z) 都会打印 2 个字节。如果符号位为零(如 0x7fff 的情况),则剩余 2 个字节。 非常感谢任何帮助!
最佳答案
第一个 printf
的输出正如预期的那样。第二个printf
产生未定义的行为。
在 C 语言中,当传递小于 int
的值时作为可变参数,该值始终隐式转换为类型 int
。不可能物理地传递 short
或char
可变参数。隐式转换为 int
是您的“符号扩展”发生的地方。
因此,您的printf("%x", y);
相当于 printf("%x", (int) y);
。传递给 printf
的值是 0xFFFF
类型 int
。从技术上讲,%x
格式需要 unsigned int
参数,但非负 int
值也还可以(除非我遗漏了一些技术细节)。输出是0xFFFF
.
转换为int
第二种情况也会发生。 IE。你的printf("%x", (signed short) y);
相当于 printf("%x", (int) (signed short) y);
。 0xFFFF
的转换至(signed short)
是实现定义的,因为 0xFFFF
显然超出了 signed short
的范围在您的平台上。但很可能它会产生负值( -1
)。当转换为int
时它产生相同的 int
类型的负值(同样,对于 32 位, -1
表示为 0xFFFFFFFF
)。进一步的行为未定义,因为您传递的是负 int
格式说明符的值 int
,这需要%x
争论。使用unsigned int
是非法的带有负面%x
值。
换句话说,正式是您的第二个 int
打印不可预测的垃圾。但实际上上面解释了 printf
在哪里来自。
关于c - 短签扩展查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26392736/