直奔主题,先上一道例题,大家思考一下,为什么答案是这个样子!
下面是linux系统的输出结果:
(1)几点基础注意
变量定义:是在内存中确定变量的位置和大小,即:定义时分配内存。例如:int a;
赋值:是在擦除对象当前值,并用新的值代替。例如:a = 2;
初始化:先分配内存,再进行赋值操作。
(2)原码、反码、补码
机器数:一个数在计算机中是以二进制形式存储的,这个数就是机器数。机器数的高位是符号位,正数为0,负数为1。
真值:除了符号位,其余位对应的值是真值。
例如:1000 0001 真值是-1,不是129。
原码:符号位加上真值的绝对值。
例如:[+1]原码:0000 0001,[-1]原码:1000 0001
反码:正数的反码是其本身,负数的反码是在原码的基础上,符号位不变,其余为取反。
例如:[+1]反码:0000 0001,[-1]反码:1111 1110
补码:正数的补码是其本身,负数的补码是其反码加1。
例如:[+1]补码:0000 0001,[-1]补码:1111 1111
整型数据在内存中是以补码的形式存储的。要得到负数的真值需要得到原码。补码的补码就是其原码。
(3)%d和%x
%d:是有符号位输出,那么首先看补码的符号位,是正是负;是正,补码就是原码;是负,补码的补码才是原码,也才是输出结果。
%x:是16进制数输出,输出时是4字节,32位。如果不够4字节要进行扩展,并且高位全部用符号位来填充。
(4)分析计算
char a = 247;
系统分配1个字节内存大小,里面存储正数247的补码,即:1111 0111(正数的补码就是原码)。
%d输出:首先看高位,变量a是char类型,8位,高位是1,代表是负数,现在内存中存储的是其补码,要得到输出的原码,需要得到现在补码的补码(补码的补码是原码),即: 1111 0111 ------ 反码:1000 1000 ------ 补码:1000 1001,此时的补码就是真正的原码:-9,所以输出结果就是-9。
%x输出:现在存储的是:1111 0111,即:0xf7,要注意%x是4字节输出,此时是char类型,输出时要进行默认转换,转换成32位,并且高位全部用符号位填充,即:1111 1111 1111 1111 1111 1111 1111 0111,是0xff ff ff f7。