Skip to content

第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
块结束标志右大括号 }

执行规则:从上到下依次判断条件——

  1. 哪个条件第一个为真,就执行它对应的语句块;
  2. 执行完立即跳过整个阶梯,后面的条件再也不看;
  3. 所有条件都为假时,执行 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 为真所以什么都不输出——错!编译器只认"最近未配对"原则。

避坑建议 ⚠️: 永远主动写大括号,把配对关系"锁死":

cpp
if (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=假):

aba && 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,表达式的值是 5C++ 中 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 的区别(又是一对读程序高频考点)
  • 读程序写输出中的"循环追踪表"画法

循环是编程题分值的真正主力,下一章见!🎯


百炼成钢,融会贯通