路径中的再选择——嵌套判断

官官方信息技术老师·20 页·深入(追求细节与边界)·0 次浏览·38 天前
条件分支嵌套结构流程图

嵌套判断:路径中的再选择

看完你能画出多层分支的完整流程图,并说清每层判断的职责边界

按 空格/→ 演示下一步

问一句
1 / 20 页

全部页面点击任意一页,跳回舞台从这页播放

条件分支嵌套结构流程图

嵌套判断:路径中的再选择

看完你能画出多层分支的完整流程图,并说清每层判断的职责边界

1第 1 页 · 嵌套判断:路径中的再选择

什么是 if 的嵌套

上一页说嵌套是「路径中的再选择」。想想真实场景:你先进了写字楼大门,这只是一次判断;进了大堂还得看门牌,找电梯上楼——进门是第一层判断,看门牌是进门之后才发生的第二层判断。

分支体内再写 if
外层 if 的代码块里,完整地再放一个 if 判断
谁包含谁
外层是前提,内层只有在外层条件成立时才轮到执行
缩进表层级
内层 if 多缩进一层,缩进就是「包含关系」的视觉证据
进门后再看门牌对应 →if 的嵌套

进门成功对应外层条件成立,看门牌对应内层 if

2第 2 页 · 什么是 if 的嵌套

嵌套的执行路径

从上往下读:只有通过外层条件这道门,才会走到内层判断;通不过就绕道,内层根本不执行。

图解渲染中…
c1:外层不成立时内层判断完全不会执行,这就是嵌套的门卫效应d1:内层条件只有在外层通过后才会被求值
3第 3 页 · 嵌套的执行路径

嵌套的语法与缩进

python

看一段真实可运行的嵌套 if:外层判断门票资格,内层判断折扣,缩进体现谁包含谁。

代码高亮加载中…

第 4 行是外层判断;第 6 行比它多缩进一层,说明内层 if 被「包」在外层成立之后才执行;第 10 行的 else 与第 4 行对齐,属于外层。

4第 4 页 · 嵌套的语法与缩进

嵌套 if vs else-if 链

两种写法都像"多条件选择",但语义完全不同:一个是层层包含,一个是并列互斥。混用会写出错误逻辑。

嵌套 if
  • 分支之间是包含关系
  • 外层不成立,内层不执行
  • 用于前提出成立才有后续判断
else-if 链
  • 分支之间是并列互斥关系
  • 命中一个,其余全部跳过
  • 用于同一变量的多种取值分类
当条件有前提依赖(A 成立才需判断 B)选嵌套;当条件是同一层级的互斥分类选 else-if 链。
5第 5 页 · 嵌套 if vs else-if 链

小测:else 配对谁

点击作答

阅读这段代码:if (a > 0) { if (b > 0) { print("A"); } else { print("B"); } } 当 a=-1、b=5 时输出什么?

6第 6 页 · 小测:else 配对谁

悬空 else 问题

上一页的小测里,else 写在两层缩进之间——它属于谁?编译器不靠缩进,只按一条铁律配对:就近原则。于是悬空 else 的真实归属,常和眼睛看到的不一样。

就近原则
else 总是与它上方最近的、尚未配对的 if 结合
缩进不参与
编译器只看语法结构,缩进只是给人看的提示
悬空的代价
逻辑挂到内层 if 上,外层为假时整段不执行
解法:加大括号
花括号显式圈定归属,消除歧义
排队认亲对应 →else 配对

else 像找人认领,只能牵起离自己最近、还没被牵走的那只手

7第 7 页 · 悬空 else 问题

用花括号消除歧义

c

同一逻辑加不加花括号,else 的配对对象完全不同——两段可运行代码直接对比。

代码高亮加载中…

a=1>0 且 b=2>0,两版都只打印 both;但 v1 的 else 挂在内层 if 上,v2 靠花括号把 else 明确挂到外层 if。

8第 8 页 · 用花括号消除歧义

嵌套层次的结构图

从上往下读:每个菱形是一次判断,其下方的分支就是它的管辖范围,越深的条件管辖范围越小。

图解渲染中…
f1:虚线强调:内层整个位于外层『是』分支之内,『否』分支与之无关a1:菱形/方块表示一次判断节点,编号从外到内逐层深入
9第 9 页 · 嵌套层次的结构图

小测:判断输出结果

点击作答

有代码:x=6; if(x>5){ if(x>10){ print("A") } else { print("B") } },运行输出什么?

10第 10 页 · 小测:判断输出结果

问题拆解:怎样比才不遗漏

前面我们见过嵌套的写法和 else-if 链,但真正动手时先要回答一个问题:判断三个数谁最大,到底要比几次、每次比完走哪条路?先把「比什么、比几回」规划清楚,代码才不会写漏。

比较次数下限
三个数比大小,至少比较 2 次才能定出最大值
两两比较
先比 a 和 b,胜者再和 c 比,共 2~3 次
分支规划
每次比较分两路,先画路径图再写嵌套
遗漏情形
共 6 种大小排列,每种都要有路径覆盖
淘汰赛对应 →两两比较

第一场胜者晋级,再和第三人争夺冠军,场次对应比较次数

11第 11 页 · 问题拆解:怎样比才不遗漏

排序的判断流程

三个数排序,拆成三次两两比较,每层嵌套定下一个位置。

1
先比前两个
外层 if 比较 a 和 b,把较大者暂时当作候选最大值
2
和第三个比
在 winner 分支内再 if 一次,胜者与 c 比较,定出真正的最大值
3
else 定次大
落败的一方与剩下那个数再比较,确定中间值
4
收尾最小值
最后剩下的自然是最小值,无需再比较,直接输出
12第 12 页 · 排序的判断流程

排序代码实现

python

用嵌套 if 实现三个数的完整排序:每层比较后交换,保证 a≤b≤c。

代码高亮加载中…

高亮行展示「再选择」:b>c 成立触发交换后,还需嵌套 if 再检查 a、b——这正是路径中的再判断。

13第 13 页 · 排序代码实现

小测:边界输入

点击作答

用 a、b、c 三个数找最大值,判断写成 if(a>b && a>c){max=a} else if(b>c){max=b} else {max=c}。当 a=b=5、c=3 时,结果是?

14第 14 页 · 小测:边界输入

登录检查要查几道门

前一页我们用嵌套处理了排序的边界,现在换个场景:登录。系统不会只问一次密码——先看用户名存不存在,存在才验密码。每道门都过,才放行。

层层设卡
外层 if 验用户名,内层 if 验密码,各挡一种错误
失败即止
用户名不存在就直接拒绝,不必再验密码
提示更精准
不同的 else 给不同提示:用户名错和密码错分开说
小区门禁对应 →嵌套 if

大门验身份对应验用户名,单元门验密码对应验密码

15第 15 页 · 登录检查要查几道门

逐层校验的流程

登录检查像过两道门:先验用户名,再验密码,各给反馈。

1
查用户名
外层 if 查询用户名是否存在,这一步决定走哪条路径
2
不存在分支
else 提示『用户不存在』,直接结束,不再往下查
3
查密码
用户名存在时进入内层 if,比对密码是否正确
4
给结论
内层 if/else 分别输出『登录成功』或『密码错误』
16第 16 页 · 逐层校验的流程

登录检查代码实现

python

把三道门写进嵌套 if,看错误提示如何一层层过滤出具体原因。

代码高亮加载中…

嵌套版中每道门都是「通过才进内层」,失败立刻给出对应提示——错误的分层正来自判断的分层。

17第 17 页 · 登录检查代码实现

顺序不同,提示不同

同样查两道门,先查密码还是先查用户名?顺序不同,报错信息和判断逻辑都会不一样。

先查用户名
  • 先确认身份,再验密码
  • 密码错时提示"密码不正确"
  • 用户名不存在时不泄露密码检查逻辑
先查密码
  • 先验密码,再确认身份
  • 用户名错时提示"用户不存在"
  • 可能向攻击者暴露哪些账号存在
面向安全性选左:先用户名后密码,避免泄露账号信息;教学演示判断顺序时可先写右版再改。
18第 18 页 · 顺序不同,提示不同

要点收束

  • ✓if 进 else:先猜配对,再看缩进,花括号是铁证
  • ✓嵌套 vs else-if:前者的分支里还能再问,后者问完即止
  • ✓比大小不遗漏:先定全序,两两比较,等号单独处理
  • ✓逐层校验:每道门只拦一种错,先拦的先提示
延伸主题:逻辑运算符 && 与 || 能少写几层嵌套吗early return:用提前返回拍平嵌套switch 与多分支选择的适用边界
19第 19 页 · 要点收束

课后思考

三个问题先自己想,再看参考答案——答案只是起点。

1深层嵌套的代码,你是按什么顺序读的?缩进和 else 配对谁,哪个先看?

参考答案先看缩进层级定结构,再由内层 else 向上找最近未配对的 if。可试着把登录检查代码口头「翻译」成流程图验证。

2登录检查那道门,如果调换两个判断的顺序,用户看到的提示会怎么变?什么时候顺序不重要?

参考答案顺序决定提示的先后:靠前的判断先拦截,提示它对应的问题。各分支互不影响结果时顺序才无所谓,可回看「顺序不同,提示不同」一页对照。

3如果判断条件里出现 a<b<c 这类边界,你会设计哪些输入来验证漏没漏?

参考答案取每个边界的两侧值加等于值,如 x==10 时试 9、10、11,再试极端值。目标是让每个分支至少被踩中一次。

20第 20 页 · 课后思考