深度剖析数据在内存之中的存储
简介: 本文介绍在计算机中, 不同数据结构的数据在内存中的存储方式
重点:
- 数据类型的详细介绍
- 整形数据在内存之中的存储 : 原码, 反码, 补码
- 大小端字节
- 浮点型数据在内存中的存储
一 PART ONE 数据类型的详细介绍:
1. 数据类型的分类:
2. 相同数值, 定义为不同的数据类型, 在内存中的存储方式不同
例:
由上图可知,我们可以知道同样的大小的数据值在因为定义的数据类型不同, 而在内存中的存储不一样 !!!
3 数据类型的意义:
<1> 使用类型开辟内存空间的大小
<2> 如何看待内存空间的视角
二 整形数据家族:
1 分类:
char :
unsigned char
signed char
int :
unsinged int
signed int
long :
unsinged long
signed long
xhort :
unsigned short
signed short
2. 有符号位 和 无符号位数据的区别 ????
同样是8位, 有符号位需要那最高位去作为符号位, 因此表示的数值就会少一半 , 其中符号位(0正 1负), 例如: unsigned char (0 ~ 255)
signed char (-128 ~ 127)
3. short = short int , long = long int
三 . 浮点型家族(float 和 double )
1 分类: 单精度和双精度
四 构造类型(自定义类型)
五 指针类型:
作用 : 存放地址 !!!!
六 空类型—— void
二 PART TWO 整形数据在内存中的存储
##一 源码 , 反码, 补码的定义
源码: 直接将数值按照正负数形式转化为二进制即可 !!!
反码: 符号位不变, 其他位取反
补码: 反码 + 1
可以发现: 计算机存的是补码 !!!!
**思考: 为什么计算机里存的是补码 ???**答案:
CPU只有加法器 !!!!!
二 大端, 小端—— 大端字节序 存储模式
** 定义 : **
小端: (数据的低位) 放在 (内存的低地址) , (高位) 放在 (内存的高地址)
大端 : 与小端相反
注意: 大小端描述的意义: 是字节的顺序而不是 bit位的顺序! !!
为什么会存在大小端 ???
应用实例 : 请编写一个程序判断计算机存储是大端还是小端 ????
int main()
{
int a = 1;/// 定义为int型, 4个字节
char* p = &a; 用char* 来取地址, 就是去a的第一个字节 !!!!
if (*p == 1)/ 判断a的第一个字节是否为1 来判断大小端
printf("小端\n");
else
printf("大端\n");
return 0;
}
补: VScode终端乱码怎么办?
已解决:
在终端命令中输出: chcp 65001
补:在编写函数的时候, 要注意函数里面不要乱打印, 只要一个返回值即可
补: 指针的意义
例题: 分析代码:
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
结果
例题: 分析:
例二——代码分析
int main()
{
char a = -128;
源: 10000000,0000000,0000000,10000000(整型提升)
反: 11111111,11111111,11111111,01111111
补: 11111111, 11111111, 11111111,100000000
因为a是8位, 所以a = 100000000,放入内存
printf("%u", a); %U 打印的是无符号数据
需要打印无符号数 a的补码是11111111, 11111111, 11111111, 10000000
/// 所以源码也是这个 !!!!!
return 0;
}
例三: 代码分析:
int main()
{
char a = 128; 注意char 是有负号的char, 表示的范围是 -128 ~ 127
128已经溢出 128 = 127 + 1 = -128! !!! !
printf("%u", a);
return 0;
}
例四: 程序分析:
int main()
{
unsigned char i;
for (i = 9; i >= 0; i--)
{
printf("%d\n", i);
Sleep(100); /// 睡眠100ms
}
return 0;
}
分析:
例四:代码分析
int main()
{
char aa[1000];
int i;
for(i = 0; i < 1000; i++)
aa[i] = -1 -i;
printf("%d\n", strlen(aa));
return 0;
}
结果:
分析:
结论:
注意: 无符号数可能导致死循环, 一定要注意使用!!!!!
三: PART THREE 浮点型数据在内存1中的存储
一 浮点家族:
float, double, long double
取值范围可以在float.h中找到
二 浮点数据在内存中的存储
1.先把要存的数据, 以小数点为界, 整数和小数分别用二进制表示
- 按照 S(符号位) E(指数位) M (小数位) 法则存储
实例:
三 指数E 如何从内存中取出
1.E不全为0, 或不全为1的情况(一般情况)
2.E全为0的情况
注意此时指数的值为 -126, 而不是 -127!!!!
3.E全为1的情况 —— 认为是无穷大
实例