<!-- title: 一切程序，只用三种积木 -->
<!-- domain: programming -->

# 一切程序，只用三种积木：104万人看过的编程第一课深度解读

## 概述

你大概听说过一个流传很广的说法：学会 if 和 while，你就学会了编程的一半。这听起来像鸡汤，但它背后站着一个1966年就被严格证明的数学定理。本文深度解读的，是 YouTube 传奇教育频道 CrashCourse《计算机科学速成课》第12集《Programming Basics: Statements & Functions》（语句与函数基础）——一集只有十分钟出头、却把“程序到底是什么”讲得干干净净的入门神课。它没有炫技，没有概念轰炸，只是把语句、分支、循环、函数这四块“积木”按叙事顺序一块块递到你手里。这篇文章会带你拆开它的论证结构，挖出每块积木背后的真实学术源头——从博姆-雅可比尼定理到迪杰斯特拉的 goto 信件，再到世界上第一个子程序库——最后告诉你：哪些说法证据扎实，哪些被简化了，以及你能立刻带走的三条写代码习惯。没看过视频也能读懂，看过视频会懂得更深。

## 一、视频基本信息

| 项目 | 内容 |
|---|---|
| 视频标题（英文） | Programming Basics: Statements & Functions - Crash Course Computer Science #12 |
| 标题（中文译名） | 编程基础：语句与函数——《计算机科学速成课》第12集 |
| 频道 | CrashCourse |
| 主持人 | Carrie Anne Philbin（据频道页面） |
| 系列信息 | 计算机科学速成课（Crash Course Computer Science）第12集，共约40余集（据频道页面） |
| 发布时间 | 2017年（据频道页面信息，本轮未能二次核实精确日期） |
| 播放量 | 约104.2万次（据系统2026-09-21对YouTube搜索结果的自动抓取） |
| 视频链接 | https://www.youtube.com/watch?v=l26oaHV7D40 |

需要说明的是热度数据：这集上线于2017年，是典型的“常青课”。它不是靠算法推送一夜爆红的视频，而是八年里持续被全球编程初学者、计算机专业新生和自学党一集一集补课补上来的百万播放。它的母系列《计算机科学速成课》由PBS数字工作室支持制作，是YouTube上被引用最多的计算机科普系列之一，整季覆盖从布尔逻辑、CPU、操作系统到网络与人工智能的完整地图，而这第12集恰好卡在地图的关键位置：**前11集讲完了硬件和语言的历史，从这一集开始，正式教你写程序**。

## 二、核心主张拆解：视频按什么顺序讲了什么

这一集的叙事结构非常干净，可以拆成五个递进的要点。

### 要点1：程序的本质是“语句”

视频开宗明义：所谓程序，就是把一条条**语句（statement）**按顺序写下来。语句就是一门编程语言里“合法的完整句子”，每一条都在指挥计算机做一件小事，比如赋值语句 `a = 5`，意思是“把5放进名叫a的格子里”。

这个定义看似平淡，其实完成了一次重要的“祛魅”。多数初学者面对代码的第一反应是“这是天书”——满屏符号，不知从何读起。而“语句即句子”这个类比把代码拉回自然语言的框架：有语法，有语义，一句一个动作。程序不再是魔法咒语，而是**一份写给机器的、必须精确执行的菜谱**。视频从这里建立全片的基调：复杂程序 = 大量简单句子的有序组合。

### 要点2：分支（if）——程序第一次有了“选择”

只会顺序执行的程序是死的。视频引入的第二块积木是 **if 语句**：条件为真就走这条路，为假就走另一条路。程序由此第一次具备了“看情况办事”的能力。

视频用直白的伪代码演示了单分支和双分支（if / else），并强调条件本身是一个真假值的表达式。这里埋着一个容易被初学者忽略的深层结构：**分支意味着程序的执行路径开始分岔**。一个程序里有几个 if，理论上就可能走出几条不同的路径——这也是为什么后面讲软件测试时，工程界发明了“路径覆盖”这样的概念。分支给了程序智能，也给了它复杂性。

### 要点3：循环（while / for）——程序第一次有了“重复”

第三块积木是循环。视频讲了 while 循环（条件为真就一直重复执行）和 for 循环（按已知次数重复），并且特意警告了一个每个程序员都亲自踩过的坑：**死循环（infinite loop）**——如果循环条件永远为真，程序就会原地打转到天荒地老，你只能眼睁睁看着风扇起飞。

这十分钟里的一个“顺口提醒”，其实是计算理论的边界线：1936年图灵就已经证明，**不存在一个万能算法，能判断任意程序是否会陷入死循环**——这就是著名的停机问题。视频没展开讲，但这个警告背后站着整个可计算性理论。我们在第四节还会回到这里。

### 要点4：函数——把一段逻辑打包、命名、送进黑盒

前三块积木解决了“怎么写一句、怎么选择、怎么重复”，但很快会遇到新问题：同样的代码要写很多遍怎么办？复制粘贴显然是灾难。视频给出的答案是第四块积木，也是全集的主角：**函数（function）**。

把一段完成特定任务的代码打包起来，起个名字，以后随时“喊”它执行——这就是函数。视频重点讲了函数的三个接口要素：**参数**（调用时传给它的输入）、**返回值**（它算完交还给你的结果）、以及**封装**（函数内部的实现细节对使用者不可见）。它还提到一个跨语言的细节：在有些语言里，依附于对象的函数被叫做“方法（method）”，本质是同一件事。

用今天的话说，函数就是程序的“压缩包”和“乐高块”：写函数的人负责内部逻辑，用函数的人只需要知道“给它什么、它还你什么”。注意这个视角的翻转——**从这一刻起，程序员的核心技能从“写出每一步”变成了“设计接口”**。

### 要点5：抽象与函数库——站在前人代码的肩膀上

视频收尾把镜头拉高：函数可以调用别的函数，函数之上可以再封装出更大的函数，层层堆叠，每一层只关心相邻层的接口——这就是**抽象（abstraction）**。而把大量现成函数收集在一起供人取用，就成了**函数库（library）**。视频强调，今天你写一个再简单的应用，底下都垫着海量前人写好的库代码；而且“几乎所有编程语言都有这几种结构”——语句、分支、循环、函数，是全行业的通用积木。

这就是全集的最终主张：**编程语言千千万，底层积木就这几块；学会这几块，你就拿到了进入任何语言的通行证。**

## 三、知识与理论溯源：每块积木背后站着谁

这集视频最大的隐藏价值，是它每一句话几乎都有几十年的学术与工程史背书。逐一溯源如下。

### 3.1 “三种结构就够了”——博姆-雅可比尼定理（1966）

视频“顺序、分支、循环是程序的基本结构”这一主张，学理源头是**结构化程序定理**：1966年，意大利计算机科学家 Corrado Böhm 和 Giuseppe Jacopini 在《ACM通讯》（Communications of the ACM）上发表论文《Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules》，证明任何可计算的函数，都可以只用**顺序、选择、循环**三种控制结构（甚至只需两种）表达出来，不需要任意跳转。这个定理是纯表达力层面的证明，本意未必是提倡某种编程风格，但它为两年后那场著名的编程革命提供了数学弹药。

### 3.2 革命的引爆点——迪杰斯特拉的 goto 信件（1968）

1968年3月，荷兰计算机科学家艾兹赫尔·迪杰斯特拉（Edsger W. Dijkstra，2002年图灵奖得主）在《ACM通讯》上发表了一封只有一页多、标题却被编辑加了戏的信：**《Go To Statement Considered Harmful》**（go to 语句有害论，手稿编号 EWD215）。他主张：程序员的水平，体现在让程序文本与执行过程保持结构上的对应；而任意跳转（goto）会把这种对应撕得粉碎，让程序“变成一团无法理清的乱麻”。

这封信直接引爆了**结构化编程运动**：尼克劳斯·维尔特（Niklaus Wirth，Pascal 之父）设计了为结构化而生的语言；1972年 Dahl、Dijkstra、Hoare 三人合著《Structured Programming》一书，把方法论系统化。你在任何现代语言里都找不到（或被强烈不建议用）任意 goto，追根溯源就是这封信。视频里那些整整齐齐的 if 和 while，是一场五十多年编程范式战争的胜利成果。

### 3.3 平反的一角——克努特的冷静反思（1974）

有意思的是，这场运动内部并非铁板一块。1974年，高德纳（Donald Knuth）发表长文《Structured Programming with go to Statements》，指出：教科书式地禁止一切 goto 是教条；在循环退出、错误处理等场景，跳出结构的语句能让代码**更快也更清晰**。他强调结构化编程的价值在于“可推理”，而非“枚举禁令”。今天很多语言保留的 `break`、`continue`、`return`，正是这场反思留下的折中。视频作为入门课只讲了“标准答案”，但完整的学术图景是有争论、有反复的。

### 3.4 函数的祖先——世界上第一个子程序（1949-1951）

“把代码打包复用”这个想法比结构化编程更老。1949年前后，英国剑桥大学 EDSAC 计算机上的**大卫·惠勒（David Wheeler）**发明了“惠勒跳转”（Wheeler jump）——把返回地址存好、跳去执行一段公共代码、再跳回来的技巧，这就是**子程序（subroutine）的诞生**。1951年，Wilkes、Wheeler、Gill 出版的著作里甚至附带了世界上第一个**子程序库**。惠勒后来获颁英国计算机学会的首个计算机先驱奖。视频里“函数让代码复用”这一课，直接的祖师爷就是他。

### 3.5 函数库与“让机器写程序”——格蕾丝·霍珀（1952）

把“复用”推向工业化的，是**格蕾丝·霍珀（Grace Hopper）**。1952年她写出 A-0 编译器，让程序员用可翻译的记号写代码、由机器自动展开成机器指令，并梦想让程序“自动调用库里的例程”。她后来主导的 COBOL 让“用接近英语的语句写程序”成真。视频开头承接的前几集里恰好讲过霍珀——第12集的“函数库”，正接在她递出的接力棒上。

### 3.6 抽象的工程化——从 THE 系统到 Liskov

“抽象层”不只是教学比喻，而是被写进操作系统的工程原则。1968年迪杰斯特拉设计的 **THE 操作系统**第一次明确按抽象层次分层设计、逐层证明正确性。1970年代，**芭芭拉·利斯科夫（Barbara Liskov，2008年图灵奖得主）**在 CLU 语言中提出数据抽象与抽象数据类型，把“接口与实现分离”变成了现代软件工程的基石（她的名字如今更广为人知是因为“里氏替换原则”）。视频说的“函数内部细节对使用者不可见”，背后是这条跨越半个世纪的抽象史。

### 3.7 死循环警告的理论下限——停机问题（1936）

视频提醒小心死循环，而图灵在1936年的论文《论可计算数》中证明：**不存在任何算法，能对任意程序判断它是否终将停机**。换言之，“写一个万能死循环检测器”在数学上被判定不可能。这给初学者的教训格外务实：防死循环不能指望工具兜底，只能靠写代码时的纪律——这正是本文第五节要给的建议之一。

### 3.8 模块化的实证支持

“函数让代码更可读、更好维护”也非空谈。软件工程领域有大量实证研究考察模块化与缺陷的关系，其中较常被引用的是 Basili 与 Perricone 1984 年对大型软件的经验研究，以及后续一系列关于函数长度、圈复杂度与缺陷率相关性的工作。总体结论谨慎但一致：**过大的函数/模块与更高缺陷率显著相关**——当然，把它切成太碎也有代价，这个问题第四节还会谈。

## 四、批判性审查：哪些说法站得住，哪些被简化了

### 4.1 “三种结构足够” ——定理为真，但不能读过头 ✅⚠️

博姆-雅可比尼定理证明的是**表达力的充分性**：三种结构能算出一切可计算函数。但它**没有**证明三种结构写出的代码一定最清晰、最短或最快。克努特1974年的反思正是针对这种误读。此外，定理假设的是理想化的顺序执行程序；现代语言为了真实需求长出了一堆“第四种结构”：异常（exception）、协程、async/await——它们严格说都能还原回三种结构（定理保证这点），但作为“人类可读性装置”已经超出了教科书三件套。视频作为入门内容只呈现标准答案，可以理解，但读者应知道边界。

### 4.2 “几乎所有语言都有函数” ——成立，但视频里的函数观偏命令式 ⚠️

视频把函数介绍为“打包步骤的黑盒”，这是命令式语言的视角。在函数式编程（Lisp、Haskell 一系）传统里，函数是**一等公民**：可以像数值一样被传来传去、可以被另一个函数接收和返回（高阶函数）、可以“记住”定义时的环境（闭包）。这是编程语言理论里极重要的一支，也是 JavaScript、Python、Rust 等主流语言近二十年不断吸收的能力。对零基础观众，视频的简化是合理的取舍；但若你想真正理解现代语言，函数这条线要往函数式方向再补一课。

### 4.3 “函数越小越模块化越好” ——证据支持有度，过度切分有害 ⚠️

视频鼓励封装，方向正确；但实证研究的结论是“过大相关于缺陷”，而不是“越小越好”。把一个连贯算法机械地切成二十个三行函数，反而会让读者在调用栈里来回跳——工程界称之为“碎函数病”。合理的经验法则是**一个函数做一件事、且只涉及一个抽象层级**，而非追求行数指标。

### 4.4 教学取舍：伪代码与未展开的机械层 ℹ️

视频用伪代码而非具体语言演示，降低了入门门槛，代价是没有展示函数调用在真实机器上的代价——**调用栈**、栈帧分配、栈溢出（递归太深会怎样）这些“函数的地板”完全留白。这不是错误，而是系列分集的结果（调用细节更多落在该系列后面 CPU 与算法各集）。初学者应意识到：你在这集学到的函数模型，是“建筑图纸”，不是“施工细节”。

### 4.5 内容时效性 ✅

尽管制作于2017年，本集讲的是1949-1970年代就定型、此后未再变动的语言地基，内容几乎无老化。真正“过期”的只是例子外衣，而非内核。这也是它能八年常青的根本原因。

## 五、认知提升与实用启示：三条立刻能用的习惯

### 启示1：写函数前，先逼自己说“一句话签名”

函数设计的最简自检：能否用**一句中文**说清“给它什么、它做什么、还你什么”？比如“给它一个名字列表，返回其中最长的名字”。说不清，说明这个函数干了不止一件事，或者抽象层级混乱。动手前先写这句签名（甚至直接写成注释或函数名），能挡掉大量未来的返工。这是“接口先于实现”这一抽象原则的最小实践版。

### 读不懂代码时，先画控制流地图

面对嵌套的 if 和循环看晕了？用最笨也最有效的办法：拿笔把这段代码的**路径**画成一棵树——每个 if 分出两枝，每个循环标出“回到哪里”。画完你通常会发现，看不懂的从来不是某一句，而是“我现在在树的哪一枝上”没有着落。这本质上是把代码还原回结构化定理给定的三积木，也是所有调试器单步功能的纸上版。

### 启示3：任何循环，三要素凑齐再提交

既然停机问题保证没有万能工具替你查死循环，就自己立规矩：每个循环写完，检查三要素——**初始化**（起点在哪）、**条件**（何时停）、**推进**（每轮怎么朝终点挪一步）。三行审查，五秒钟，能拦住绝大多数死循环。顺手再问一句：如果循环条件第一次就为假，行为还对吗？——这是初学者 bug 榜的常年前列（循环根本没执行）。

## 六、一张图看懂全集论证结构

```mermaid
flowchart TD
    A[程序：语句的序列] --> B[顺序结构]
    A --> C[分支结构 if]
    A --> D[循环结构 while与for]
    B --> E[三种结构足以表达<br/>一切可计算程序]
    C --> E
    D --> E
    E --> F[痛点：代码重复<br/>复制粘贴不可持续]
    F --> G[函数：打包命名复用]
    G --> H[参数入口<br/>返回值出口]
    H --> I[细节藏进黑盒<br/>使用者只看接口]
    I --> J[函数调用函数<br/>抽象层层堆叠]
    J --> K[函数库<br/>站在前人代码之上]
    K --> L[现代软件<br/>百万行的通用积木]
```

这张图的上半段是“数学下限”（三种结构足够），中间是“工程动机”（重复催生函数），下半段是“工业结果”（抽象与库撑起现代软件）——一节十分钟的入门课，实际走完了从图灵到云计算的八十 years 长路。

## 延伸阅读

1. **CrashCourse《计算机科学速成课》第13集《Intro to Algorithms》（算法入门）**——正是第12集结尾预告的下一课：同样的三块积木，如何拼出线性搜索、二分搜索这些经典算法（据频道页面）。
2. [basics of CODING in 10 minutes | The StudyTube Project](https://www.youtube.com/watch?v=I-k-iTUMQAY)——另一条约200万播放的十分钟入门视频，与本集互补：它用更生活化的例子讲变量、循环和条件，适合完全零基础者先看它找感觉、再回来看本集打地基。

## 参考来源

1. [Programming Basics: Statements & Functions - Crash Course Computer Science #12](https://www.youtube.com/watch?v=l26oaHV7D40) — 本文解读的视频本体；播放量数据取自2026-09-21系统对YouTube搜索结果的抓取记录
2. [Structured program theorem - Wikipedia](https://en.wikipedia.org/wiki/Structured_program_theorem) — 博姆-雅可比尼定理（1966）的词条，三种控制结构充分性证明
3. [Considered harmful - Wikipedia](https://en.wikipedia.org/wiki/Considered_harmful) — 迪杰斯特拉1968年《Go To Statement Considered Harmful》信件的来龙去脉及后续争论
4. [Structured programming - Wikipedia](https://en.wikipedia.org/wiki/Structured_programming) — 结构化编程运动综述，含1972年 Dahl/Dijkstra/Hoare 专著与克努特1974年的反思
5. [David Wheeler (computer scientist) - Wikipedia](https://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)) — 子程序与第一个子程序库（EDSAC，1949-1951）的发明史

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
