内存中数据的存储情况

数据类型

1. 内置类型

内存中数据的存储情况

  • 类型的意义

  • 1.使用了这个类型开辟的内存空间的大小(大小决定了使用范围)

  • 2.以什么样的视角来看待这个内存空间(如int a=0,那就认为这个0是整数0)

  • 类型的基本归类

  • 整形
    内存中数据的存储情况(方块里的那些是可以省略掉的,signed:有符号的)
    像char c=‘w’,到底是signed char c 还是 unsigned char c是不确定的,这取决于编译器
    但除了char 其他的像 int、char等,都是signed有符号的。
    另外注意,signed的二进制的最高位是符号位,而unsigned的最高位是有效位

  • 浮点型
    float和double

  • 自定义类型(即构造类型)
    内存中数据的存储情况
    对于数组类型来说,如 int arr[10]
    arr就是数组名,把arr去掉,int [10]就是类型,所以 int 和 [10] 去掉一个就改变了这个数组的类型。

  • 空类型

  • 内存中数据的存储情况

整形在内存中的存储

内存中数据的存储情况可以说明:数据在内存中存储的时候用的是二进制,但vs编译器在展示内存的时候为了方便,用的是十六进制
内存中数据的存储情况可以看出c是倒着存的

那他们在内存中是怎么存储的呢?
内存中数据的存储情况
(正数的原码反码补码相同)
(无符号数和正整数是一样的)

内存中数据的存储情况(这就是-1的原码反码补码)
补码如果换算成十六进制的话,就是四个为一组进行换算,所以-1的十六进制就是八个f。根据上面的那些图,可以得出,对于整形来说,数组存储在内存中存的是补码。

那为什么存的是补码呢?
内存中数据的存储情况
计算机的本质是只能算加法 像int c=1-1
1-1就要变成1+(-1)的形式
内存中数据的存储情况

如果直接根据原码进行计算,那结果得到的是-2,显然不对
而如果用补码计算的话 就会像如下这样
内存中数据的存储情况

第三行1为多出来的那位,所以最后结果为0

那么现在就来解决为什么是 “ 倒着存 ” 的这个问题
“大小端字节序”
内存的两种存储方法:
内存中数据的存储情况44就是它的最低位,33相对于22来说也是低位
内存中数据的存储情况
目前的计算机采用的是小端存储方式

以下是一道关于大端小端的题
内存中数据的存储情况
假设 int a=1
小端 01 00 00 00
大端 00 00 00 01
把四个字节中的第一个字节拿出来判断就行。

然后把这个字节放到char的指针,再对这个char的指针进行解引用进行判断。那a的类型是int咋办呢?对a进行强制转换即可
内存中数据的存储情况
为什么要把(char*)&a赋给char*p呢?
因为想通过p指针从那个地址开始向后访问一个字节,所以用了一个char *p。

内存中数据的存储情况
可简化成
内存中数据的存储情况
还可以再简化成
内存中数据的存储情况

练习题

第一道
内存中数据的存储情况
结果:-1 -1 255
首先,-1用二进制表示补码是32个1,但是char只有一个字节即八个比特位,所以a中真正存储的是后面的八位:11111111。
而对于unsigned char来说,由于下面打印的是%d(整数)且要以原码形式进行打印,所以unsigned char需要进行整形提升,而整型提升是按原符号位来补充高位
char和signed char的具体情况如下↓↓
内存中数据的存储情况
第一行是-1,32个1。 第二行是a真正存储的值,然后进行整型提升补充原符号位。第三行是反码。 第四行是补码。
signed char与char情况相同

unsigned char具体情况如下↓↓
进行整型提升后二进制为00000000000000000000000011111111
当补完0后,发现这个补码的最高位是0,所以他是一个正数,而正数的原码反码补码相同,所以打印出来的结果是255

第二题
内存中数据的存储情况
(打印无符号整形)
结果:2的32次方-128
char a具体情况如下↓↓
内存中数据的存储情况
第一行是 a的原码。第二行是反码。第三行是补码
由于char只有一个一个字节的内存空间,所以a真正存储的是 后面的八位10000000,而第四行就是整型提升之后的a的补码。
由于打印的是无符号整形,所以说明a整形提升之后的原反补是一样的 。所以第四行就是最终的打印结果,那这个结果具体是多少呢?
内存中数据的存储情况
如上图,假设有第二行那个数:2的32次方,可以发现第一行二进制从右向左数的第八位上加个1(128)就得到了第二行,所以结果是2的32次方-128。

第三题
内存中数据的存储情况
与上面-128的情况一模一样

第四题
内存中数据的存储情况
结果:-10
i和j的原反补的具体情况如下↓↓
内存中数据的存储情况
j是无符号整形,所以他的原反补是一样的
所以i+j的情况如下↓↓
内存中数据的存储情况
第三行的二进制就是i+j的补码。由于打印出来的是原码形式,所以再计算出他的原码
内存中数据的存储情况
第三行就是打印出来的i+j的结果,所以结果是-10

补充
像这道题
内存中数据的存储情况
计算的时候可引出printf的特性:由于printf是可变参数的函数,所以后面参数的类型是未知的,所以不管传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。所以可得出结果:300 44