首页 › programming › 语句与函数:百万人的第一课

语句与函数:百万人的第一课——一条CrashCourse神课深读

概述

编程教学视频千千万,但绝大多数是在教你“用某种语言做事”,很少有一堂课肯退后一步,把“程序到底是什么”讲成一副骨架。CrashCourse(速成课)的《计算机科学》系列是YouTube上被引用最多的计算机科学入门课之一,其中第12集《编程基础:语句与函数》用十几分钟,把构成一切软件的两块基石——语句与函数——从原子层面拼给你看。这篇文章替你把这节课“吃透”:先按视频的叙事顺序拆解它讲了什么,再把它背后的真实历史与理论(从1949年的第一个子程序,到1968年那封著名的Dijkstra信件)逐一挂上钩,最后告诉你哪些说法站得住、哪些被简化了,以及三条今天就能用上的建议。没看过视频,你可以完整吸收它;看过视频,你会多懂一层它没时间讲的东西。

视频基本信息

项目 内容
标题(英文) Programming Basics: Statements & Functions: Crash Course Computer Science #12
标题(中文) 《编程基础:语句与函数》(计算机科学速成课 第12集)
频道 CrashCourse
主持人 Carrie Anne Philbin
发布时间 2017年(该系列首播年份;具体日期据频道页面)
播放量 约104万次(素材抓取于2026-09-21)
链接 https://www.youtube.com/watch?v=l26oaHV7D40

CrashCourse 是YouTube知识区的头部频道,订阅量千万级(据频道页面),其《计算机科学》系列共四十余集,从布尔逻辑一路讲到操作系统与网络,被全球大量计算机导论课堂用作预习材料。第12集处在这门课的关键位置:硬件与机器指令已经讲完(第5—11集),软件大厦即将拔地而起(第13集起讲算法与数据结构),这一集负责打地基。

核心主张拆解:从原子到大厦

这集视频的叙事是典型的“自底向上”结构,按顺序可以拆成五层。

第一层:程序是“一句一句说给计算机听”的话

视频先把“语句(statement)”立为程序的最小单位。一条语句,就是一个完整的指令:给变量赋值、做一次运算、打印一行字。它们像汉语里的句子,单独成立,按顺序排列。这一层要回答的其实是那个最容易被跳过的问题——高级语言为什么存在?因为机器指令只认数字,而人类靠语言思考。语句是人类可读性与机器可执行性之间的第一个翻译层。你写下 x = x + 1 时,本质上是在说人话,翻译给机器的活儿交给编译器和解释器——这正是前几集讲过的内容的延续。

第二层:控制流——让程序会“看情况”和“会重复”

只有顺序执行的语句,程序就只是一张购物清单。视频的第二步是给出两个改变一切的结构:条件判断(if/else)让程序能根据不同情况走不同的路;循环(while/for)让程序能把一件事重复做到天荒地老,而纸面上只占三行。至此,构成一切程序控制逻辑的三件套——顺序、分支、循环——全部到齐。这个“三件套就够”的主张,是整集视频理论分量最重的一句伏笔,后文溯源部分会展开它的定理背书。

第三层:函数——给一段流程起名字

集名的另一半在这里登场。函数(function)就是把一段语句打包、起个名字,往后想用就喊名字。两个关键配件被点明:参数是进料口,决定函数“对谁做事”;返回值是出料口,决定函数“交回什么结果”。一次定义、处处调用——同样的排序逻辑不必抄写一千遍。视频同时点出机械层面的原理:每次调用,程序会跳到那段代码执行,完事后带着返回值跳回原地,一层层进出,秩序井然(这套“进出”背后的调用栈机制,下文会补上视频没讲的那一层)。

第四层:库——站在别人的函数大厦上

函数一旦可以打包流通,就有了“库(library)”:前人写好的成千上万个函数,你直接拿来调用。视频借此把镜头拉远——今天任何一门语言的开箱即用能力,本质上都是几十年来无数程序员函数沉淀的总和。程序员说的“不要重复造轮子”,轮子指的就是这些被反复验证过的函数集。

第五层:抽象不是魔法,是分层包装

系列一贯的风格是在结尾把镜头压回硬件:无论语句写得多像人话、函数名取得多优雅,最终都要翻译成机器指令,在上一集讲过的那个CPU上逐条执行。这个收尾非常关键——它 prevent 了初学者最常见的幻觉:以为高级概念是另一套魔法。抽象的真相是层层包装:函数包住语句,库包住函数,语言包住库,而最底下永远是那台只会执行指令的机器。

知识与理论溯源:这节课背后的七十年

视频十几分钟带过的每一个概念,背后都站着真实的人和论文。把它们挂上钩,才算真正“多懂一层”。

子程序:1949年,David Wheeler的“一跳”。 函数的前身是“子程序(subroutine)”。公认的第一个软件意义上的子程序出现在英国剑桥大学的EDSAC计算机上——1949年,博士后研究员 David Wheeler(后来大家叫他 Wheeler 教授,计算机体系结构里著名的“Wheeler跳转”即以他命名)实现了“把一段代码存起来、跳过去执行、再跳回来”的机制。这是人类第一次让“写一次、处处用”在机器上成立。Wheeler 因此被视为子程序之父,这个概念后来直接演化成所有现代语言的函数。

编译器:Grace Hopper的赌注。 “让程序员用人话写代码”在1950年代曾被视作异想天开——Grace Hopper 在1952年推出 A-0 编译器,坚持让机器自己把接近英语的描述翻译成指令。她赌的方向,和语句这个概念的存在本身,是同一条思想线:把重复的翻译劳动交给机器。没有这条线,“语句”永远只能是纸面设想。

三件套定理:Böhm–Jacopini(1966)。 视频里“顺序、分支、循环就够了”这句话,学名叫结构化程序定理:Corrado Böhm 与 Giuseppe Jacopini 在1966年的论文中证明,任何单入口、单出口的可计算控制流,都可以仅用这三种结构表达。这是整个“结构化编程运动”的理论地基。

那封著名的信:Dijkstra(1968)。 荷兰计算机科学家 Edsger W. Dijkstra 在《ACM通讯》上发表了一页多一点的信件《Go To Statement Considered Harmful》(goto语句有害论),主张随意跳转的 goto 会让程序的静态文本与动态执行过程彻底脱钩,人脑无法再“读懂”程序在干什么。这封信把 Böhm–Jacopini 的定理变成了一场工业运动:结构化编程、Pascal语言、乃至今天几乎所有语言里 if 和 while 的统治地位,都源于此。

对极端化的反驳:Knuth(1974)。 高德纳 Donald Knuth 1974年发表《Structured Programming with go to Statements》,提醒大家定理只说“三种结构够用”,没说“goto 一律有罪”;在某些算法场景下受控的跳转反而更清晰。这场辩论的真正遗产不是“禁用goto”,而是一个更深的共识:编程语言的首要服务对象是阅读代码的人,而不是执行的机器——这个立场后来被 Abelson 与 Sussman 写进《计算机程序的构造和解释》(SICP)的前言:“程序必须写给人读,只是顺便让机器执行。”

函数调用的机械原理:调用栈。 视频讲到“跳过去、跳回来”,但没展开凭什么跳得回来——答案是调用栈(call stack):每调用一个函数,系统就在栈顶压入一个栈帧,记录该函数的局部变量和“回程地址”;函数返回时弹出栈帧、回到回程地址。一层层嵌套调用,就是栈一层层堆高;堆得太深没有出口,就是你听说过的“栈溢出(stack overflow)”——著名程序员问答网站的名字正来源于此。理解了调用栈,“函数为什么能嵌套、局部变量为什么互不干扰、递归为什么能停下”就全部打通了。

代码质量的量化尝试:McCabe(1976)。 函数写多长、多绕算“复杂”,太主观。Thomas McCabe 在1976年提出圈复杂度(cyclomatic complexity):数一数函数内部的分支路径数量,并给出经验建议——单个函数不超过10。这是第一个把“这段代码好不好读”变成可测量指标的严肃尝试,今天的静态检查工具仍在沿用。

现代之争:Ousterhout vs Clean Code。 关于函数的设计哲学,2018年 John Ousterhout 在《A Philosophy of Software Design》里提出了一个反直觉的标准:函数的价值不在“短”,而在“深”——接口窄、实现厚、把复杂性吞进肚子里的函数才是好函数;把几十行代码机械切成三十个两行小函数,只会制造一堆需要同时装进脑子的“浅接口”。这是对2008年《Clean Code》“函数应该短小”教条的直接修正。加上 DRY 原则(《程序员修炼之道》,1999)与 Martin Fowler 的“三次法则”(重复出现三次再抽象,出自《重构》),构成了今天关于“何时提炼函数”的主流答案。

批判性审查:哪些站得住,哪些被简化了

证据充分的部分。 三种控制结构的完备性有定理背书;函数/子程序的历史脉络(EDSAC、编译器运动)是教科书级的定论;“复用与抽象是软件工程核心手段”这一点,从 Brooks 1986 年《没有银弹》把“本质复杂度”列为软件根本困难、并把抽象作为主要武器以来,业界再无争议。视频把这些主干讲对了。

被简化、容易造成误解的部分。 第一,视频把函数的价值主要落在“复用”上,这只是副产品。函数更深的价值是命名抽象——给一段逻辑一个名字,让读者不必看实现就能推理程序。一段只出现一次、但名字取得好的函数,依然值得存在。第二,“出现重复就提炼”若严格执行,常会提炼出错误的抽象;Fowler 的“三次法则”更稳妥:第一次照写,第二次皱眉,第三次才动手。第三,视频没提命名、测试、调试——这不是它的错(十几分钟装不下),但初学者容易把“掌握语法”当成终点,殊不知语法只是词汇表,组织词汇写出可读的“文章”才是真功夫。

值得保留态度的部分。 CrashCourse 的定位是“速成”:每分钟概念密度极高,代价是没有一处允许你停下来练习。它是一张优秀的地图,而不是领土本身——用它建立全局图景极佳,用它替代动手练习必翻车。另外,McCabe 的“≤10”阈值从1976年起就是经验值而非科学定律,工具报警了值得看一眼,但不必奉为圣旨。

认知提升与实用启示

一、先写契约,再写实现。 下次提炼函数时,先只写三样东西:函数名、一行注释(输入是什么、输出是什么、有没有副作用)、参数表。确认“读契约就能明白这个函数干什么”之后,再往里填代码。这个动作逼你从“把代码收进盒子”切换到“设计接口”,正是 Ousterhout 所说的“深函数”的起点。

二、每月做一次“命名审计”。 打开自己一个月前写的模块,只读函数名和参数名,遮住实现。如果读不出“这个程序在讲一个什么故事”,说明函数边界切错了位置——这比任何度量工具都灵敏。配合一次圈复杂度检查(Python 用 radon,多语言可用 lizard),超过10的函数重点复查。

三、用“四件事”框架快速上手任何新语言。 学一门新语言,第一周只学四个东西:语句怎么写、分支怎么写、循环怎么写、函数怎么定义。骨架四件事在任何语言里同构,语法差异只是方言口音。先把骨架跑通一个完整小程序,再回头补语言独有的高级特性——顺序对了,学习曲线会平缓得多。

视频论证结构图

flowchart TD
    A[语句<br/>程序的最小句子] --> B[控制流三件套<br/>顺序·分支·循环]
    B --> C[函数<br/>命名打包·传参返回]
    C --> D[调用栈<br/>进出有序的机械保障]
    C --> E[库<br/>前人函数的沉淀]
    E --> F[分层抽象<br/>包到最底仍是机器指令]
    D --> F

延伸阅读

  1. Edsger W. Dijkstra《Go To Statement Considered Harmful》(CACM,1968)——原信一页半,十分钟可读完,现存于德州大学奥斯汀分校的 EWD 档案:https://www.cs.utexas.edu/~EWD/
  2. John Ousterhout《A Philosophy of Software Design》(2018)——“深模块 vs 浅模块”,本文批判性审查一节的最佳后续读物。

参考来源

  1. Programming Basics: Statements & Functions: Crash Course Computer Science #12 — 本文解读对象,播放量数据抓取于2026-09-21
  2. CrashCourse 频道主页 — 视频出品方,系列与主持人信息
  3. Structured Programming - Wikipedia — Böhm–Jacopini 定理与结构化编程运动脉络
  4. Subroutine - Wikipedia — 子程序与 Wheeler 跳转的历史
  5. EWD 档案(德州大学奥斯汀分校) — Dijkstra 全部手稿的官方存档

本文由「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学通信知识星球海报-扫码加入