CPU 只认机器码,所以你写的每一段代码都必须【翻译】一次——编译器是一次翻完再跑,解释器是边翻边跑;这两条路没有谁更高级,只有取舍不同。
1-1 已经铺好地基:硬件→操作系统→应用程序六层皮,程序最终要落到 CPU 上执行(回收 10. 🔵 计算机基础第 06 篇【接收指令的装置-CPU】)。本节回答的是:人写的字符怎么变成 CPU 的指令——这是第二章一切语言差异的总开关。
一、两种格式:源代码与机器码
源代码:你用编程语言写的文本文件,本质是给人看的。 机器码:CPU 能直接执行的二进制指令,本质是给机器看的(回收计算机基础第 05~07 篇:指令是什么、CPU 怎么执行)。
中间隔着一道翻译关。翻译有两条路,走哪条,决定了这门语言大部分的脾气。
二、编译器:一次翻译,终身受用
编译器(Compiler)在你运行之前,把整个源代码文件翻译成机器码,生成执行文件(Windows 上的 .exe、Linux 上的可执行文件)。之后每次运行,直接跑翻译好的结果,不再需要源代码和编译器。
- 代表:C、C++、Rust、Go
- 优点:运行时零翻译开销,速度天花板高;发布时不带源码
- 代价:改一行就要重新编译整个项目(大项目编译以分钟计);执行文件绑定平台(Windows 编译的 exe 在树莓派上跑不了——机器码不一样)
C++ 课第 1.2 节搭的 Dev-C++ 环境,点【编译】按钮干的就是这件事。
三、解释器:边翻译边执行
解释器(Interpreter)不生成执行文件,而是拿着源代码逐句翻译、逐句执行——翻译一行、跑一行。
- 代表:Python、JavaScript、Ruby、PHP、Shell
- 优点:改完立刻能跑,写一行试一行,学习与调试体验好;跨平台(只要有对应平台的解释器)
- 代价:运行时翻译本身要花时间,速度通常慢于编译型
教材原文只有【编译型/解释型】两分法,但真实的 2026 年是一条光谱,不是两个箱子——这是本节最重要的修正:
四、老教材哪一处已经讲得太粗
【Python 是纯解释型语言】这句话只对了一半:CPython 解释器拿到 .py 文件后,第一步也是先编译——编译成字节码(bytecode,一种中间格式),缓存成 __pycache__ 目录下的 .pyc 文件,然后由一个叫【虚拟机】的循环逐条解释执行字节码。所以:
- Python 有编译,只是编译产物不是机器码,且不落成执行文件;
- Java 更典型:先编译成
.class字节码,再由 JVM 执行,还能在运行时把热代码再翻成机器码(JIT)——这是 2-9 的主题; - 现代语言全都活在【编译——字节码——解释——JIT】这条光谱的某个位置上,没有纯血的两分法。
记住修正版:【编译型/解释型】描述的是【翻译发生的时机】,不是【有没有翻译】。
五、动手 Demo:亲眼看见 Python 的【编译】这一步
用 dis 模块把 CPython 编译出的字节码拆开看:
import dis
def add(a, b):
return a + b
dis.dis(add)
看到什么算成功(示意,版本不同细节略有差异):
2 LOAD_FAST 0 (a)
LOAD_FAST 1 (b)
BINARY_OP 0 (+)
RETURN_VALUE
读结果:add 这个两行的函数,被编译成了 4 条字节码指令——LOAD_FAST 是【把变量搬上工作台】,BINARY_OP 是【做加法】,RETURN_VALUE 是【把结果交回去】。这就是源代码与机器码之间的【中间格式】长什么样:它不是机器码(CPU 不认),也不是源代码(人不爱读),是给虚拟机看的说明书。
六、30 秒实验
在终端里跑一条命令,直接看一行表达式的字节码:
python -c "import dis; dis.dis(compile('1+1', '<x>', 'eval'))"
输出里能看到 BINARY_OP——【1+1 这句话被编译过】的铁证。顺手再看一眼你某个 Python 项目的 __pycache__ 目录:里面躺着 .pyc,就是编译缓存。
七、常见误区
- 【执行文件里装的就是源代码】——错。
.exe里是机器码,源代码早在编译阶段就被【消化】掉了;反编译只能得到近似还原,拿不回你原来的注释和变量名。 - 【解释型语言不需要编译】——错。CPython 第一步就是编译成字节码;只是产物不是机器码、不落成独立执行文件。
- 【编译器比解释器先进,新语言都该编译成机器码】——错。两种翻译时机各有场景:命令行小工具要【改完就跑】(解释型舒服),数据库引擎要【榨干性能】(编译型舒服)。2026 年主流做法是两者混用(见 2-9)。
自测三问(点开对答案)
1. **编译器和解释器最核心的差别是什么?** 答:翻译发生的**时机**——编译器在运行前一次翻译完整个程序并生成执行文件;解释器在运行时逐句翻译逐句执行。 2. **Python 的 `__pycache__` 目录里是什么?是机器码吗?** 答:是字节码(`.pyc`),源代码编译成的中间格式,给 Python 虚拟机看的,CPU 不直接执行——不是机器码。 3. **为什么 Windows 上编译的 C 程序不能拿到树莓派上直接跑?** 答:执行文件里是机器码,而两台机器 CPU 指令集不同(x86 与 ARM),机器码不通用(详见 2-2 的跨平台两条路)。- ☐ 下一节(2-2)
相关笔记
- 计算机基础 06 · CPU —— 机器码最终由谁执行
- C++ 1.2 · 搭建开发环境 —— 编译器在真实工具链里的位置
- 树莓派 6-1 · 认识 Python —— 【编译型换运行速度、解释型换你的时间】的初遇版
- ⌨️ 编程原理 · 索引 —— 全课路线图