0
#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 代码在我的机器上 sizeof short int 是 2 个字节,而 int 的大小是 4 个字节。

4

2 回答 2

3

在您的实现中,short 是 16 位,int 是 32 位。

unsigned short a=-1;
printf("%d",a);

首先, -1 转换为unsigned short. 这导致值 65535。有关精确定义,请参见标准“整数转换”。总结一下:取值取模USHORT_MAX+1

此值 65535 分配给a

然后对于printf使用可变参数的 ,该值被提升回int。varargs 从不传递小于 int 的整数类型,它们总是被转换为 int。这将产生值 65535,并打印出来。

unsigned int a=-1;
printf("%d",a);

第一行,与之前相同,但取模UINT_MAX+1a是 4294967295。

对于 printf,a作为unsigned int. 由于%d需要intC 标准未定义行为。但是您的实现似乎已将所有位设置为无符号值 4294967295 重新解释为具有所有位设置的有符号整数,即二进制补码值 -1。这种行为很常见,但不能保证。

于 2012-10-22T09:30:30.827 回答
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 bit' 会让你读起来像'Most Significant Bit')。谢谢。

于 2012-10-22T09:30:12.833 回答