整型在内存中的存储

 前言:

本文章旨在从例题中加深对整型在数据中的存储的相关知识的理解。

首先我们需要明确整型在内存中都是以补码的形式进行计算

例1:

整型在内存中的存储_第1张图片
解析:

首先我们需要明确整型在内存中都是以补码的形式进行计算。

接着将一个整型类型的数据存储在char类型,需要进行截断(直接截断整型的后8位)。

所以存储在a中的补码就是8个1。同理目前在a,b,c中存储的都是8个1.

然后是以%d十进制的形式打印,然而a是一个char类型的变量,所以需要整型提升。

TIP:

char类型不能确定是有符号还是无符号,根据编译器自己。

如何进行整型提升?
有符号位的整型提升就是根据符号位进行提升,而无符号位的直接补0。

综上所述,signed char b,b此时内存中补码存储就是全1,又因为-1的补码就是全1,即b的打印结果就是-1.

而无符号的char整型提升后有8个1,又因为无符号数的原码反码补码相同,所以c的十进制打印结果就是255.

综上,a,b的打印结果都是-1,c的打印结果是255

总结:

因为将整形数据存储在char类型中,所以先进行截断,接着%d打印又需要整型提升!

例2

整型在内存中的存储_第2张图片
解析:

-128的原码:

10000000000000000000000010000000//原码

11111111111111111111111101111111//反码

11111111111111111111111110000000//补码

存储在char类型中,进行截断,只留后面8位。

所以此时存储在a中的补码就是

10000000

又因为%u打印,所以需要整型提升,char类型没有unsigned表明,默认都是有符号的,所以此时10000000整型提升就按符号位。

11111111111111111111111110000000//整型提升完毕。

又因为无符号数,所以原码反码补码相同,即二进制位的表达形式就是上述式子,然后再转换为十进制即可。

总结:

最后整型提升打印函数中%d和%u的区别

因为我们都是对补码进行操作,最后一步如果%u那么原码反码补码相同,不用转换,如果是%d,还需要将补码转换为原码进行打印输出。

例3

整型在内存中的存储_第3张图片
解析:

00000000000000000000000010000000//128的原码

01111111111111111111111101111111//128的反码

01111111111111111111111110000000//128的补码

又因为存储在char类型中,所以进行截断。

10000000//阶段之后的a

接下来的步骤跟上一道题一模一样,所以结果也一样。(因为存在内存中的值都是一样的)

例4:

整型在内存中的存储_第4张图片
解析:

首先将两个数的补码表示出来,然后利用补码计算。

10000000000000000000000000010100//i的原码

11111111111111111111111111101011//i的反码

11111111111111111111111111101100//i的补码 -------(1)

00000000000000000000000000001010// j的原码反码补码-------(2)

(1)+(2)得到

11111111111111111111111111110110//i+j的补码

11111111111111111111111111110101//i+j的反码

10000000000000000000000000001010//i+j的原码

所以最终屏幕上的输出结果就是-10

总结:

无符号和有符号是可以相加的,他们都是存储在内存中,所以需要补码计算,最后打印函数输出是原码的形式。

例5:

整型在内存中的存储_第5张图片
解析:

首先是死循环打印,因为i是一个无符号整型是恒大于0的,当i变成-1时,无符号整型补码形式就是全1,一个非常大的数,接着再-1.

TIP:

如果把i变量的类型改为int,则输出结果就是9~0.因为循环语句的判断条件卡住了。

例6:

整型在内存中的存储_第6张图片
解析:

首先我们从数学的角度理解在数组a里面存储的应该是-1~-1000,但是又因为a是一个char类型的数组,而一个char类型的数组只能存的下-128~127,所以在数组真实的存储情况是这样

-1,-2,…………,-128,127,126……1,0,-1进行一个循环。

整型在内存中的存储_第7张图片

 注意上图的10000000表示-128,是因为10000000是负数的补码,需要再变成原码

又因为strlen计算字符串长度到‘\0’之前出现字符的个数,而\0的ASCII码值就是0,因此当遇到0就结束,所以最终的输出结果就是128+127=255

例7

整型在内存中的存储_第8张图片
解析:

输出结果是死循环打印hello world

因为unsigned char取值范围是0~255(11111111),而循环判断条件是小于等于255,所以恒成立。

你可能感兴趣的:(C语言,c语言,开发语言)