第15章:使用条件语句

第15章:使用条件语句:把 if 与 case 组织成正常路径清晰、分支互斥且输入域完备的可验证决策。

学习目标

  • 识别 if 与 case 中的正常、替代和默认路径,并说明每个输入的归属。
  • 重构一条条件串,使分支互斥、输入域完备,且复杂判断拥有可读的名字。
  • 验证正常值、恰好边界和故障输入,保存首个偏离、拒绝理由与复位后的重放证据。

为什么需要这一机制

条件语句不是把几行判断拼在一起,而是在输入域上建立一份可阅读的决策合同。原书第15章讨论 if、if-then-else 和 case 的组织方式;本章把这组建议改写成可观察的检查流程:先让读者看见最常见的正常路径,再证明替代路径彼此不重叠,最后为未知值写出明确的默认结论。

当一段代码只在一个样例上通过时,最容易被藏起来的是恰好边界。例如 score 为 60 时,score > 60score < 60 都不成立;如果没有默认处理,输入就从决策表中“消失”了。好的条件代码让读者能回答三个问题:输入在哪个集合里、为什么只命中一个分支、如果没有命中应该接受、拒绝还是报告不可达。

先写分支合同,再写判断

把输入域记作 D,每个分支能接受的集合记作 Bᵢ。条件代码至少需要满足:

D=iBi,BiBj=(ij)D=\bigcup_i B_i,\qquad B_i\cap B_j=\varnothing\quad(i\ne j)

这里的“互不相交”不是数学装饰:它要求一个输入最多只能走一条业务路径;“并集等于输入域”则要求没有边界被遗漏。先预测 score = 60、一个正常值和一个不合法值会落在哪里,再运行实验;只修改阈值直到测试变绿,不能代替解释。

目录节点到可验证证据

下面 8 个节点与 manifest 中的第15章目录保持同名。每节都说明条件结构的意图、边界探针和可保存的证据;标题本身不是覆盖率,实验与练习才是。

第15章 使用条件语句

第15章的总原则是让正常路径醒目、让互斥分支可证明、让默认路径有结论。审查时先写输入域,再把每个分支写成“条件 → 动作 → 输出”的三元组。若两个条件可以同时为真,先拆出命名谓词;若有输入没有归属,先补边界规则。

15.1 if语句

简单 if 适合表达“条件成立才执行”的单向动作,例如只有在缓存有效时才读取缓存。它不应被用来模拟一个没有说明的二选一:当条件为假时,代码应让“不执行”本身成为可理解的正常结果,或者改为显式的 if-then-else

简单if-then语句

简单 if-then 的主路径应靠近条件,并且动作要小到读者能在局部确认副作用。将 isAuthorizedhasCapacity 这类布尔判断命名后,条件表达式就从一串运算变成了可以讨论的业务事实;测试至少要包含真和假两侧。

if-then-else语句串

当输入有多个互斥等级时,if-then-else 串比多个并列 if 更能表达“只选一个结果”。先列出正常等级,再按互斥的替代等级排序,最后说明没有任何等级命中的默认动作。每加一个条件,都要问它是否与前面的范围重叠。

15.2 case语句

case 适合一个离散选择值对应多个互斥动作,例如状态、命令或菜单项。每个 case 应保持短小,选择值和动作要同层可见;不要把复杂范围判断硬塞进 case 标签后再让读者猜实际覆盖了什么。

为case选择最有效的排序

case 的排序同时服务于可读性和运行特征:把最常见且最能说明主流程的值放在前面,把危险或不合法输入放在可见的默认位置。排序不能改变互斥关系;如果频率数据尚未稳定,优先选择最容易审查的语义顺序,而不是凭感觉微优化。

使用case语句的提示

使用 case 时检查四点:是否处理了所有合法值,是否明确 break 或等价的退出,是否防止意外贯穿,是否让默认处理暴露新增值。对每个选择值保存输入、命中标签、输出和复位结果;这样重构排序后,独立复核者仍能重放同一组证据。

关键点

条件语句的关键点不是“少写几行”,而是让决策表能被另一位读者复算。正常路径、替代分支、默认拒绝和覆盖测试必须互相指向;如果无法给出一条输入的唯一归属,就先修合同,再谈语法风格。

专属因果实验

先预测改变“条件输入”或“默认分支”后,五节点链中哪一个节点最先变色。动手试:切换正常、恰好边界和故障输入,再用单步或播放查看条件从输入走到覆盖的过程;最后点击“重置实验”,确认场景、时间线、节点和状态文字回到基线。

分步1 / 3

1. 列出条件输入与边界

第15章 · 分支合同实验

条件输入 → 正常分支 → 默认拒绝 → 分支覆盖

先猜输入会在哪个节点被接受,再切换边界或故障,观察一条分支链怎样暴露遗漏。

当前焦点:条件输入
条件语句的分支合同domain 被完整覆盖;任意输入只能落入一个可解释路径1条件输入正常 / 边界 / 故障2正常分支先展示主路径3替代分支互斥且有名字4默认拒绝未知值不静默通过5分支覆盖每个输入有归属12345基线:输入先进入正常路径,其他已知输入进入替代路径当前代码草图:if (score >= 60) pass(); else review();审查记录保存:输入值 · 命中分支 · 首个偏离 · 默认结论 · 重置后的重放

第 1 / 5 步 · 先列出正常值、恰好边界和一个故障输入。

先预测首个偏离,再用单步或播放检查互斥与完备性。

红色只表示故障被定位到某个节点;修复的标准是重新运行同一个输入,得到同一条可解释路径。

术语与边界

本章用 6 个操作术语把语法连接到审查证据:。它们都必须能在实验按钮、节点或状态文字中找到对应证据。

本页小结

  • 先定义输入域,再证明分支互斥且完备。
  • 正常路径应醒目,异常路径应尽早拒绝或报告。
  • 复杂条件要命名,case 要检查退出和默认处理。
  • 正常、边界、故障与复位结果共同构成覆盖证据。

名词解释

本章出现的专业名词,用大白话再讲一遍。

条件表达式

一条告诉程序“下一步走哪条路”的判断,可以是布尔值,也可以是离散选择。

互斥分支

两个分支不能同时成立,因此同一个输入不会同时触发两套动作。

完备覆盖

输入域里的每个合法值都能找到一个归属分支,不会掉进未说明的空白处。

默认分支

没有其他条件命中时的明确处理;它可以拒绝、报告错误,也可以在证明不可达后记录该事实。

条件串

按顺序检查多个条件的 if-then-else 结构,通常只执行第一个命中的动作。

case 排序

安排 case 值出现顺序的方式;优先考虑主流程的可读性,再用稳定的频率证据优化。

练习

  1. 给出 score 为 59、60、61 和 -1 时的分支归属。指出哪一个输入能证明 score > 60 漏掉了边界,并写出一个带明确默认拒绝的修法。
  1. 把三个并列 if 重构为互斥的 if-then-else 串或 case,并说明你选择正常路径、替代路径和默认分支的排序理由。
  1. 完成第15章的覆盖清单:第15章 使用条件语句、15.1 if语句、简单if-then语句、if-then-else语句串、15.2 case语句、为case选择最有效的排序、使用case语句的提示、关键点。每项写出一个正文解释、一个实验节点和一条可重放证据。

讨论

评论区加载中…