else if 把判断从两条路扩展到多条路,理解它“一旦命中就跳过其余”的执行规则;
再用 &&、||、! 把多个条件组合成一个,
写出“区间判断”这类更复杂的逻辑。
else if 把判断从两条路扩展到多条路,理解它“一旦命中就跳过其余”的执行规则;
再用 &&、||、! 把多个条件组合成一个,
写出“区间判断”这类更复杂的逻辑。
上节课的 if / else 只能选两条路。但现实里常有三条、四条甚至更多:
成绩分 A / B / C / D / E 五档,年龄分婴儿 / 儿童 / 少年 / 成年 / 老年。
上节课练习里“两个数相等”的第三种情况,本质也是同样的问题——
if / else 给不出第三条路。今天就来解决它。
在 if 和 else 之间插入 else if (条件),
就能多出一条路。可以连续写很多个 else if。
Python:elif 是一个独立关键字
if age < 1:
elif age < 12:
else:
C++:else 和 if 是两个词
if (age < 1) {
} else if (age < 12) {
} else {
#include <iostream>
int main() {
int age;
std::cout << "请输入年龄:";
std::cin >> age;
if (age < 1) {
std::cout << "婴儿" << std::endl;
} else if (age < 12) {
std::cout << "儿童" << std::endl;
} else if (age < 18) {
std::cout << "少年" << std::endl;
} else if (age < 60) {
std::cout << "成年" << std::endl;
} else {
std::cout << "老年" << std::endl;
}
return 0;
}
下面两段代码都是上面年龄分类器的“变体”。分别代入 age = 5、
12、70,猜一猜各自会输出什么:
if (age < 60) {
std::cout << "成年" << std::endl;
} else if (age < 18) {
std::cout << "少年" << std::endl;
} else if (age < 12) {
std::cout << "儿童" << std::endl;
} else if (age < 1) {
std::cout << "婴儿" << std::endl;
} else {
std::cout << "老年" << std::endl;
} if (age < 1) {
std::cout << "婴儿" << std::endl;
}
if (age < 12) {
std::cout << "儿童" << std::endl;
}
if (age < 18) {
std::cout << "少年" << std::endl;
}
if (age < 60) {
std::cout << "成年" << std::endl;
}
if (age >= 60) {
std::cout << "老年" << std::endl;
} wrong_order:顺序反了。age < 60 排在最前面,
5 岁、12 岁都满足这一条,于是统统被判成“成年”,更精确的分支再也没机会执行。
no_else:去掉了 else,每个 if 各自独立判断。
而这些条件本来就不互斥——5 岁同时满足 <12、<18、<60,
于是连续输出三行。
else if 链真正的意义:条件要按从特殊到一般排列,而且“命中就跳过其余”这条规则, 正是让分支彼此互斥的关键。
else if 链其实是嵌套 if 的简写——每个 else
后面紧跟一个 if,只是被代码格式“拉平”了,本质没变:
// 写法一:else if 链
if (score >= 90) {
std::cout << "优秀" << std::endl;
} else if (score >= 60) {
std::cout << "及格" << std::endl;
} else {
std::cout << "不及格" << std::endl;
}
// 写法二:嵌套 if,和写法一完全等价
if (score >= 90) {
std::cout << "优秀" << std::endl;
} else {
if (score >= 60) {
std::cout << "及格" << std::endl;
} else {
std::cout << "不及格" << std::endl;
}
}
既然 else if 本质是嵌套,那嵌套的 if 如果省略大括号,
else 会配对给离它最近、还没被配对的 if——
不一定是程序员以为的那个:
int score = 75; // 75 分,本该是“及格”
// 写法一:省略大括号——else 配对到最近的 if (score >= 90)
if (score >= 60)
if (score >= 90)
std::cout << "优秀" << std::endl;
else
std::cout << "不及格" << std::endl;
// 输出:不及格 —— 75 分被判成了不及格!
// 写法二:补上大括号——else 才配对到外层 if (score >= 60)
if (score >= 60) {
if (score >= 90) {
std::cout << "优秀" << std::endl;
}
} else {
std::cout << "不及格" << std::endl;
}
// 75 >= 60,进入大括号;90 不满足,什么都不输出——这才对 这也是为什么上节课建议大括号总是写上——嵌套层数一多,悬挂 else 很难一眼看出。
“成绩在 60 到 80 之间”——单靠一个比较运算符做不到,需要把两个条件合起来判断。
&&(与)要求两边都成立,||(或)只要一边成立:
| a | b | a && b | a || b |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 |
| 0 | 0 | 0 | 0 |
int score = 75;
if (score >= 60 && score < 80) {
std::cout << "中等" << std::endl; // 75 满足:>= 60 且 < 80
} int day = 6;
if (day == 6 || day == 7) {
std::cout << "周末" << std::endl; // 6 满足第一个条件,整体就是 true
} >= 等)的优先级高于 &&,
&& 又高于 ||。表达式复杂时不必死记,直接加括号最稳妥。
这行代码能编译通过,但意义完全不对:
int score = 95;
std::cout << (60 <= score <= 80) << std::endl;
// 计算顺序:先算 60 <= score,结果是 true(即 1)
// 再算 1 <= 80,结果还是 true
// 所以不管 score 是多少,几乎都输出 1!
std::cout << (score >= 60 && score <= 80) << std::endl;
// 这才是真正的“60 到 80 之间”,正确写法
根源还是上节课讲的条件本身是一个值——60 <= score 算出的
true/false(即 1/0)又被拿去跟
80 比较,跟“区间”毫无关系。
&& 和 || 会“算到能确定结果就停”:左边已经决定了整体结果,
右边就不会再算。这能避免一些错误:
int a = 10, b = 0;
if (b != 0 && a / b > 2) {
std::cout << "比较结果" << std::endl;
}
// b != 0 已经是 false,&& 后面的 a / b 不会再被计算
// 否则 a / b 就是除以 0,程序会出错 ! 放在条件前面,把 true 变 false、
false 变 true。常用于“校验输入是否不合法”这类场景:
bool isAdult = (age >= 18);
std::cout << !isAdult << std::endl; // 取反:成年时输出 0,未成年时输出 1
if (!(score >= 0 && score <= 100)) {
std::cout << "分数输入错误" << std::endl;
}
了解即可:!(a && b) 和 !a || !b 是等价的(德摩根定律),
不要求记忆,遇到时知道怎么回事就好。
读入一个整数温度,按下表分五档输出:
要求:用 else if 链实现,不要用独立的 if。
< 写,也可以从“高到低”用 >= 写——
两种顺序都行,但顺序和比较方向必须搭配一致,否则就会遇到本节课开头的“顺序陷阱”。
读入一个年份,判断它是否为闰年。
闰年规则:能被 4 整除且不能被 100 整除,或者能被 400 整除。
要求:用一个 if 条件,把 && 和 || 组合起来表达这条规则(回忆第 2 讲的 % 取余)。
|| 连接。要不要给 && 部分加括号?试着去掉括号看看结果是否变化。
| 能力 | 用到的工具 |
|---|---|
| 三条以上路径选一条 | if / else if / else |
| 判断顺序与互斥性 | 从特殊到一般排列,命中即跳过其余 |
| 组合多个条件 | &&、|| |
| 反转条件 | ! |
最该记住的一句话:else if 链一旦命中就跳过其余,所以条件的顺序和互斥性都很重要;
最该警惕的一个坑:60 <= score <= 80 在 C++ 里能编译,但意义不对。
else if 和 &&,下节课会在一个完整项目里综合起来——
写一个成绩等级判断器,把分数分成 A / B / C / D / E 五档。