数组取地址只有一条公式——元素地址 = 基址 + 序号 × 元素长度;两个寄存器各管一段。
1.5 讲了栈(一段内存按后进先出用),这一节讲另一段最常用的内存用法——按序号直取。
一、数组在内存里就是排好队
数组的元素一个挨着一个放,而且每个占同样多的字节(同样类型)。 这两条一凑,就能算出任意一个元素在哪:知道开头、知道每个多长就够了。 公式写出来只有一行:元素地址 = 基址 + 序号 × 元素长度。 例:int 数组从 0x1000 开始,每个 int 占 4 字节,那 a[3] 在 0x1000 + 3×4 = 0x100C。
二、两个寄存器各管一半
CPU 为这件事准备了两个寄存器(1.2 提过): 基址寄存器装【数组从哪开始】——0x1000。 变址寄存器装【要第几个】——3。 CPU 在一条指令里把两者加起来(有的架构的寻址方式还自带乘 4)。 所以人写 a[3],机器看到的是【基址 + 3×4】——这个换算不用你操心。
三、为什么要乘,不能直接加
因为单位和序号不是一回事:地址的单位是字节,序号的单位是元素。 元素占几个字节,就要乘几——这就是那个乘法的全部来历。 顺带解释了一个老问题:为什么数组下标从 0 开始? 因为0 号元素的地址恰好就是基址本身,不用做任何减法——这是最省事的起点。
四、换个写法就是指针
指针存的也是地址,本质上就是【把基址放进一个变量】。
所以 a[i] 与 *(p + i) 是同一件事的两种写法:一个让机器算、一个你自己算。
理解到这一层,指针的神秘感就没了:它不特殊,它只是一段门牌号。
五、动手 Demo:基址 + 变址,算出数组元素的地址
内存像一幢大楼:每个字节是一间房,地址就是门牌号。 数组的取地址公式只有一条:元素地址 = 基址 + 序号 × 每个元素占几个字节。
base, size, a = 0x1000, 4, [10, 20, 30, 40, 50]
for i, v in enumerate(a):
print("a[%d] 基址 0x%04X + %d x %d = 地址 0x%04X 值 %d"
% (i, base, i, size, base + i * size, v))
实跑输出:
--------------------------------------------------------------------
基址 + 变址,算出数组元素的地址
--------------------------------------------------------------------
内存像一幢大楼:每个字节是一间房,地址就是门牌号。
数组的取地址公式只有一条:
**元素地址 = 基址 + 序号 × 每个元素占几个字节**
样本:int a[5],从地址 0x1000 开始,每个 int 占 4 字节
序号 i 基址寄存器 变址 i×4 算出的地址 内存里的值
-----------------------------------------------------------------
0 0x1000 0 0x1000 10
1 0x1000 4 0x1004 20
2 0x1000 8 0x1008 30
3 0x1000 12 0x100C 40
4 0x1000 16 0x1010 50
三个角色各干一件事:
基址寄存器 装着 0x1000——数组开头在哪儿
变址寄存器 装着 i——要第几个
CPU 顺手做 base + index × 4
所以你是**不用**自己算地址的:写 a[3],机器替你做了上面这道乘法加法。
**人看到的是【第几个元素】,机器看到的是【哪一号门牌】。**
基址管开头、变址管第几个,CPU 顺手做一次乘加。 人看到的是【第几个元素】,机器看到的是【哪一号门牌】。
30 秒实验
- 用 Python 打印一个整数列表各元素的地址(或用
id()观察),看相邻元素差多少。 - 手算:一个 int 数组从 0x1000 开始,a[7] 的地址是多少?
常见误区
- 以为数组【知道自己的长度】。内存里的数组只知道开头在哪,长度是语言层面替你记着的。
- 以为指针是另一个物种。它和你算的地址是同一类东西,只是一个存在变量里。
自测三问(点开对答案)
1. 数组元素的地址公式是什么? —— 元素地址 = 基址 + 序号 × 每个元素占的字节数。 2. 基址寄存器和变址寄存器各装什么? —— 基址装数组开头的地址,变址装序号(偏移量)。 3. 为什么数组下标从 0 开始最省事? —— 0 号元素的地址就是基址,不需要额外做减法。- ☐ 下一节(1.7 CPU的处理其实很简单)
相关笔记
- CPU是寄存器的集合体 — 基址与变址的出处
- CPU的处理其实很简单 — 本章收口
- 💻 计算机是怎样跑起来的 · 索引 — 姊妹篇里算法与数据结构两章讲得更系统
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引