CC++ & Algorithm

C++分支语句嵌套

困难21
语言版本:C++Python
概述:学习将if、if-else或switch语句嵌套在另一个分支内部,实现更复杂的条件判断,就像连环套的迷宫一样。

分支嵌套:让程序学会“连环判断”

今天我们要学习一个非常有用的技能——分支语句的嵌套。简单来说,就是在一条 ifif-elseswitch 语句的“身体”里面,再放一条新的分支语句。这就好比你在做决定的时候,先考虑一个条件,满足了还要考虑更细的条件。比如:

  • “如果今天下雨,我就不去公园。但如果雨不大,我还可以打伞去。”
  • “如果考试及格了,再看分数:如果超过90分,奖励一个游戏机;如果在80~89分,奖励一本漫画书;否则只奖励一根冰棍。”

这些“判断里面还有判断”的情况,用分支嵌套就可以轻松搞定。

什么是分支嵌套?

分支嵌套就像一个俄罗斯套娃——大娃娃里面装着小娃娃,小娃娃里面还装着更小的娃娃。在C++里,我们可以在 if 的语句块里再写一个 if-else,也可以在 switch 里面放 if,都是允许的。但是要注意:每一层都要正确使用花括号 {},并且缩进对齐,否则代码会像一团乱麻,谁也看不懂。

生活中的例子:判断能不能去踢球

想象一下:小明想周末去踢足球,但他必须满足两个条件:第一,周末不能下雨;第二,如果不下雨,他还要看自己是否写完作业。如果作业写完了,才能去踢球;如果作业没写完,就只能在家写作业。

用嵌套的 if 可以这样写:

#include <iostream>
using namespace std;

int main() {
    bool is_rainy = false;   // 是否下雨,false表示不下雨
    bool homework_done = true; // 作业是否完成,true表示完成

    if (is_rainy == false) {  // 外层判断:不下雨
        // 不下雨,再检查作业
        if (homework_done == true) {
            cout << "可以去踢球啦!" << endl;
        } else {
            cout << "先写完作业才能去踢球。" << endl;
        }
    } else {
        cout << "下雨了,不能去踢球。" << endl;
    }
    return 0;
}

注意: 外层的 if 里面,我们放了一个完整的 if-else 结构。这就是嵌套。

嵌套的常见形式

1. if 里面嵌套 if-else(就像上面的例子)

适合“先满足一个大条件,再根据小条件做不同选择”的场景。

2. if-else 里面嵌套 if

比如判断一个数字是正数还是负数,如果是正数,再判断它是不是偶数:

int num;
cin >> num;
if (num > 0) {
    // 正数
    if (num % 2 == 0) {
        cout << "正偶数" << endl;
    } else {
        cout << "正奇数" << endl;
    }
} else if (num < 0) {
    cout << "负数" << endl;
} else {
    cout << "零" << endl;
}

3. switch 里面嵌套 if

虽然 switch 本身用来处理多个固定值,但有时在某个 case 里还需要做额外判断,就可以用 if。例如学校根据班级编号和座位号发礼物:

int class_id, seat;
cin >> class_id >> seat;
switch (class_id) {
    case 1:
        if (seat <= 20) {
            cout << "一班前20排的同学获得铅笔" << endl;
        } else {
            cout << "一班其余同学获得橡皮" << endl;
        }
        break;
    case 2:
        cout << "二班全体获得尺子" << endl;
        break;
    default:
        cout << "其他班级没有礼物" << endl;
}

4. 更深的嵌套:三层以上(慎用)

理论上可以无限嵌套,但一般不超过3层,否则代码会变得非常难看懂,而且容易出错。比如下面这个“判断闰年”的例子(就是原文的例子),就用了两层嵌套(实际上三层,因为最内层还有一个 if-else):

#include <iostream>
using namespace std;

int main() {
    int year;          // 年份
    cout << "请输入一个年份:";
    cin >> year;

    if (year % 4 == 0) {               // 能被4整除
        if (year % 100 != 0) {         // 且不能被100整除
            cout << year << " 是闰年" << endl;
        } else {                        // 能被100整除
            if (year % 400 == 0) {      // 且能被400整除
                cout << year << " 是闰年" << endl;
            } else {
                cout << year << " 不是闰年" << endl;
            }
        }
    } else {
        cout << year << " 不是闰年" << endl;
    }
    return 0;
}

这个程序从最外层 (year%4==0) 开始,如果满足,就进入内层判断 (year%100==0 或 !=0),内层中又嵌套了最里层的 (year%400==0)。每一层都有清晰的花括号和缩进,所以看起来还是能看懂。但如果你嵌套到5层、6层,别人读你的代码就会像走迷宫一样晕。

新手最容易犯的3个错误

错误一:忘记写花括号,导致 else 配对错误

C++ 里 else 总是和它上面最近的 if 配对(如果没有花括号)。看这个例子:

if (score >= 60)
    if (score >= 90)
        cout << "优秀" << endl;
else
    cout << "不及格" << endl;

你可能会想:else 是跟着第一个 if 的(如果不及格就输出)。但实际上,编译器会把 else 跟第二个 if 配对,变成“如果分数≥60且≥90就优秀,否则(分数≥60且<90)什么也不输出?不对,这里的 else 实际是跟第二个 if,所以如果分数<60,两个 if 都不满足,else 当然不执行。结果:分数59分时,不会输出“不及格”,什么都不会输出。这和我们想的完全不一样!

正确写法:给内层的 if 加上花括号,或者把 else 放在正确的位置:

if (score >= 60) {
    if (score >= 90)
        cout << "优秀" << endl;
    // 这里不能再加else,否则会配错
} else {
    cout << "不及格" << endl;
}

规则: 只要 ifelse 后面跟了多条语句,或者内部要嵌套另一个分支,一定要加 {} 明确范围。哪怕只有一条语句,加上花括号也能避免错误。

错误二:缩进混乱,导致误解

缩进不整齐虽然不会影响程序运行结果,但会让代码难以阅读。比如:

if (a > 0)
    if (b > 0)
        cout << "a和b都为正" << endl;
    else
        cout << "a为正,b为负或零" << endl;

上面代码缩进显示 else 和第二个 if 对齐,但实际上 else 确实和第二个 if 配对(因为没花括号)。如果想让 else 和第一个 if 配对,必须用花括号把内层 if 包起来。所以缩进不能代替花括号,但好的缩进能帮助你发现逻辑问题。

错误三:嵌套太深,把程序写成了“意大利面条”

嵌套超过3层,代码就会变得非常难维护。比如你要判断一个学生能不能加入游戏俱乐部:

  • 年龄大于12岁
  • 如果是男生,再检查有没有家长同意
  • 如果是女生,再检查有没有女生陪同
  • 如果年龄小于12岁,再检查是不是周末

这种多层嵌套很容易写错括号或漏掉条件。建议:如果嵌套层数太多,可以考虑用 &&|| 等逻辑运算符合并条件,或者把内层判断提取成单独的函数(以后会学到)。

一个完整的嵌套示例:计算打折后的价格

小明去文具店买文具,店里有优惠活动:

  • 如果购买金额超过100元,可以享受8折,但必须同时持有会员卡才能再享受9折(双重优惠)。
  • 如果购买金额在50~100元之间,只有持有会员卡才能打9折。
  • 如果低于50元,没有优惠。

请根据输入的总金额 money 和是否有会员卡 has_card(用1表示有,0表示没有),输出最终需要付的钱。

#include <iostream>
using namespace std;

int main() {
    double money;           // 购买金额
    int has_card;           // 是否有会员卡,1有,0没有
    cout << "请输入购买金额:";
    cin >> money;
    cout << "是否有会员卡?(1有,0没有):";
    cin >> has_card;

    if (money > 100) {                          // 外层:金额>100
        // 打8折
        money = money * 0.8;
        // 内层:如果有会员卡,再打9折(即再乘以0.9)
        if (has_card == 1) {
            money = money * 0.9;
        }
    } else if (money >= 50) {                   // 外层:50~100之间
        // 只有有会员卡才打9折,否则原价
        if (has_card == 1) {
            money = money * 0.9;
        }
        // 如果没有卡,money不变(原价)
    } else {                                    // 金额<50
        // 无优惠,原价
    }

    cout << "最终需要支付:" << money << "元" << endl;
    return 0;
}

运行一下:

请输入购买金额:200
是否有会员卡?(1有,0没有):1
最终需要支付:144元

解释:200元超过100,先打8折变成160元,再打9折变成144元。

总结

分支嵌套就像连环套,让程序能处理“条件中的条件”。记住三个要点:

  1. 花括号一定要加,尤其是嵌套时,花括号能清楚划分每个分支的范围,避免 else 配错。
  2. 缩进对齐,让每层嵌套一目了然,自己以后看或别人看都舒服。
  3. 不要嵌套太深,超过3层就要想办法简化,比如用逻辑运算符合并条件,或者后面学到的函数。

如果你对分支语句的基础还不熟,可以先复习 [C++ if-else 语句] 和 [C++ switch 语句]。掌握了嵌套,你就能写出像游戏里的复杂规则一样有趣的程序啦!

例题精讲

1单选题

以下关于C++中if语句嵌套的说法,正确的是?

A内层if语句可以独立于外层if的条件执行
B内层if语句必须包含else分支
C内层if语句的条件判断依赖于外层if的条件成立时才执行
D嵌套层数不能超过3层
2单选题

下列代码输出结果是什么? int x = 10; if (x > 5) { if (x < 15) { cout << "A"; } else { cout << "B"; } } else { cout << "C"; }

AA
BB
CC
D无输出
3判断题

C++中,如果外层if条件为假,内层if条件无论真假都会被执行。

4填空题
以下程序判断三个整数a、b、c能否构成三角形,请填空:
if (a + b > c && a + c > b && b + c > a) {
    if (a == b && b == c) {
        cout << "等边三角形";
    } else ___ {
        cout << "等腰三角形";
    } else {
        cout << "普通三角形";
    }
} else {
    cout << "不能构成三角形";
}
5填空题
下面代码根据分数输出等级(90以上优秀,80-89良好,70-79中等,60-69及格,其余不及格)。但存在错误,请填空修正:
if (score >= 90) {
    cout << "优秀";
} else if (score >= 80) {
    cout << "良好";
} else if (score >= 70) {
    cout << "中等";
} else if (score >= 60) {
    cout << "及格";
} ___ {
    cout << "不及格";
}