#include<stdio.h>
int main()
{
unsigned short a=-1;
printf("%d",a);
return 0;
}
我知道unsigned short int的范围是0到65535。 但是为什么在0到65535的范围内旋转。内部会发生什么?
#include<stdio.h>
int main()
{
unsigned int a=-1;
printf("%d",a);
return 0;
}
我知道%u用于打印无符号十进制整数。
为什么第二个代码中的行为未定义,而不是第一个。
这是我在gcc编译器中编译的。这是一个C代码 在我的机器上,short int为2个字节,int的大小为4个字节。
答案 0 :(得分:3)
在您的实现中,short是16位,int是32位。
unsigned short a=-1;
printf("%d",a);
首先,-1转换为unsigned short
。这导致值65535.有关精确定义,请参阅标准“整数转换”。总结一下:该值取模USHORT_MAX+1
。
此值65535已分配给a
。
然后对于使用varargs的printf
,该值将被提升回int
。 varargs从不传递小于int的整数类型,它们总是转换为int。这导致值65535,打印出来。
unsigned int a=-1;
printf("%d",a);
第一行,与之前相同但模UINT_MAX+1
。 a
是4294967295。
对于printf,a
作为unsigned int
传递。由于%d
需要int
,因此C标准未定义该行为。但是你的实现似乎已经重新解释了无符号值4294967295,它已经设置了所有位,就像一个带有全位设置的有符号整数,即二进制补码值-1。这种行为很常见,但不能保证。
答案 1 :(得分:0)
对变量类型的存储量进行变量赋值(例如,short为2个字节,int为4个字节,通常为32位硬件)。变量的符号在赋值中并不重要。这里重要的是你将如何访问它。分配给“短”(有符号/无符号)时,将值分配给“2字节”内存。现在,如果要在printf中使用'%d',printf会将其视为'整数'(硬件中为4个字节),两个MSB将为0,因此您得到[0 | 0](两个MSB)[ - 1](两个LSB)。由于新的MSB(由printf中的%d引入,迁移),您的符号位隐藏在LSB中,因此printf认为它是无符号的(由于MSB为0),您会看到正值。要在此处获得否定,您需要在第一种情况下使用'%hd'。在第二种情况下,您分配了“4字节”存储器,MSB在分配期间得到其SIGN位“1”(表示负数),因此您在printf的'%d'中看到负数。希望它解释。如需更多说明,请对答案进行评论。
注意:我使用'MSB'来表示高阶字节。请根据上下文阅读(例如,“SIGN位”将使您读起来像'最重要的位')。感谢。