C中的一个短变量的值

时间:2016-07-11 09:43:46

标签: c variables integer-overflow short variable-declaration

我有一个简短的程序,带有一个简短的变量声明:

    short int v=0XFFFD;  
    printf("v=%d\n",v);  
    printf("v=%o\n",v);  
    printf("v=%X\n",v);

结果是:

v=-3 ; v=37777777775 ; v=FFFFFFFD

我不明白如何计算这些值。我知道一个短变量可以保持-32768和32767之间的值,而值0XFFFD会导致溢出,但我不知道如何计算精确值,在这种情况下为-3。

另外,如果我的声明是v = 0XFFFD,为什么输出v =%X是FFFFFFFD?

顺便说一句,我使用Code:Blocks 16.01。

4 个答案:

答案 0 :(得分:4)

首先,short可以短至16位(编译器可能就是这种情况)。这意味着65533无法正确表示,分配溢出,它包装到-3(因为short int是带符号的短整数)。但你已经知道了。

其次,当作为参数发送到printf时,short int会自动转换为int,但v包含-3的{​​{1}}发送到printf的值。

%o%X次转化期望unsigned int并不是您所提供的。{1}}。这意味着未定义的行为(理论上),但在实践中它是可以预测的。这意味着-3的位模式被解释为无符号整数,而在32位机器上恰好是0xFFFFFFFD

答案 1 :(得分:2)

如果此机器上的short是2个字节,那么0x8000是该类型所持有的最大负值的二进制表示,即-32768。由于事物的设计方式,下一个数字由相应的下一个比特模式表示,即:

biggest negative value = 0x8000 = -32768
0x8001 = biggest negative value + 1 = -32767
0xFFFF = biggest negative value  + 0x7FFF = -1
0xFFFE = biggest negative value  + 0x7FFE = 0xFFFF - 1 = -2
0xFFFD = biggest negative value  + 0x7FFD = 0xFFFF - 2 = 0xFFFE - 1 = -3

答案 2 :(得分:1)

数字0xFFFD不会导致溢出,因为-3完全在-32768到32767的范围内。

任何短变量都是带符号的二进制补码,-3(十进制)的结果与任何二进制补码值一样计算。因此,要了解如何计算-3(十进制)的结果,请查看youtube或任何相关教科书中的许多教程。

在将数字作为int打印之前,您的编译器似乎将短变量的隐含类型转换为int值。要做到这一点,它必须执行所谓的符号扩展,因为它必须用16位带符号的二进制补码制作一个32位带符号的二进制补码。就像任何十进制数一样,在数字之前存在无限量的零(例如34 = 0034),在负的二进制补码数之前存在无限数量的1。因此编译器将最有效位复制到左侧。 makin 0xFFFFFFFD超出0xFFFD和37777777775(oct)超出177775(oct),即(00)1 111 111 111 111 101(bin)。

我希望这些信息可以帮到你。

答案 3 :(得分:1)

  

但我不知道如何计算确切的值,在这种情况下为-3。

在计算机中表示整数的最常用方法是2的补码。

如果你有一个n位整数,你会得到这样的十进制值:

十进制值= - b n-1 2 n-1 + b n-2 2 n-2 + ... + b 1 2 1 + b 0 2 0 其中b i 是位号i的值。

在您的情况下,您有一个16位变量。十六进制表示为0xfffd,二进制为1111.1111.1111.1101

插入公式即可:

十进制值= - 1 * 2 15 + 1 * 2 14 + ... + 1 * 2 2 + 0 * 2 1 + 1 * 2 0 = - 3

有关此主题的详情,请参阅https://en.wikipedia.org/wiki/Two%27s_complement