💻 第四章 程序像河水一样流动着
📄 一句话概括

结构化=只用顺序、循环、分支三种积木,每块单入口单出口——把随意跳转的【面条代码】改造成从上往下读得懂的段落。

📝 本节和前面几节的关系

三种流程都认识了(4.1~4.3),这一节回答一个工程问题:程序该怎么组织才不出乱子。

一、面条代码的病

早期用跳转指令(类似 BASIC 的 GOTO)随意跳来跳去的程序,被叫作【面条代码】:箭头来回缠绕,像一碗面条。 病灶有二:多入口(可以从任意一行跳进来)、多出口(可以从任意一行跳出去)——读代码的人必须拿着笔在行号间追,忘一处前功尽弃。

二、结构化的药方

只用三种基本结构搭程序,并给每种结构定规矩:单入口、单出口。 于是每块积木都成了一个【黑盒】:进去一个口、出来一个口,内部细节可以不看——大程序就是一层层黑盒的嵌套。 规矩换来的是可读性:任何一段代码都能从上往下顺读,不用追跳转。

三、结构化为什么成了主流

因为人的脑子是【顺序理解】的机器。代码写得像清单,读者就省力;写得像迷宫,读者就崩溃。 【⚠️ 2026 现状】现代语言干脆不提供随意跳转(Java 的 goto 只是保留字、Python 没有 goto),异常处理与函数调用成了新的结构化工具。

四、动手 Demo:面条改结构化

把一段靠跳转拼的程序改写成只用三种结构的版本,对照两张表。

# 面条版(伪码): 跳来跳去
noodle = ["L1: 读一个数", "JP Z, L3", "累加", "JP L1", "L3: 输出和"]
# 结构化版: 从上往下读
struct = ["和 = 0", "当 数 != 0:", "    和 += 数", "    再读一个数", "输出和"]
print("-- 面条 --")
for s in noodle:
    print("  ", s)
print("-- 结构化 --")
for s in struct:
    print("  ", s)

实跑输出:

--------------------------------------------------------------------
从【面条代码】到结构化
--------------------------------------------------------------------

先看一段靠随意跳转拼起来的【面条代码】:

    L1: 读一个数
        JP Z, L3        ← 是 0 就跳到 L3
        累加
        JP L1          ← 跳回去
    L3: 输出累加和

箭头来回乱窜,读者得拿着笔在行号之间跳——这就是结构化要治的病。

改写成结构化(只用三种基本结构):

    和 = 0
    当 (读到的数 != 0):        ← 循环
        和 = 和 + 数            ← 顺序
        再读一个数
    输出和                     ← 顺序

  对比项       面条代码           结构化代码
  ---------------------------------------------
  进入方式     可从任一行跳入     只有一个入口
  退出方式     可从任一行跳出     只有一个出口
  读代码       要追跳转           从上往下读

结构化的口号:**只用顺序、循环、分支三种积木搭房子**——
每种积木单入口单出口,任意嵌套都不乱。

两段代码做同一件事,区别只在【读起来的顺序】:面条要追 L1/L3,结构化从上往下就行。 结构化的三层嵌套(循环里套顺序)在这种缩进里一眼可见——缩进本身就是结构化的副产品。

30 秒实验

  1. 打开一段你写过的长脚本,找出所有跳转/嵌套层级——层级超过五层就是重构信号。
  2. 把结构化版的伪码翻译成任意一门语言的 while 循环,跑一遍。

常见误区

  1. 以为结构化禁用分支——分支照用,禁的是【随意跳转】。
  2. 以为结构化是语法规定——它是【写法约定】加【语言支持】,核心是人的可读性。
自测三问(点开对答案) 1. 面条代码的两个病灶是什么? —— 多入口、多出口——导致流程可以随意跳入跳出,无法顺序阅读。 2. 结构化的三条规矩是什么? —— 只用顺序/循环/分支三种结构;每种单入口单出口;任意嵌套组合。 3. 结构化换来的最大好处是什么? —— 可读性——任何一段都能从上往下读,不必追跳转。

相关笔记