数据在内存中的存储
数据类型介绍
c语言的类型分为两类
- 内置类型
char short int long等
- 自定义类型
类型有什么意义呢?
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角
类型的基本归类
浮点型家族
float
double
空类型:void
如果不需要形参,也可以使用void
整形在内存中的存储
要知道上面的结果,需要先了解原码反码补码
计算机中的有符号数有三种表示方法,并且三种表示方法各不相同,其中有符号数有分为正负,正数是完全相同的,负数则不是;而对于无符号数,三种表示方法都相同
1.原码
直接将数字翻译成二进制就行
2.反码
符号位不变,剩余位取反
3.补码
反码+1
问题来了,内存中存一个整数的时候,是存的原码反码还是补码呢?是补码
可以看到,因为正数的原码反码补码相同,所以用十六进制表示看不出存的是哪个码;但是负数就可以看出,打开调试窗口的监视,可以看到b在内存中存储的是
不难发现,这其实就是b的补码的十六进制表示,所以可以得出正数在内存中是以补码形式存储的
为什么内存中是用补码来存储的呢?
cpu只有加法器,那在计算减法的时候,用的什么码呢?
这里就不得不佩服这帮科学家了
当你用原码计算1-1时,会发现错误;但是用补码进行计算的时候,就会产生正确的结果,正是因为有了补码的出现,才让这些运算更加正确,所以在内存中是用补码来存储的
在解决了上面的问题之后,你会发现,你算出来的十六进制和内存中存的好像顺序不一样,是倒着存的,这就涉及到了大小端存储
大小端介绍
其实通俗来讲,我们人读的最多的就是大段,反过来就是小端
假设有一个0x11223344,这里11是高位,44是低位
如果把高位放到了低地址就是大端
为什么会有大端小端之分呢
小练习
注意在内存中存放的是补码,所以不管是什么类型,都放的补码。先算出补码,之前提到过,整型提升,所以先提升为32位,再根据char一个字节再截断
放的方式一样,但是拿出来解析就不一样了
最后打印a=%d,是整形,所以要进行整形提升,如何提升,按照原符号位进行提升
-
char 是有符号的char 所以高位是符号位,提升补1,变成了32位全1,但还是补码,如果要打印原码的话还得算原码,还是-1
-
signed char跟char其实是一回事
-
unsigned char高位不是符号位,对于无符号位的提升高位补0,再用%d进行打印的时候发现高位是0,看成正数,正数的原码反码补码相同
按下面的步骤来
1 先写成二进制序列,写32位的原码,再算补码,再截断8位(因为是char型)
最后截断8位是1000 0000 (此时还是补码)
2 进行整形提升,整形提升看a的类型,a是char类型,有符号的,按符号位提升,全补1,注意此时还是补码
3 要看清最后输出格式
%u-----是打印十进制的无符号数字
%d-----是打印十进制的有符号数字
本题是打印无符号数字,所以认为原码反码补码相同,所以2步中得到的补码不用再转换成原码
跟第二题一样
先写出i和j的补码,由于j是无符号数,原码反码补码相同,所以就不用转换
得到的结果仍然是补码,但是以%d来进行打印,打印的是原码,所以再计算得到原码
最后代码死循环,因为当i = -1时,是个很大的数字,而又被看成无符号数,所以会一直这样进行下去
最后为255
由于unsigned char能表示的范围时0-255,所以条件恒成立,是死循环。
浮点型在内存中的存储
见下一讲