接上回,让我们看看下个例题:

例4:首先,我们先写出-20的原码反码补码
原码:10000000000000000000000000010100
反码:11111111111111111111111111101011
补码:11111111111111111111111111101100
10的原码反码补码:
00000000000000000000000000001010
两个补码相加:
11111111111111111111111111101100
00000000000000000000000000001010
11111111111111111111111111110110(结果的补码)
因为输出结果是%d,是输出有符号的十进制数,所以要先将结果转化为原码,然后再输出。
(结果的补码)11111111111111111111111111110110
(结果的反码)11111111111111111111111111110101
(结果的原码)10000000000000000000000000001010 = -10
所以最终输出结果为-10.

例5:

题中条件为(i=9;i>=0;i--)
解题思路:因为题中的i为int型且为无符号数,所以i永远都大于0,且打印要求为%u无符号十进制数。当i一直--,直到i<0时,由int型的范围可知,-1将被自动转化为一个很大很大的数(类似上一节char中的那个循环圈),所以i>=0,无限循环。因此打印结果为 9 8 7 6 5 4 3 2 1 0,很大的数......

解题思路:有符号的char类型的范围为-128——127,共256个字符。strlen遇到‘\0'自动停止,0的ASCLL码值为'\0'。
由题意,char中存储的值为-1到-1000,由于char类型最多只能存256个字符,因此当存储的数值大于127或小于-128时,会被自动转化为-128到127中的值。例如,这题a[i]等于-128时,下一位为-129,但char类型中并没有-129,所以根据上部分的那个循环,将a[i]自动变为127,直到遇到'\0'才停止,因此最终结果为255。
例7:

解题思路:无符号的char只能存0到255的数,所以当i=255时,i++之后便又开始了轮回,因此结果为无限循环打印hello world。
例8:

1E10表示1×10^10。

让我们一起看看这串代码:
首先定义一个int n ,将n的地址放入float*指针中,再将&n强制类型转换成float型。按照我们的惯性思维,第一个printf应该打印出9,第二个应该9.000000,第三个应该是9,第四个是9.000000。那么结果是否是这样呢?让我们看看结果。

看来结果不如我们所愿,那这是为什么呢?这就要提到float在内存中的存储。

如上图,任何一个二进制浮点数都可以写成(-1)^s *M*2^E
例如:5.5
写成以上表达形式就是 ( 101.1 = 5.5(.1 = 1*2^-1 = 0.5))
(-1)^0 *1.011*2^2
s = 0;
M = 1.011;
E = 2;

单精度浮点数存储模型:第一位符号位(s),后面8为给E,最后23位给M
双精度浮点数存储模型:第一位符号位,后面11为给E,最后52位给M。
特别注意:E也有自己的存储形式

简单来说,对于8位的E,中间数为127.对于11位的E,中间数为1023.
特别地:M在储存时只保留小数部分,如1.01,只保存01,自动舍弃1,最后再添上即可。
上面的5.5用二进制形式则表示为:
0 10000001 011 000000000000000000000
s E M(自动舍弃1) (因为M占23个bit位,所以后面自动补齐0)
将以上二进制转为16进制,查看其在内存中的存储:
0x40b00000

接下来是E的几种特殊形式:

记住即可。
文章的最后,让我们再次计算刚开始的那道题目:

首先第一个打印int n = 9;打印有符号十进制整形,结果还是9
第二个,首先写出9的补码0 00000000 00000000000000000001001
E为全0
所以还原为浮点数表达式:(-1)^0*0.00000000000000000001001*2^-126
打印结果为0.
第三个,首先将9.0写成浮点数表达式:
(-1)^0*1.001*2^3
0 10000010 00100000000000000000000
符号位0表示正数,所以原码反码补码相同,直接打印即可,结果为1091567616
第四个结果为9.0
因此,若打印的值为整形,且以整形的方式打印,则没问题。若以浮点数方式打印,则有问题,反过来也一样,因此,浮点型与整形在内存中的存储方式是不同的。