最近被这样一道题弄哭,查了好多资料,才勉强弄懂,废话不多说,请看题。
#include "stdio.h"
void main()
{
int8 a = -1;
uint16 b;
printf("%d",b);
}
A.0
B.1
C.255
D.65535
A.0
B.1
C.255
D.65535
要弄清楚这个问题,我们首先要明确的是在计算机中,数据是以二进制补码的形式保存的,而显示给我们形态的是经过计算机转换而来的。 首先,我们来看看原码,反码,补码的关系: 以8位二进制为例,正数的原码、反码、补码相同, 负数的反码为:除符号位外,原码各位取反,反码加1,得负数的反码. 下面就对于原码,反码,补码详细分析一下: 原码:将一个整数,转换成二进制,就是其原码。如单字节的5的原码为:0000 0101;-5的原码为1000 0101。 反码:正数的反码就是其原码;负数的反码是将原码中,除符号位以外,每一位取反。如单字节的5的反码为:0000 0101;-5的反码为1111 1010。 补码:正数的补码就是其原码;负数的反码+1就是补码。如单字节的5的补码为:0000 0101;-5的原码为1111 1011。 在计算机中,正数是直接用原码表示的,如单字节5,在计算机中就表示为:0000 0101。 负数用补码表示,如单字节-5,在计算机中表示为1111 1011。 所以回到刚开始的题目,-1(8位有符号整形)的原码为10000001,当其被强制转换为无符号16位整形时,-1的原码转换为1000000000000001(扩展原则为符号位不变,增加的位用0代替),则其补码为0xFFFF(1111111111111111),由于这串二进制的数据类型定义为无符号,计算机把这段补码看成是正数的补码,由前面的论述可知,正数的补码即为原码(of course,无符号数当然都是正数了),即计算机输出显示给我们看到的这串数据即为0xFFFF(16进制),所以输出的结果也就是选项D了。 至于其他的,我总结如下: 同理可得(哈哈哈), 本人也是非科班出身的C语言爱好者,如有不正确的地方,请评论区指教。
以8位二进制为例,正数的原码、反码、补码相同, 负数的反码为:除符号位外,原码各位取反,反码加1,得负数的反码. 下面就对于原码,反码,补码详细分析一下: 原码:将一个整数,转换成二进制,就是其原码。如单字节的5的原码为:0000 0101;-5的原码为1000 0101。 反码:正数的反码就是其原码;负数的反码是将原码中,除符号位以外,每一位取反。如单字节的5的反码为:0000 0101;-5的反码为1111 1010。 补码:正数的补码就是其原码;负数的反码+1就是补码。如单字节的5的补码为:0000 0101;-5的原码为1111 1011。 在计算机中,正数是直接用原码表示的,如单字节5,在计算机中就表示为:0000 0101。 负数用补码表示,如单字节-5,在计算机中表示为1111 1011。 所以回到刚开始的题目,-1(8位有符号整形)的原码为10000001,当其被强制转换为无符号16位整形时,-1的原码转换为1000000000000001(扩展原则为符号位不变,增加的位用0代替),则其补码为0xFFFF(1111111111111111),由于这串二进制的数据类型定义为无符号,计算机把这段补码看成是正数的补码,由前面的论述可知,正数的补码即为原码(of course,无符号数当然都是正数了),即计算机输出显示给我们看到的这串数据即为0xFFFF(16进制),所以输出的结果也就是选项D了。 至于其他的,我总结如下: 同理可得(哈哈哈), 本人也是非科班出身的C语言爱好者,如有不正确的地方,请评论区指教。