将unsigned short int初始化为有符号值

时间:2012-10-22 09:06:00

标签: c gcc unsigned-integer output

#include<stdio.h>
int main()
{
unsigned short a=-1;
printf("%d",a);
return 0;
}
  1. 这给我输出65535。为什么?
  2. 当我增加a的负值时,输出为(2 ^ 16-1 =)65535-a。
  3. 我知道unsigned short int的范围是0到65535。 但是为什么在0到65535的范围内旋转。内部会发生什么?

    #include<stdio.h>
    int main()
    {
    unsigned int a=-1;
    printf("%d",a);
    return 0;
    }
    
  4. 输出为-1。
  5. %d用于有符号十进制整数,而不是为什么它不遵循打印其(int)范围的最大值的规则。
  6. 为什么此部分的输出为-1?
  7. 我知道%u用于打印无符号十进制整数。

    为什么第二个代码中的行为未定义,而不是第一个。

    这是我在gcc编译器中编译的。这是一个C代码 在我的机器上,short int为2个字节,int的大小为4个字节。

2 个答案:

答案 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+1a是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位”将使您读起来像'最重要的位')。感谢。