🧮 第1章 什么是算法
📄 一句话概括

所有流程只用三块积木:顺序、选择、循环。不需要第四块。 「选择」的顺序会决定结果:先判 90 再判 60,和反过来完全两回事。 结构化的好处是代码的排版顺序等于执行顺序,人不用在脑子里跳转。

📝 本章和前面几章的关系

这一篇对应教材第 1 章末尾的「专题 1 算法基础之结构化编程思想」。 专题不是选读,它是后面所有章节的地基:第 4 章的循环、第 5 章的排序、第 6 章的查找, 全是这三块积木拼的。 这一篇也解释了为什么本书所有示例里都没有 goto。

一、三块积木,别的不需要

顺序:从上往下一条条做。选择:满足条件走这条,否则走那条。循环:满足条件就回去再做一遍。 就这三块。任何流程都能用它们拼出来——包括那些看起来很复杂的业务逻辑。 为什么强调「只用三块」?因为多一块(比如跳转)就多一种读代码时要在大脑里维护的状态。

教材把这个叫结构化编程。它的价值不在写得快,在别人(和三个月后的你)读得懂。

二、选择:顺序会改结果

演示里那段判等级:先判 90,再判 60,最后兜底。八个人的分数出来了。 如果把顺序反过来——先判 60——所有人都变成「及格」,因为 92 也大于等于 60,第一个条件就命中了。 这就是「选择」最容易错的地方:条件之间有重叠时,先判哪一个决定了结果。

所以写判断的规矩是:范围窄的放前面,兜底的放最后。 同理,写 if 链时每一条尽量写成「互斥」的,就不用依赖顺序了——依赖顺序的代码,改一行就可能全错。

三、循环:叠上选择就是统计程序

演示里那段及格率:外面一个循环,里面一个判断,两个累加器。 八个人:及格 6 人,及格率 75.0%,总分 594,平均 74.25。 这就是绝大多数统计程序的骨架。第 4 章整章都是它的变形:换一个累加的东西、换一个判断条件, 就变成求最大、求最小、求排名。

认准这个骨架,比记住十个例子有用。

四、为什么不要用跳转

演示最后那张对照表:全用跳转写 12 行,加一条新规则要改 3 处;用三块积木写 5 行,只改 1 处。 注意那两个数字是手写对照用的,不是跑出来的。跳转的坏处也没法用一个数字量出来。 真正能说清的是这一句:用跳转写的流程,读的时候要在纸上画箭头才跟得上。

而三块积木写的流程,从上往下读就是执行顺序——这是它唯一的、也是最大的好处。 所以「结构化」不是风格问题,是可维护性问题。 代码写完是给别人看的,多数时候那个「别人」是三个月后的自己。

五、动手 Demo:三块积木:拼一个判等级、一个算及格率

先看三块积木各长什么样,再用它们拼一段判断、一段统计。 然后故意把判断顺序调反,看结果怎么全变。 最后对照一下「全用跳转」和「只用三块」的差别。

# 顺序
a = 1
b = 2

# 选择(顺序不能反:先窄后宽,兜底最后)
if s >= 90:   g = '优'
elif s >= 60: g = '及格'
else:         g = '不及格'

# 循环 + 选择 = 统计
for s in scores:
    total += s
    if s >= 60: ok += 1

实跑输出:

--------------------------------------------------------------------
结构化编程:顺序、选择、循环
--------------------------------------------------------------------


  ① 所有流程只用三块积木
  --------------------------------------------------------------------

| 积木 | 一句话 | 代码长什么样 |
|---|---|---|
| 顺序 | 从上往下一条条做 | a = 1 然后 b = 2 |
| 选择 | 满足条件走这条,否则走那条 | if / else |
| 循环 | 满足条件就回去再做一遍 | for / while |

  这三块能拼出任何流程,不需要第四块。教材把这件事叫「结构化编程」。

  ② 拼一块:判断成绩等级
  --------------------------------------------------------------------
  八个人的分数:[92, 78, 55, 61, 88, 47, 100, 73]

| 分数 | 等级 |
|---:|---|
| 92 | 优 |
| 78 | 及格 |
| 55 | 不及格 |
| 61 | 及格 |
| 88 | 及格 |
| 47 | 不及格 |
| 100 | 优 |
| 73 | 及格 |

  这一段只有「选择」一块,但注意它的顺序:先判 90,再判 60,最后兜底。
  顺序反了(先判 60)所有人都会变成「及格」。

  ③ 三块拼在一起:及格率与平均分
  --------------------------------------------------------------------
  循环 8 次,两次累加
  及格 6 人,及格率 75.0%
  总分 594,平均分 74.25
  外层一个循环,里面一个选择——这就是绝大多数统计程序的骨架。
  后面的排序、搜索,八成也是这个骨架加几行。

  ④ 为什么不要用「跳转」代替这三块
  --------------------------------------------------------------------

| 写法 | 行数 | 加一条新规则要改几处 |
|---|---:|---:|
| 全用跳转(goto) | 12 行 | 3 处,还可能漏 |
| 顺序 + 选择 + 循环 | 5 行 | 1 处 |

  用跳转写的流程,读的时候要在纸上画箭头才跟得上;
  用三块积木写的流程,从上往下读就是执行顺序。
  这就是「结构化」的全部好处:代码的排版顺序等于执行顺序,人不用在脑子里做跳转。
  (上面那两行的行数是这一节手写对照用的,不是跑出来的;
  跳转的坏处也没法用一个数字量出来,所以这里只给对照,不给结论。)

①第一张表三行,第三列是「代码长什么样」。三句话对三块积木,一一对应。 ②八个人的分数里 100 和 47 是特意放的:一个顶上、一个底下,用来试边界。 ③第三段「及格 6 人、及格率 75.0%」——8 个人里 6 个及格,手算能核对。 ④最后那张对照表只有两行。那两个行数是手写的,演示里也说清了,不是测出来的。 ⑤这一节没有新奇的东西,全是常识。但它决定了你后面写的每一个排序、每一个查找是不是别人能看懂。

30 秒实验

  1. 把判等级的顺序改成先判 60,重跑,数一下还有几个「优」。
  2. 给这段统计加一条「90 分以上算优秀率」,看要动几行。
  3. 用这三块积木写一个「猜数字」的流程,先画流程图再写代码。

常见误区

  1. 「跳转更灵活,想跳哪跳哪。」灵活的是写法,受罪的是读的人。
  2. 「判断顺序无所谓,条件都写对了。」条件有重叠时,顺序决定结果。
  3. 「结构化是给初学者定的规矩。」它是给维护代码的人定的,那个人多半是你自己。
自测三问(点开对答案) 1. 结构化编程的三块积木是什么? —— 顺序、选择、循环。这三块能拼出任何流程,不需要第四块。 2. 判等级时为什么必须先判 90 再判 60? —— 条件有重叠。先判 60 的话,92 也满足,所有人都变成「及格」。 3. 结构化的最大好处是什么? —— 代码的排版顺序等于执行顺序,读的人不用在脑子里做跳转。

第一章到此结束。 下一章从最小的零件开始:数据、变量、数组——后面所有算法都是在这些东西上做文章。

相关笔记