Appearance
第7章 多层分支结构
🎯 本章学习目标
学完本章,你将能够:
- ✅ 掌握 if-else if-else 阶梯分支的用法
- ✅ 理解阶梯条件的排列顺序(严格条件在前)
- ✅ 掌握嵌套 if 的结构与 else 配对原则
- ✅ 牢记 else 总是与最近未配对的 if 配对
- ✅ 理解大括号的作用(界定语句块)
- ✅ 掌握逻辑运算符 &&、||、! 及短路求值
- ✅ 学会用短路求值避免除零错误
- ✅ 掌握 switch 语句的语法与规则
- ✅ 理解 case 穿透现象及 break 的作用
- ✅ 能灵活运用分支解决闰年、分段函数、计算器等问题
- ✅ 会用三目运算符
?:简洁地表达"二选一"取值 - ✅ 区分 = 赋值与 == 相等判断的区别
🗺️ 本章知识图谱
多层分支结构
├── if-else if-else 阶梯
│ ├── 语法:if → else if → else
│ ├── 执行规则:从上到下,第一个为真就执行
│ ├── 条件顺序:严格/特殊条件放前面
│ └── else 可省略(兜底分支)
├── 嵌套 if
│ ├── 定义:if 里面再写 if
│ ├── else 配对原则:最近未配对的 if
│ ├── 与缩进无关,只看代码结构
│ └── 大括号锁定配对关系
├── 逻辑运算符
│ ├── && 与(两边都真才真)
│ ├── || 或(一边真就真)
│ ├── ! 非(取反)
│ └── 短路求值
│ ├── && 左边假,右边不执行
│ └── || 左边真,右边不执行
├── 三目运算符 ?:(if-else 的表达式写法)
│ ├── 语法:条件 ? 值1 : 值2
│ ├── 本身有值,可嵌进表达式
│ └── 可嵌套分多档(超两层建议改回 if 阶梯)
├── switch 语句 ⭐⭐⭐
│ ├── 表达式类型:整型/字符型/枚举
│ ├── case 标签:必须是常量,不能重复
│ ├── break:跳出 switch
│ ├── case 穿透:无break就继续执行
│ ├── default:都不匹配时执行(可省略)
│ └── 多case共用:连续case做同一件事
├── 常见陷阱
│ ├── = 与 == 混淆(赋值 vs 相等)
│ ├── 忘写break导致穿透
│ ├── 阶梯条件顺序错误
│ └── 嵌套if中else配对错误
└── 经典应用
├── 成绩等级判定
├── 闰年判断
├── 分段函数计算
├── 简单计算器
└── BMI/票价分级一、为什么需要"多层分支"
一级我们学过最简单的 if:条件成立就做一件事,这叫单分支。但真实题目往往是"分情况讨论":
- 成绩分优秀、良好、中等、及格、不及格——五选一;
- 判断闰年要先看能不能被 400 整除,再看能不能被 100 整除,再看能不能被 4 整除——分支里面还有分支;
- 计算器要根据
+ - * /四种符号做四种运算——多路开关。
这些"多选一""分了又分"的结构,统称为多层分支结构。
| 分支形态 | 生活类比 | 对应语法 |
|---|---|---|
| 单分支 | 下雨就带伞 | if |
| 双分支 | 带伞 / 不带伞,二选一 | if ... else ... |
| 多分支(阶梯) | 成绩五档,对号入座 | if ... else if ... else |
| 嵌套分支 | 先看是不是周末,再看天气好不好 | if 里面再写 if |
| 多路开关 | 电梯按哪个楼层到哪个楼层 | switch |
二、if-else if-else 阶梯:多档对号入座
2.1 语法对照
当情况超过两种时,把 if ... else 串成"阶梯":
cpp
// C++
if (条件1) {
语句块1;
} else if (条件2) {
语句块2;
} else if (条件3) {
语句块3;
} else {
语句块4; // 以上条件都不满足时的"兜底"
}| 对照要素 | C++ |
|---|---|
| 条件位置 | 小括号内 if (x >= 90) |
| 语句块范围 | 大括号 { } 包裹 |
| "否则如果" | else if(两个单词) |
| "否则" | else |
| 块结束标志 | 右大括号 } |
执行规则:从上到下依次判断条件——
- 哪个条件第一个为真,就执行它对应的语句块;
- 执行完立即跳过整个阶梯,后面的条件再也不看;
- 所有条件都为假时,执行
else块;else可以省略(省略则什么都不做)。
高频考点 🔥:阶梯条件的"排列顺序"决定对错! 成绩判定必须从高到低写:先判
>=90,再>=80……如果反过来先判>=60,那么考 95 分的同学也会在第一个条件就命中"及格"——因为 95 确实 >= 60!范围有重叠时,越特殊、越严格的条件越要放前面。
2.2 例题1:成绩等级判定 ⭐⭐⭐⭐
题目: 输入一个 0~100 的整数成绩,输出等级:90 分及以上"优秀",80~89"良好",70~79"中等",60~69"及格",60 分以下"不及格"。
思路: 标准的五档阶梯。从高分往低分判断,命中即输出;用 else 兜底最低档。
cpp
#include <iostream>
using namespace std;
int main() {
int score;
cin >> score;
if (score >= 90) {
cout << "优秀" << endl;
} else if (score >= 80) { // 能走到这里,说明 score < 90
cout << "良好" << endl;
} else if (score >= 70) {
cout << "中等" << endl;
} else if (score >= 60) {
cout << "及格" << endl;
} else {
cout << "不及格" << endl;
}
return 0;
}
// 输入:85 输出:良好
// 输入:59 输出:不及格
// 输入:100 输出:优秀易错点 ⚠️: 有人喜欢把区间写"完整":
else if (score >= 80 && score < 90)。这样写不算错,但纯属多余——能走到第二个分支,本身就意味着第一个条件score >= 90已经为假。写全区间反而增加笔误风险(比如把< 90写成< 80就漏了一档)。
三、嵌套 if:分支里面还有分支
3.1 什么是嵌套
if 的语句块里再写一个 if,就是嵌套分支。它适合"先分大类、再分小类"的问题。
cpp
// C++:嵌套结构示意
if (外层条件) {
if (内层条件) {
...
} else {
...
}
} else {
...
}3.2 else 悬空配对原则 🔥🔥🔥
这是二级最高频的读程序陷阱,没有之一。
铁律:在 C++(以及 C)中,
else总是与它前面【最近的、还没有配对的】if配对——和缩进、和你"看起来"的对齐方式毫无关系!
cpp
int a = 3, b = 5;
if (a > 2)
if (b > 6)
cout << "A";
else // 缩进上"看起来"像配对外层 if
cout << "B"; // 实际上它配对的是最近的内层 if!手工执行: a=3 > 2 为真 → 进入内层判断:b=5 > 6 为假 → 执行内层 if 的 else → 输出 B。
很多同学按缩进误以为 else 配对外层、a>2 为真所以什么都不输出——错!编译器只认"最近未配对"原则。
避坑建议 ⚠️: 永远主动写大括号,把配对关系"锁死":
cppif (a > 2) { if (b > 6) cout << "A"; } else { // 有了大括号,这个 else 明确配对外层 if cout << "B"; }此时 a=3>2 为真、b=5>6 为假,程序什么都不输出——和上面的版本结果完全不同!
3.3 大括号与缩进:两种语言的"块"
| 话题 | C++ |
|---|---|
| 语句块界定 | 大括号 { } |
| 不写括号/缩进错误 | if 后只管辖第一条语句,第二条悄悄"脱管" |
| 最佳实践 | 哪怕只有一条语句也写上 { } |
cpp
// C++ 反面教材:不加大括号
if (score >= 60)
cout << "及格" << endl;
cout << "请继续努力" << endl; // ⚠️ 这行不属于 if!无论及不及格都会输出!小结: C++ 的大括号"可省但别省",让代码的视觉结构和逻辑结构保持一致。
3.4 例题2:闰年判断 ⭐⭐⭐⭐
题目: 输入年份 y,判断是否为闰年。闰年规则口诀:四年一闰,百年不闰,四百年再闰——能被 4 整除但不能被 100 整除,或能被 400 整除。
思路一(嵌套阶梯,体现多层分支): 按"400 → 100 → 4"的优先级逐层判断:
cpp
#include <iostream>
using namespace std;
int main() {
int y;
cin >> y;
bool leap;
if (y % 400 == 0) {
leap = true; // 能被400整除:一定是闰年(如2000年)
} else if (y % 100 == 0) {
leap = false; // 不能被400整除但能被100整除:平年(如1900年)
} else if (y % 4 == 0) {
leap = true; // 剩下的里面,能被4整除:闰年(如2024年)
} else {
leap = false; // 其余:平年
}
if (leap) cout << y << " 是闰年" << endl;
else cout << y << " 是平年" << endl;
return 0;
}
// 输入:2024 输出:2024 是闰年
// 输入:1900 输出:1900 是平年
// 输入:2000 输出:2000 是闰年思路二(逻辑运算符一行搞定): 嵌套分支和逻辑运算表达式经常可以互相改写:
cpp
bool leap = (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);高频考点 🔥: 闰年判断是二级"钉子户"题目。三个年份必须会验证:2024 闰年、1900 平年、2000 闰年。判断题常考"能被 4 整除的年份一定是闰年"——错,1900 能被 4 整除却是平年(百年不闰)。
四、逻辑运算符、短路求值与条件陷阱
4.1 三个逻辑运算符
| 含义 | C++ 运算符 | 为真的条件 |
|---|---|---|
| 与(并且) | && | 两边都为真 |
| 或(或者) | || | 两边有一个为真 |
| 非(取反) | ! | 真变假、假变真 |
真值表(用 1=真、0=假):
| a | b | a && b(与) | a || b(或) | !a(非) |
|---|---|---|---|---|
| 真 | 真 | 真 | 真 | 假 |
| 真 | 假 | 假 | 真 | 假 |
| 假 | 真 | 假 | 真 | 真 |
| 假 | 假 | 假 | 假 | 真 |
4.2 短路求值 🔥🔥
短路求值(Short-circuit):
&&:左边为假,右边根本不计算(假与任何数相与都是假,没必要再算);||:左边为真,右边根本不计算(真或任何数相或都是真)。
这个特性不只是"省时间",更是保命技巧——防止除零错误:
cpp
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 0;
// 若 b==0,b!=0 为假,&& 右边的 a/b 被短路,不会发生"除以0"!
if (b != 0 && a / b > 1) {
cout << "OK" << endl;
} else {
cout << "除数为0,已安全跳过" << endl;
}
return 0;
}
// 输出:除数为0,已安全跳过高频考点 🔥: 判断题爱考"
if (b != 0 && a / b > 1)当 b=0 时会发生除零错误"——错! 短路求值保护了右边。反过来,如果把顺序写反成if (a / b > 1 && b != 0),b=0 时程序就真的崩溃了——保护性条件必须放在&&的左边。
4.3 = 与 ==:一个等号的血案 ⚠️
| 写法 | 含义 | 后果 |
|---|---|---|
if (x == 5) | 判断 x 是否等于 5 | 正确写法 |
if (x = 5) | 把 5 赋值给 x,表达式的值是 5 | C++ 中 5 非 0 即"真",条件恒成立! |
if (x = 0) | 把 0 赋值给 x,表达式的值是 0 | 条件恒为假! |
C++ 编译器通常只给一个警告(warning),程序照样能编译运行——这种 bug 极难排查。
防坑小技巧: 判断相等时把常量写在左边:
if (5 == x)。一旦手滑写成5 = x,编译器会直接报错(常量不能被赋值),把运行期 bug 变成编译期错误。
五、switch 语句:C++ 的多路开关 🔥
5.1 为什么需要 switch
阶梯 if 能处理多分支,但当"判断条件"是一个变量等于若干个固定值时(如运算符 + - * /、菜单选项 1/2/3/4),C++ 提供了更清晰的开关语句 switch。
5.2 语法与执行流程
cpp
switch (表达式) // 表达式的值必须是【整型或字符型】
{
case 常量1:
语句1;
break; // 跳出 switch
case 常量2:
语句2;
break;
// ...
default:
兜底语句; // 所有 case 都不匹配时执行
}执行流程:计算 switch 后表达式的值 → 找值相等的 case 标签 → 从该标签处往下执行,遇到 break 跳出 switch;都不匹配则执行 default。
5.3 switch 规则速查表 🔥🔥
| 规则 | 说明 | 考频 |
|---|---|---|
| switch 后表达式类型 | 只能是整型、字符型、枚举;C++11 不支持浮点数、字符串、区间(如 case x>90: 是非法的) | 🔥🔥 |
| case 后标签 | 必须是整型/字符常量(如 case 1:、case '+':),不能是变量、表达式、范围;同一 switch 内不能重复 | 🔥🔥 |
break 的作用 | 执行到 break 立即跳出整个 switch;省略 break 会发生"case 穿透" | 🔥🔥🔥 |
| case 穿透 | 没有 break,程序会继续执行下一个 case 的语句,直到遇到 break 或 switch 结束 | 🔥🔥🔥 |
default | 所有 case 都不匹配时执行;可以省略;位置习惯放最后(语法上放哪都行) | 🔥 |
| 多 case 共用 | 连续写多个 case 标签可共用同一段语句(见 5.4) | 🔥 |
5.4 case 穿透:是陷阱也是工具
陷阱版——故意不写 break,看程序输出什么:
cpp
int n = 2;
switch (n) {
case 1: cout << "周一";
case 2: cout << "周二";
case 3: cout << "周三"; break;
case 4: cout << "周四"; break;
default: cout << "其他";
}
// n=1 输出:周一周二周三 (case 1 穿透 2、3,直到 break)
// n=2 输出:周二周三 (case 2 穿透 3)
// n=4 输出:周四
// n=9 输出:其他高频考点 🔥: 读程序题看到 switch,第一件事就是逐个 case 检查有没有 break!穿透不是"只穿透一个",而是一路执行到 break 为止——default 也挡不住穿透的脚步。
工具版——多个 case 做同一件事时,穿透反而让代码更简洁:
cpp
switch (grade) {
case 'A':
case 'B':
case 'C':
cout << "合格"; // A、B、C 三个等级都输出"合格"
break;
case 'D':
cout << "不合格";
break;
}5.5 例题3:简单计算器 ⭐⭐⭐⭐⭐
题目: 输入一个算式,格式为"数字 运算符 数字"(运算符为 + - * / 之一),输出运算结果;除数为 0 时提示错误,运算符非法时提示无效。
思路: 用 switch 根据运算符分四路;除法分支里再嵌套一个 if 判断除数是否为 0——这正是"switch 与嵌套 if 联手"的典型考法。
cpp
#include <iostream>
using namespace std;
int main() {
double a, b;
char op;
cin >> a >> op >> b; // 输入如:3 + 5 或 10/4
switch (op) {
case '+':
cout << a + b << endl;
break;
case '-':
cout << a - b << endl;
break;
case '*':
cout << a * b << endl;
break;
case '/':
if (b == 0) { // 嵌套 if:分支里面还有分支
cout << "除数不能为0" << endl;
} else {
cout << a / b << endl;
}
break;
default:
cout << "无效运算符" << endl;
}
return 0;
}
// 输入:3 + 5 输出:8
// 输入:10 / 4 输出:2.5
// 输入:6 / 0 输出:除数不能为0
// 输入:7 % 2 输出:无效运算符易错点 ⚠️:switch 四大笔误汇总—— ①
case后忘写冒号写成case 1(应为case 1:); ② case 后写变量或区间:case x:、case score>=90:都是编译错误; ③ 该写 break 不写,逻辑莫名其妙"多做了好几件事"; ④ switch 里放字符串表达式(C++11 不支持)。
六、三目运算符:if-else 的极简写法
有些分支很简单——条件成立取一个值,不成立取另一个值。为这么一句话写满 if...else 大括号,未免啰嗦。C++ 提供了一个"缩写版 if-else"——三目运算符(也叫条件运算符),因为它用 ? 和 : 两个符号把三个部分串起来,故得此名。
6.1 语法与执行规则
cpp
条件 ? 表达式1 : 表达式2先算"条件":为真就取"表达式1"的值,为假就取"表达式2"的值。
关键点:三目运算符是一个"表达式"——它本身有值,可以像普通数值一样参与运算或赋给变量,这一点和 if-else 语句有本质区别。
例: 取 a、b 中的较大值:
cpp
int a = 7, b = 3;
int maxVal = (a > b) ? a : b; // a>b 为真,取 a,maxVal = 7它等价于:
cpp
int maxVal;
if (a > b) maxVal = a;
else maxVal = b;6.2 与 if-else 的对应关系
| 写法 | 形式 | 有没有"值" |
|---|---|---|
| if-else 语句 | if (c) x = 1; else x = 2; | ❌ 是语句,没有值 |
| 三目运算符 | x = c ? 1 : 2; | ✅ 有值,能嵌进表达式 |
正因为"有值",三目运算符可以直接写在其它表达式里,例如放进输出语句:
cpp
cout << "成绩:" << score << ((score >= 60) ? " 及格" : " 不及格") << endl;6.3 嵌套三目:可以,但要慎用
三目运算符可以嵌套(在"表达式1 或 2"的位置再写一个三目),一次分三档:
cpp
// 成绩等级:>=90 优秀(A),>=60 及格(B),否则不及格(C)
char grade = (score >= 90) ? 'A' : (score >= 60 ? 'B' : 'C');虽然紧凑,但嵌套一多,可读性会明显变差。二级考试中,分段超过两档时,建议仍旧用 if-else if 阶梯,更清晰、也更不易写错。
易错点 ⚠️: ① 两个分支的类型要兼容,否则会做隐式转换——如
x > 0 ? 1 : 2.5的结果整体是double; ② 别把?和:的位置写反或漏写; ③ 它只适合"二选一取值"。若两个分支要做的事不止"取一个值"(比如各自输出多行、同时修改多个变量),还是老老实实用if-else。
高频考点 🔥: 三目运算符在二级属于"了解 + 会用"级别,常出现在程序阅读题里让你算结果,或编程题里简化"求最值、判断奇偶、输出及格与否"。记住:它是表达式(有值),不是语句——这是与
if-else最本质的区别。
七、读程序写输出:分支题解题三步法
二级的"读程序写输出"题,分支结构出现率极高。按三步走,稳拿分:
第一步:找入口、顺流程。 从 main 第一行开始,按顺序执行,遇到 if 就代入当前变量值判真假。 第二步:列变量变化表。 草稿纸上写下每个变量的当前值,每次赋值/输入立即更新——绝不靠眼睛硬看。 第三步:遇结构"对号入座"。
- 阶梯 if:从第一个条件往下找第一个为真的,其余跳过;
- 嵌套 if:先在纸上给每个 else 画条线连到它配对的 if(最近未配对原则!);
- switch:先找匹配的 case,再逐行检查 break,标出穿透会执行到哪一行。
八、📝 实战练习
练习题 1(程序阅读题)
题目: 下面程序的输出是( )
cpp
#include <iostream>
using namespace std;
int main() {
int x = 1;
switch (x) {
case 1: cout << "A";
case 2: cout << "B";
default: cout << "C";
case 3: cout << "D"; break;
}
return 0;
}A. A B. AB C. ABCD D. ACD
🔑 点击查看答案与解析
答案: C
解析: x=1 匹配 case 1,输出 A;没有 break,穿透! 继续执行 case 2 输出 B;仍无 break,穿透到 default 输出 C;继续穿透到 case 3 输出 D,遇到 break 跳出。最终输出 ABCD。注意:穿透不区分 case 和 default,default 也挡不住。
练习题 2(程序阅读题)
题目: 下面程序的输出是( )
cpp
#include <iostream>
using namespace std;
int main() {
int a = 5, b = 2;
if (a > 3)
if (b > 3)
cout << "X";
else
cout << "Y";
return 0;
}A. X B. Y C. XY D. 无输出
🔑 点击查看答案与解析
答案: B
解析: 按"else 与最近未配对的 if 配对"原则,这个 else 配对的是内层 if (b > 3),而非缩进上看起来的外层。执行:a=5>3 为真 → 进入内层:b=2>3 为假 → 执行内层 else → 输出 Y。
练习题 3(编程题)
题目: 输入实数 x,按分段函数计算并输出 y:
| x + 1 , x < 0
y = | x * x , 0 ≤ x < 10
| 2*x + 3, x ≥ 10🔑 点击查看答案与解析
思路: 三段阶梯。第一个分支判 x<0;第二个分支能走到就说明 x≥0,只需再判 x<10;剩下的 else 兜底 x≥10。
参考答案(C++11):
cpp
#include <iostream>
using namespace std;
int main() {
double x, y;
cin >> x;
if (x < 0) {
y = x + 1;
} else if (x < 10) { // 走到这里必然 x >= 0
y = x * x;
} else { // x >= 10
y = 2 * x + 3;
}
cout << y << endl;
return 0;
}
// 输入:-5 输出:-4
// 输入:3 输出:9
// 输入:10 输出:23手工验证: x=-5 → -5+1=-4 ✅;x=3 → 3×3=9 ✅;x=10 → 2×10+3=23 ✅。边界点 x=0 落到第二支(0×0=0),x=10 落到第三支,符合"含等号归右边区间"的定义。
练习题 4(编程题)
题目: 输入体重 w(千克)和身高 h(米),计算 BMI = w ÷ (h × h),并判定:BMI < 18.5 为"偏瘦",18.5 ≤ BMI < 24 为"正常",24 ≤ BMI < 28 为"超重",BMI ≥ 28 为"肥胖"。
🔑 点击查看答案与解析
参考答案(C++11):
cpp
#include <iostream>
using namespace std;
int main() {
double w, h;
cin >> w >> h;
double bmi = w / (h * h);
if (bmi < 18.5) {
cout << "偏瘦" << endl;
} else if (bmi < 24) {
cout << "正常" << endl;
} else if (bmi < 28) {
cout << "超重" << endl;
} else {
cout << "肥胖" << endl;
}
return 0;
}
// 输入:70 1.75 BMI=70/(1.75*1.75)=70/3.0625≈22.86 输出:正常
// 输入:50 1.7 BMI=50/2.89≈17.30 输出:偏瘦
// 输入:90 1.7 BMI=90/2.89≈31.14 输出:肥胖解析要点: 阈值按从小到大排列,每个分支只需写上界(下界由前面的分支不成立隐式保证)。注意身高单位是米不是厘米,输入 175 要写成 1.75——变量单位是这类生活题的常见坑。
练习题 5(程序阅读题)
题目: 阅读以下 C++ 程序,写出当 x=5, y=8 时的输出:
cpp
#include <iostream>
using namespace std;
int main() {
int x = 5, y = 8;
if (x > 3)
if (y > 10)
cout << "A";
else
cout << "B";
else
cout << "C";
cout << endl;
return 0;
}A. A B. B C. C D. AB
🔑 点击查看答案与解析
答案: B
解析: 按"else 与最近未配对的 if 配对"原则:
- 第 1 个 else(第 8 行)与最近的内层
if (y > 10)配对; - 第 2 个 else(第 10 行)与外层
if (x > 3)配对。
执行:x=5 > 3 为真 → 进入内层:y=8 > 10 为假 → 执行内层 else → 输出 B。
🔥 这是二级最高频的读程序陷阱——缩进会骗人,编译器只认"最近未配对"原则。解题时建议在草稿纸上用画线法把每个 else 和它配对的 if 连起来。
练习题 6(单选题)
题目: 执行以下代码后,变量 b 和 c 的值分别是( )
cpp
int a = 0, b = 5, c = 3;
if (a != 0 && b++ > 4) {
c++;
}A. b=5, c=3 B. b=6, c=3 C. b=5, c=4 D. b=6, c=4
🔑 点击查看答案与解析
答案: A
解析: && 是短路与——左边为假,右边不执行。
- a=0,
a != 0为假 →&&短路,右边的b++ > 4根本不执行 → b 的值不变,还是 5; - 整个 if 条件为假 → c++ 不执行 → c 的值不变,还是 3。
选 A。
🔥 高频考点:短路求值不只是"省时间",更重要的是右边表达式的副作用(如 b++、赋值、函数调用)都不会发生。判断题常考"b++ 一定会执行"——错!要看短路有没有发生。
💡 防坑技巧:保护性条件(如
b != 0)一定要放在&&的左边,这样才能保护右边的a/b不发生除零错误。
练习题 7(判断题)
题目: 判断下列说法是否正确,正确的打 ✓,错误的打 ×。
① switch 语句的表达式可以是 float 类型。( )
② case 后面可以跟变量或表达式。( )
③ 每个 case 后面都必须有 break,否则编译报错。( )
④ default 子句可以省略,也可以放在 switch 的任意位置。( )
⑤ case 穿透时,会从匹配的 case 开始一直执行,直到遇到 break 或 switch 结束。( )
⑥ switch 中可以嵌套 if 语句,if 中也可以嵌套 switch。( )
🔑 点击查看答案与解析
答案: ① × ② × ③ × ④ ✓ ⑤ ✓ ⑥ ✓
解析:
- ① ×:switch 表达式只能是整型、字符型、枚举型,不能是 float/double/string;
- ② ×:case 后必须是常量(字面量或 const 常量),不能是变量或表达式(如
case x:、case a+b:都是错的); - ③ ×:不写 break 不会编译报错,但会发生case 穿透——逻辑错误,不是语法错误;
- ④ ✓:default 可省略(所有 case 都不匹配时什么都不做),位置也灵活(习惯放最后,但放中间语法也对);
- ⑤ ✓:这正是 case 穿透的定义——没有 break 就"一路向下",穿透所有后续 case,甚至穿透 default;
- ⑥ ✓:分支结构可以任意嵌套,switch 里可以写 if,if 里也可以写 switch,只要语法正确即可。
练习题 8(判断题)
题目: 输入年份和月份,输出该月有多少天。要求:用 switch 语句实现,2 月需要判断闰年(闰年 29 天,平年 28 天)。
输入样例1:
2024 2输出样例1:
29天输入样例2:
2023 4输出样例2:
30天🔑 点击查看答案与解析
参考代码(C++):
cpp
#include <iostream>
using namespace std;
int main() {
int year, month;
cin >> year >> month;
int days;
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31; // 大月:31天(7个大月)
break;
case 4: case 6: case 9: case 11:
days = 30; // 小月:30天(4个小月)
break;
case 2:
// 2月:判断闰年
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
days = 29; // 闰年2月29天
} else {
days = 28; // 平年2月28天
}
break;
default:
days = -1; // 非法月份
cout << "输入错误" << endl;
return 1;
}
cout << days << "天" << endl;
return 0;
}
// 输入 2024 2 → 2024是闰年 → 29天 ✅
// 输入 2023 4 → 4月是小月 → 30天 ✅解析要点:
- 利用 case 穿透让多个月份共用相同的天数(连续写 case 标签);
- 2 月特殊处理:switch 内部嵌套 if 判断闰年,这是"switch + if 联手"的经典考法;
- 闰年公式:
(能被4整除且不能被100整除) 或 能被400整除; - default 处理非法输入,增加程序健壮性。
🍎 生活比喻:switch 就像电梯,case 是楼层按钮——你按了几楼就在几楼下(匹配到哪个 case 就从哪开始执行);break 是"出电梯"——没有 break 就每层都经过(穿透)。大月小月的 case 穿透就像"同一种户型的楼层合并停靠"。
九、📊 考点总结表
| 考点 | 重要程度 | 出题形式 |
|---|---|---|
| if-else if 阶梯的执行规则(命中即跳出) | ⭐⭐⭐⭐ | 选择/编程 |
| 阶梯条件排列顺序(严格条件在前) | ⭐⭐⭐⭐ | 编程/判断 |
| 嵌套 if 与 else 悬空配对(最近未配对原则) | ⭐⭐⭐⭐⭐ | 读程序写输出 |
| 大括号的作用 | ⭐⭐⭐⭐ | 判断/编程 |
| 逻辑运算符 && || ! | ⭐⭐⭐⭐ | 选择/编程 |
| 短路求值(防除零、保护性条件放左边) | ⭐⭐⭐⭐⭐ | 选择/判断 |
三目运算符 ?:(是表达式、二选一取值) | ⭐⭐⭐ | 选择/读程序 |
= 赋值与 == 相等陷阱 | ⭐⭐⭐⭐ | 判断/读程序 |
| switch 语法(整型/字符表达式、case 常量) | ⭐⭐⭐⭐ | 选择/判断 |
| case 穿透与 break 的作用 | ⭐⭐⭐⭐⭐ | 读程序/选择 |
| default 可省略、位置任意 | ⭐⭐⭐ | 判断 |
| 成绩等级、闰年、分段函数、计算器、BMI/票价 | ⭐⭐⭐⭐⭐ | 编程大题 |
⭐ 必背速记卡
┌─────────────────────────────────────────────────────┐
│ 1. 阶梯if:从上到下,第一个为真就执行,后面全跳过 │
│ 2. 阶梯条件顺序:越严格越特殊的放前面 │
│ 3. else配对原则:与最近未配对的if配对,与缩进无关 │
│ 4. 大括号能锁定配对关系,建议永远都写 │
│ 5. if后不写大括号,只管辖第一条语句 │
│ 6. && 与:两边都真才真,左边假则短路(右边不执行) │
│ 7. || 或:一边真就真,左边真则短路(右边不执行) │
│ 8. ! 非:真变假,假变真 │
│ 9. 短路求值能防除零:b!=0 && a/b,保护性条件放左边 │
│ 10. switch表达式:只能整型/字符型,不能浮点/字符串 │
│ 11. case后必须是常量,不能是变量或表达式 │
│ 12. case穿透:无break就继续执行,直到break或结束 │
│ 13. default可省略、位置任意,所有case都不匹配才执行 │
│ 14. = 是赋值,== 是相等判断,别搞混! │
│ 15. 常量写左边防手滑:if (5 == x) 而不是 if (x == 5) │
│ 16. 三目运算符 c?x:y 是表达式(有值):二选一的简写 │
└─────────────────────────────────────────────────────┘下一章预告:第 8 章 · 多层循环语句
分支让程序学会"选择",循环让程序学会"重复"。下一章我们攻克二级语法的另一半江山:
- 多层循环嵌套:外层走一步、内层走一圈,打印图形题的套路
- 循环 + 分支联手:累加、累乘、计数、找最大最小值
- break 与 continue 的区别(又是一对读程序高频考点)
- 读程序写输出中的"循环追踪表"画法
循环是编程题分值的真正主力,下一章见!🎯
