⚙️ 第四章 让内存化方为圆
📄 一句话概括

物理上只有一长串地址,但你可以按【楼层+房间号】去理解它;二维数组的行列换算,用的就是同一行公式。

📝 本节和前面几节的关系

4.1 说清了物理结构,这一节给这串地址装上一个顺手的【看法】。

一、为什么要想成一幢楼

内存的真实样子是一长串编号连续的格子,从 0 一直排到几亿。 人脑不擅长记这种长数字,但特别擅长空间感:一幢楼、几层几号,一听就明白。 于是就把它想成一幢楼:地址 = 楼层 × 每层间数 + 房间号。 记住这一行就够了——往后的二维数组、堆、栈,换算用的都是它。

二、同一串地址,可以换个看法

楼层和房间号不是内存自带的,是你加给它的理解方式。 一维:一排房间,地址就是序号。 二维:楼层 × 房间,公式如上。 三维及以上也一样——每多一个维度,就多乘一层【每层有多少个】。 这也说明:内存本身只有一维,多维是我们自己算出来的。

三、二维数组就是这么排的

声明一个 3 行 4 列的表,内存里其实是一行接一行排平的——这叫行优先。 第 2 行第 3 列(下标写作 1、2)在内存里的位置是:1 × 4 + 2 = 6 号。 用【行下标 × 每行元素数 + 列下标】一算,就知道要去哪个格子取数。 所以二维数组一点也不神秘,它只是把一维的地址换了一种算法去点。

四、这一节的用处

它给了你一把换算的尺子:以后见到任何地址,都能在心里把它摆到某个位置上去。 更重要的是它点明了一件事:数据结构不是内存自带的功能,而是人给地址定的规矩。 下一节讲的指针,就是【把地址本身当成数据来用】——这是所有规矩的工具。

五、动手 Demo:内存的逻辑结构像一幢大楼

物理上内存只有一长串地址,可人脑习惯按【楼层+房间号】找地方。 换算就一行:地址 = 楼层 × 每层间数 + 房间号。

for a in range(12):
    print("地址 %2d -> 第 %d 层,第 %d 间" % (a, a // 4 + 1, a % 4 + 1))
grid = ((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
flat = [v for row in grid for v in row]
print("摊平:", flat)
print("第 2 行第 3 列 -> 1 * 4 + 2 =", grid[1][2])

实跑输出:

--------------------------------------------------------------------
内存的逻辑结构像一幢大楼
--------------------------------------------------------------------

物理上内存只有**一长串地址**,可人脑习惯按【楼层+房间号】找地方。
同一串地址,换成不同的看法就顺手多了:

  看法         形状                地址怎么算
  --------------------------------------------------------------
  一维         一排房间            地址就是序号
  二维         楼房:楼层×房间     楼层 × 每层间数 + 房间号
  二维数组     表格:行×列         行下标 × 每行元素数 + 列下标

  把 0~11 号地址当成一幢 3 层、每层 4 间的小楼:

  地址     楼层     楼层里的第几间
  ---------------------------------
  0        1        1
  1        1        2
  2        1        3
  3        1        4
  4        2        1
  5        2        2
  6        2        3
  7        2        4
  8        3        1
  9        3        2
  10       3        3
  11       3        4

  **换算就一行:地址 = 楼层 × 每层间数 + 房间号。**

  再拿一个 3 行 4 列的表看【行优先】是怎么排的:

    第 1 行      1    2    3    4
    第 2 行      5    6    7    8
    第 3 行      9   10   11   12

    摊平到一维内存里:  1   2   3   4   5   6   7   8   9  10  11  12
    第 2 行第 3 列(下标 1、2)→ 1 × 4 + 2 = 6 号位置,值是 7

  章名说的【让内存化方为圆】,就是这个意思:
  **内存是方方正正的一长串,你要装的数据却什么形状都有——**
  **把它摆成你要的形状,就是这一章要做的事。**

每层 4 间、共 3 层,0~11 号地址正好一人一间排满。 二维数组的【行 × 每行元素数 + 列】,和楼房的换算是一回事。

30 秒实验

  1. 把 200 号地址换算成【每层 16 间】的第几层第几间。
  2. 反过来:第 7 层第 5 间(从 1 开始数)对应哪个地址?

常见误区

  1. 以为内存里真有【二维】。内存只有一维,多维都是算出来的。
  2. 以为楼层和房间号从 0 还是从 1 开始无所谓。换算时差 1 就会点错格子。
自测三问(点开对答案) 1. 把内存想成楼房的换算公式是什么? —— 地址 = 楼层 × 每层间数 + 房间号。 2. 二维数组在内存里是怎么排的? —— 按行优先一行接一行排平;地址 = 行下标 × 每行元素数 + 列下标。 3. 为什么说多维是我们自己加的理解? —— 内存物理上只有一维的一长串地址,维度是靠换算公式算出来的。

相关笔记