选择结构

官方信息技术老师·12 页·深入(追求细节与边界)·0 次浏览·3 天前
分支控制条件判断边界陷阱逻辑流程

选择结构

看透 if / switch 每条分支的细节、坑点与边界

按 空格/→ 演示下一步

1 / 12 页

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

分支控制条件判断边界陷阱逻辑流程

选择结构

看透 if / switch 每条分支的细节、坑点与边界

1第 1 页 · 选择结构

选择与条件构造

上一节我们知道了选择结构让程序有了'岔路口',但路口靠什么决定走哪边?靠的是条件。这一节我们来拆解条件本身。

条件本质
判断的结果只能是 true 或 false,二选一
关系运算
用 ==、!=、>、<、>=、<= 比较值的关系
逻辑运算
与(and)全真才真、或(or)一真即真、非(not)取反
短路求值
A 且 B:若 A 为假,B 不再计算
德摩根定律
not(A 且 B) ≡ not A 或 not B,反之亦然
多个闸机的门禁系统对应 →复合条件组合

串联闸机=必须全过(AND);并联闸机=任一通过(OR)

¬(AB)(¬A)(¬B)\neg(A \land B) \equiv (\neg A) \lor (\neg B)
2第 2 页 · 选择与条件构造

if语句

上一页我们构造了条件,这一页看条件如何驱动分支。'如果下雨就带伞、否则不带'——if 语句正是这种条件→动作判断的直接翻译。

三段式骨架
if/elif/else 加冒号,靠缩进圈定每个分支的范围
条件真假判定
除 False/None/0/空容器外,其他值都视为真
互斥与顺序敏感
命中任一分支即跳出,后续 elif/else 不再判断
嵌套与边界陷阱
嵌套越深越难维护;注意 = 与 == 区分、空 if 体需占位
医院分诊台对应 →if/elif 链

按症状优先级逐个匹配科室,第一个命中即收治

3第 3 页 · if语句

switch语句

if 擅长范围判断与复杂条件,但反复检查同一变量等于某个固定值时——比如命令码分发、星期映射——一长串 if-else if 既啰嗦又易漏 break。switch 正是为「多分支等值匹配」量身打造的语法。

离散值匹配
只能判断「等于某个具体值」,不能像 if 那样做范围或复合条件
case 常量标签
每个 case 后必须是编译期可确定的常量,且整组 case 值互不相同
break 与穿透
正常用 break 跳出当前 case;漏写则继续执行下一个 case,可被有意利用
default 兜底
所有 case 都不匹配时执行,作用对应 if-else 链末尾的 else
表达式化升级
Java 14+、C# 8+、Rust 等允许 switch 直接返回值,更简洁也更安全
自动售货机对应 →switch 语句

按 A1 出 A1 的饮料;乱按无响应(对应 default 缺失或命中);取走不及时饮料掉到下一层(穿透)

4第 4 页 · switch语句

选择结构嵌套

前面学过 if 和 switch 都是「问一个问题,根据答案走不同路」。但现实中问题常常一个套一个——先满足 A,再在 A 内问 B。这种「选完再选」的结构,就是嵌套。

嵌套定义
分支内部再放一个完整的选择结构,外层不成立就不进内层
悬空 else
else 总配对它前面最近的、尚未配对的 if,与缩进无关
嵌套深度
建议不超过 3 层;过深用函数封装或早 return
多级分类
先按大类分支,再按子类细分,典型如成绩等级+是否特殊
医院分诊流程对应 →选择结构嵌套

先按科室分流;进了科室再按病情细分;每层判断都依赖上一层的结果

5第 5 页 · 选择结构嵌套

switch语句编程

前面认识了switch的基本思想,现在要把它写成能跑的代码。它和if-else链像亲戚,但有几条硬规矩——不遵守,程序会跑出你意想不到的结果。

表达式只算一次
switch先对表达式求值一次,再用结果逐个匹配case,避免了if-else链每次重复求值
break防穿透
case匹配后若不写break,会继续执行下一个case——这叫fall-through,是switch最常见的bug
default兜底
所有case都不匹配时执行的分支,类似else;省略则未匹配的值会静默跳过
case值必须是常量
只能取字面常量或枚举常量,不能是变量,也不能写范围(case 1..5会报错)
典型应用场景
适合离散值的精确匹配:菜单选项、命令分发、状态码处理、月份天数查询
电梯按钮面板对应 →switch语句

你按几楼就只停那层并开门(break);按了无效楼层就走默认路线(default)

6第 6 页 · switch语句编程

选择结构常见错误分析

前面我们用 if 和 switch 写出了可运行的程序,但「能编译」「能运行」并不等于「正确」。选择结构中有些错误不会让程序崩溃,却悄悄给出错误的结果——下面剖析 4 类最隐蔽的陷阱。

悬空 else 归属歧义
嵌套 if 中 else 默认匹配最近的 if,缩进不影响语法,代码排版与实际归属错位
赋值与比较混淆
if(x=0) 是赋值且恒假,if(x==0) 才是等于判断;少写一个等号,意图截然相反
switch 缺 break 穿透
case 分支不自动终止,缺 break 会掉进下一分支继续执行
浮点数等值比较
0.1+0.2 == 0.3 为假,二进制小数无法精确表示十进制 0.3
把「他是张三」写成「让他是张三」对应 →== 与 = 的混淆

中文里「是」是判断、「设为」是动作,靠字区分;代码里全靠等号个数,差一个角色互换

7第 7 页 · 选择结构常见错误分析

二级C考点解析之条件的正

你去网吧上网,前台要查三件事:满18岁、没欠费、带了身份证——全过才放行。程序里的「条件」也是同一个意思:写一个表达式,让计算机判断一次,结果只有真或假。

条件的本质
任何C表达式都行,非零即为真、零即为假,不一定非是比较
关系运算
==、!=、>、<、>=、<=共六种,结果只可能是0或1
逻辑运算
&&全真才真、||一真即真、!取反,把多个条件串起来
经典陷阱
= 是赋值、== 才是比较,if(a=1) 永远成立,是高频丢分点
短路求值
A&&B:若 A 已为假则跳过 B;A||B:若 A 已为真则跳过 B
网吧前台多重安检对应 →复合条件的逻辑组合

&& 像三关全过才放行,|| 像满足一条就放行;前一关不过,后面的检查直接跳过

f(x)={1,x00,x=0f(x) = \begin{cases} 1, & x \neq 0 \\ 0, & x = 0 \end{cases}
8第 8 页 · 二级C考点解析之条件的正

二级C考点解析之if语句

前页我们看了条件怎么写才不出错,但条件装进 if 里时,C 语言还有几个坑专门等着考生——尤其是选择题爱考的细节。

三种基本形式
单分支、双分支、多分支(if-else if),覆盖所有判断场景
else就近配对
else 总是与它前面最近的、未配对的 if 组成一对
if后分号陷阱
if(条件); 多加的分号会结束 if 体,导致逻辑错误
赋值vs比较
条件里把 == 写成 = 是赋值,恒为真且不易察觉
代码里的括号对应 →if-else配对

左括号找最近的右括号配对,if也找最近的else配对

9第 9 页 · 二级C考点解析之if语句

二级C考点解析之switch语

前面梳理了 if 的考点——它擅长判断范围和处理复杂条件。但变量只在几个固定值里挑一个时,if 链就显得笨重。C 语言为此提供了「按值跳转」的 switch 捷径。

switch 表达式类型
必须为整型、字符型或枚举型,浮点和字符串都不行
case 常量要求
后面必须是整型常量表达式,不可重复、不可是变量
break 控制穿透
每个 case 通常以 break 结尾,否则落入下一个 case 继续执行
default 分支
所有 case 都未匹配时执行,位置灵活但建议放末尾
执行起点
匹配到某 case 后从该位置顺序执行,不再重新判断条件
自动售货机按键对应 →switch 分支跳转

按 B5 机器直接吐出对应货品;switch 根据值直接定位到匹配 case

switch (表达式){case 常量1: 语句; break;case 常量2: 语句; break;default: 语句;}\text{switch (表达式)} \{ \text{case 常量1: 语句; break;} \cdots \text{case 常量2: 语句; break;} \text{default: 语句;} \}
10第 10 页 · 二级C考点解析之switch语

本节要点

  • if 处理范围与复合条件,switch 只做离散等值
  • 浮点判等是高危区,需转整型或加 eps 容差
  • 漏 break 即穿透,default 写哪都行
  • 嵌套层数 ≤3,超出就拆函数或早返回
  • 复杂条件先抽布尔变量,可读性优先于简洁
延伸主题:for/while/do-while循环break/continue/goto程序三大基本结构
11第 11 页 · 本节要点

课后思考

先独立思考每个问题,再对照参考答案。开放题没有唯一答案,关键在于理清思路。

1if 条件里写成 `if (a = 5)` 而非 `if (a == 5)`,编译器为什么不报错?这体现了 C 语言的什么设计哲学?

参考答案C 把赋值视为合法表达式,`a=5` 返回 5 即真。这种「信任程序员」的设计提高了灵活性,但也埋下无数 bug。GCC 的 -Wall 可开启警告提醒。

2判断成绩所属等级时,if-else 嵌套和 switch-case 各有什么适用场景?背后的判断依据是什么?

参考答案取决于写法。直接对分数做区间判断(score>=90 等),只能用 if-else;若先除以 10 映射成离散等级,switch 更高效。关键看分支条件是连续区间还是离散常量。

3C 的 switch 要求 case 必须是常量表达式。如果放开这个限制会怎样?从底层实现角度分析原因。

参考答案放开限制编译器就难以生成跳转表,只能退化为类似 if-else 的串行比较,丧失 O(1) 跳转优势。case 标签本质是汇编层的地址偏移量,必须编译期确定。

12第 12 页 · 课后思考