解释类型转换如何在C中从int到short的位级别上工作

解释类型转换如何在C中从int到short的位级别上工作,c,math,logic,bit-manipulation,bit,C,Math,Logic,Bit Manipulation,Bit,如果2^31-1的二进制表示是01111111111111111111111111,那么当typecast转换为short时,该二进制数会发生什么变化?假设int为4字节,short为2字节 我写了一个测试程序,当typecast转换为short时,输出是-1。这是正确的吗?这是否意味着typecast to short只截断了16个最高有效位,留下11111111(带符号2的补码) 代码 #include <stdio.h> #include <stdlib.h> v

如果2^31-1的二进制表示是01111111111111111111111111,那么当typecast转换为short时,该二进制数会发生什么变化?假设int为4字节,short为2字节

我写了一个测试程序,当typecast转换为short时,输出是-1。这是正确的吗?这是否意味着typecast to short只截断了16个最高有效位,留下11111111(带符号2的补码)

代码

#include <stdio.h>
#include <stdlib.h>

void main()
{
        int x = sizeof(int);
        int y = sizeof(short);
        printf("%d, %d",x,y);

        int a = 2147483647;
        short b = (short)a;

        printf("\nad: %d",(int)a);
        printf("\nax: %x",(int)a);
        printf("\nau: %u",(int)a);

        printf("\nbd: %d",(int)b);
        printf("\nbx: %x",(int)b);
        printf("\nbu: %u",(int)b);
        printf("\n");
}

当您将
int
分配给
short
时,如果该值不能在
short
范围内表示([-2^15,2^15-1],在2的补码中),则结果是实现定义的

6.3.1.3有符号和无符号整数

将整数类型的值转换为其他整数类型时 除了_Bool,如果值可以用新类型表示,则 没有变化。否则,如果新类型是无符号的。。。否则 新类型已签名,且无法在其中表示值;任何一个 结果是实现定义或实现定义 信号升起

至于“实现定义”,这意味着行为取决于编译器、体系结构等。具体地说,正如您可能已经看到的,一个可能的结果是简单地丢弃高位。在这种情况下,这将导致
11111111111

另一个可能的结果是,它被“四舍五入”到范围内的最大值。在这种情况下,即
01111111
。但我记不清哪个实现是这样的


但无论如何,不要依赖于此。

C或任何其他语言中的任何整数都是以某些字节的形式存储的(如果使用32位C编译器,则C中有4个字节,通常
int
的大小取决于编译器),当您将其键入
short
并从内存中读取或分配给任何变量时,由于
short
指示编译器将值作为
short int
读取,因此只读取或分配较低的2个字节

在您的情况下,整数是二进制的
01111111111111111111111111
,因此,当类型转换为
short
时,它被读取为
11111111111111
(低2字节),这是
-1
的16位二进制表示(当然,如果它的
有符号short
,这是默认情况)

我的意思是,假设您在地址say
1234
存储了一个
int a=0x7fffffff
,那么
a
的内存表示形式将是:

 Memory Address:  1237     1236     1235     1234  
 Value:         01111111 11111111 11111111 11111111
当您将其作为
short
读取时,仅读取较低的2个字节(地址1235和1234)。
现在将它们读作
short
(或带符号的short)意味着您希望编译器将该数字的MSB视为符号位。因为
符号位=1
意味着它是一个负数,如果您知道2的补码格式(C编译器使用它来表示整数),那么二进制中的数字
11111111111
等于十进制中的
-1

另外,当您使用
%u
或打印
short int
值时,它将被视为
无符号
,MSB(这次)对幅值的贡献,而不是符号位

我还想补充一点:从
short
int
的类型转换
每当您像在中那样将
short
键入
int

short b = (short)a;
printf("\nbu: %u",(int)b);
符号位填充所有额外的高位,因此
11111111111111
变为
11111111111111111111
,在无符号十进制中为
4294967295

如果您尝试键入
01111111111111
而不是
11111111111
,那么它将被提升为
00000000000000000000111111111111
,因为符号位是
0


希望您能理解我的解释。

请您澄清一下“定义的实现”是什么意思。@JonSmith这意味着一个实现(编译器、体系结构等)可以决定它的功能。@JonSmith他基本上是指每个实现在许多方面都不同,这将定义这个问题的答案。不同的术语,如endianess或int和shortThanks,非常感谢。@JonSmith显然,是的,在您的特殊情况下。@H2CO3:谢谢您指出这一点!!我曾经在16位编译器上工作过,即使我犯了那个错误,我的错!!现在我已经改正了。妮特:这就是所谓的“铸造”。“类型转换”是指在电视或电影中看到同一演员扮演同一类型的角色。
short b = (short)a;
printf("\nbu: %u",(int)b);