8.1 内存
内存 (RAM) 是一组有着独特地址的存储单元。每个单元可以存储不同类型的数据,比如数字、字符和指针。当程序运行时,它会将数据和指令放入内存,以便快速访问。
内存单元示例:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
| 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
| 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
| 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
| 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
每个单元都有自己的序号,也被称为存储单元地址或地址。如果你的电脑有8G内存,那就有80亿个这样的单元可以存储有用的数据。
位和字节
每个单元可以存储一个字节的信息。每个字节由8位组成,每个位只能是0或1。示例(针对正整数):
| 数字 | 位表示 | 字节对齐 |
|---|---|---|
| 0 | 0 | 00000000 |
| 1 | 1 | 00000001 |
| 100 | 1100100 | 01100100 |
| 1000 | 1111101000 | 00000011-11101000 |
| 1000 000 000 | 111011100110101100101000000000 | 00111011-10011010-11001010-00000000 |
变量占用的字节越多,可以存储的值越多。比如:
- 1字节 — 256个独特值
- 2字节 — 6.5万个独特值
- 3字节 — 1600万个
- 4字节 — 40亿个
8.2 数据在内存中的表示
数据类型和它们的表示
计算机内和内存中的数值数据
- 整数: 以二进制形式存储。大小可以变化(1字节、2字节、4字节)。
- 浮点数: 以浮点表示法存储(例如,4字节和8字节数的IEEE 754格式)。
x = 42 # 整数
y = 3.14 # 浮点数
重要! 在Python中,内建类型int和float是完整的类,可以实现无限长度数字的复杂计算。不过,如果你使用科学计算或AI库,你将遇到我前面提到的那种数据格式。
计算机内存中的字符数据
字符和字符串 在内存中以字节序列形式存储。例如,在ASCII编码中每个字符占用1字节,而UTF-8编码可能占用1到4字节。
在Python 3.x中默认使用UTF-8编码,但你可以读取以其他格式存储文本的文件,或者在网络上传输非UTF-8编码的数据。
示例:
char = 'A' # 字符
string = "Hello, world!" # 字符串
在Python中,单个字符没有独立的类型——仍然使用类型str。但在内存中,这些字符串是按字符存储的。一个字符通常占用1到4字节。
指针
指针存储其他内存单元的地址。它们允许程序与动态数据结构交互,更有效地管理内存。
示例:
list = [1, 2, 3, 4] # 列表
list_pointer = id(list) # 指向列表开头的指针
8.3 内存中数据表示示例
1. 整数表示
整数以二进制形式(位)存储在内存中。根据数据类型,它们可能占用不同数量的字节。例如,int通常占用4字节(32位)。
如下所示,数字42在内存中的表示:
| 00000000 | 00000000 | 00000000 | 00101010 |
2. 浮点数(浮点表示法)表示
浮点数(如float类型)在内存中以浮点表示法存储,通常为IEEE 754标准。float通常占用4字节(32位),而double占用8字节(64位)。
重要! 这是与内存和处理器关联的标准数据类型。Python中的float类型相当于常用的double类型,占用8字节。
如下所示,数字3.14在内存中的表示:
| 01000000 | 01001000 | 11110110 | 01100110 |
3. 字符和字符串表示
字符(如char类型)以字节序列形式存储在内存中。字符串是字符数组。在C/C++语言中,字符串以空字节(\0)结尾,但在Python中不是这样。
如下所示,字符串Hello在内存中的表示:
| 'H' | 'e' | 'l' | 'l' | 'o' |
这又会以0和1的形式表示:
| 01001000 | 01100101 | 01101100 | 01101100 | 01101111 |
8.4 动态内存地址
动态内存在程序运行时根据需要分配和释放。你在Python中创建的所有对象都创建在这内存中。
它分为两种类型:
堆 (Heap): 从中分配动态对象的内存区域。通过分配(如C中的malloc)和释放(如C中的free)函数管理这块内存。
栈 (Stack): 用于存储局部变量和函数调用数据的内存区域。内存在进入和退出函数时自动分配和释放。
同样,我不能举Python语言的例子,因为它太高层次了。能给一个C语言的例子:
// 为10个整数的数组动态分配内存
int *dynamic_var = (int *)malloc(sizeof(int) * 10);
// 释放内存
free(dynamic_var);
地址化内存 是为每个内存单元确定唯一地址的过程。每个地址指向内存中的特定位置,可以包含数据或指令。
地址化类型
物理地址化:直接访问物理内存单元的地址。由硬件(如内存控制器)管理。
虚拟地址化: 使用管理内存的机制,如分页或分段内存,为进程提供隔离和受保护的地址空间。
GO TO FULL VERSION