
如果你是从 Python 或 JavaScript 开始你的编程之旅的,“指针”听起来可能像是为留着灰胡子的系统工程师保留的某种神秘黑魔法。即使你在大学学过 C++,你可能还记得与段错误(segmentation faults)和内存泄漏作斗争的经历。
但秘密在于:指针只是一个变量。它不是魔法。它是一个数字。那个数字恰好是其他东西的地址。
要真正理解指针,我们需要先谈谈你的数据实际上住在哪里。
当你的代码运行时,你的数据必须有个去处。通常,它们会落在两个地方之一:栈或堆。
把栈想象成你桌上的一叠便利贴。
如果你有一个变量 int a = 10;,它很可能坐在这里。它干净、快速且安全。
堆是一个巨大的仓库。
指针仅仅是一个路牌。
如果你在堆上(地址 0x1234)有一个变量 score = 99,指针就是栈上一个微小的变量,上面写着“数据在 0x1234”。
int score = 99; // 实际的值
int *p = &score; // 指针 'p' 持有 'score' 的地址p 是地址(它在哪里?)。*p 是值(里面有什么?)。为什么不直接传递值,让语言来处理这些烂摊子?
想象你有一张 10MB 的图片。如果你把它传递给一个函数 process(image),而你的语言复制了那张图片,你就刚刚浪费了 10MB 的 RAM 和 CPU 时间来复制像素。
使用指针,你只需传递地址(8 字节)。你告诉函数:“图片在那边,去看吧。”
如果你按值将变量传递给函数,函数会得到一个克隆。如果它改变了克隆,原始数据保持不变。 如果你传递指针,函数知道原始数据住在哪里。它可以修改实际数据。
链表、树、图——这些只是持有指向其他数据块的指针的数据块。没有引用,你无法轻松构建它们。
指针不是免费的。
指针是你的代码和硬件之间的桥梁。即使你编写高级的 JavaScript 或 Python,理解对象在底层只是引用(指针!),也能帮助你理解为什么 a = b 可能不会复制 b,而只是让 a 指向相同的数据。
掌握指针会给你透视代码执行的 X 射线视觉。你不再看到“魔法”,而是开始看到内存。
© Melvin Laplanche - All rights reserved.