第 9 章 岔路口——if-else 分支
🏗️ 前情回顾:上章你造好了程序的计算能力——加减乘除、取余、自增自减。但程序还是一条路走到黑。你想让程序「看情况做决定」?这章就是答案。
🎯 本章目标
学完这一章,你能:
- 理解什么是"程序的分支",为什么程序需要做判断
- 用
if、if-else、else if写出各种分支逻辑 - 熟练使用 6 种关系运算符(
==!=<><=>=) - 用
&&||!组合多个条件,并理解它们"见好就收"的秘密 - 画出简单的流程图,用图形描述程序的判断过程
📖 故事引入
每天放学回家的路上,你都会经过一个红绿灯。
"绿灯亮了,我就走;红灯亮了,我就停。"这个规则你已经烂熟于心——你的大脑在自动执行一个"判断 → 行动"的过程。
现在想象你是一个交通信号灯的程序员。你要写的程序大概是这样:
如果 现在是绿灯:
显示"可以通行"
否则:
显示"请等待"再看另一个场景——你登录游戏时需要输入密码:
如果 密码正确:
进入游戏
否则:
显示"密码错误,请重试"你看,从红绿灯到游戏登录,从自动门到成绩评级——生活中到处都是"如果……就……否则……"。这章要学的 if-else,就是把这些"如果"翻译成 C++。
🧱 知识讲解
9.1 最简单的判断:if 语句
if 是 C++ 里最基础的"岔路口"。它的格式长这样:
if (条件) {
条件成立时执行的代码
}翻译成人话:"如果条件成立,就做花括号里的事;否则跳过。"
来看一个最简单的例子——判断一个数是不是正数:
int n;
cin >> n;
if (n > 0) {
cout << "这是一个正数" << endl;
}
cout << "判断结束" << endl;运行效果:
- 输入
5:输出 "这是一个正数" + "判断结束" - 输入
-3:只输出 "判断结束"(n > 0不成立,if 里的代码被跳过)
💡 花括号
{ }包住的是"条件成立时要执行的一堆语句"。如果只有一条语句,花括号可以省略。但强烈建议初学者永远加花括号——少 bug、好阅读。
9.2 二选一:if-else
很多时候你不仅要"条件成立时做什么",还要"条件不成立时做什么"。这时用 if-else:
if (条件) {
// 条件成立 → 走这条路
} else {
// 条件不成立 → 走那条路
}两条路必走一条,且只走一条——就像岔路口,选了左边就不能走右边。
int score;
cin >> score;
if (score >= 60) {
cout << "及格!" << endl;
} else {
cout << "不及格,继续努力!" << endl;
}9.3 关系运算符:六个"法官"
if 后面括号里的"条件"到底怎么写?用关系运算符。它们专门判断两个东西之间的大小关系:
| 运算符 | 含义 | 例子 | 结果 |
|---|---|---|---|
== | 等于 | 5 == 5 | true(真) |
!= | 不等于 | 5 != 3 | true |
< | 小于 | 3 < 5 | true |
> | 大于 | 7 > 2 | true |
<= | 小于等于 | 5 <= 5 | true |
>= | 大于等于 | 5 >= 3 | true |
⚠️ 死记硬背:判断相等用
==(两个等号),不是=!=是赋值,==是比较。这个错误能坑你一整年。
❌ 先看看这段代码——有什么问题?
int x;
cin >> x;
if (x = 5) { // 🤔 这里对吗?
cout << "x 等于 5!" << endl;
}如果你输入 3,程序竟然也输出 "x 等于 5!"。为什么?因为 x = 5 是赋值,不是比较!C++ 里赋值完后,= 表达式本身的值就是 5(非零即真),所以条件永远成立。正确写法:
if (x == 5) { // ✅ 两个等号才是比较!
cout << "x 等于 5!" << endl;
}9.4 多岔路口:else if
生活不只是二选一。给考试成绩评级:
| 分数 | 等级 |
|---|---|
| ≥ 90 | A |
| ≥ 80 | B |
| ≥ 70 | C |
| ≥ 60 | D |
| < 60 | E |
这需要多个分支,用 else if:
int score;
cin >> score;
if (score >= 90) {
cout << "A" << endl;
} else if (score >= 80) {
cout << "B" << endl;
} else if (score >= 70) {
cout << "C" << endl;
} else if (score >= 60) {
cout << "D" << endl;
} else {
cout << "E" << endl;
}重要理解:else if 是"多选一"的结构。程序从上往下检查条件,第一个成立的就执行,后面的全部跳过。所以顺序很重要!如果你把 score >= 60 写在最前面,那任何 ≥60 的分数都会输出 D——后面的 score >= 90 永远不会被执行到。
写 else if 链条的铁律:要么从大到小,要么从小到大,不要把宽松条件放前面。
9.5 嵌套 if:判断里面还有判断
有时候一个条件还不能做决定,需要再问第二个问题。
比如:判断一个年份是不是闰年。规则是:
- 能被 400 整除 → 闰年
- 能被 4 整除但不能被 100 整除 → 闰年
- 其他 → 平年
第一版:老老实实用嵌套 if
int year;
cin >> year;
if (year % 400 == 0) {
cout << "闰年" << endl;
} else if (year % 4 == 0) {
if (year % 100 != 0) { // 嵌套的 if
cout << "闰年" << endl;
} else {
cout << "平年" << endl;
}
} else {
cout << "平年" << endl;
}😩 这段代码嵌套了 4 层(if → else if → if → else),读起来好累!像套娃一样一层套一层。
第二版:用逻辑运算符,一行搞定!
int year;
cin >> year;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
cout << "闰年" << endl;
} else {
cout << "平年" << endl;
}天壤之别!逻辑运算符把"能被 4 整除且不能被 100 整除,或者能被 400 整除"浓缩成一行——清晰又强大。下面就来学这三个"条件组合器"。
9.6 逻辑运算符:把条件组合起来
有时候条件不是单个的——"分数 ≥ 90 且 体育也 ≥ 90,才给全额奖学金"。多个条件需要"且/或/非"来组合。
C++ 的三个逻辑运算符:
| 运算符 | 含义 | 例子 | 结果为 true 的条件 |
|---|---|---|---|
&& | 与(且) | a > 5 && b < 10 | 两边都成立 |
|| | 或 | a > 5 || b < 10 | 至少一边成立 |
! | 非(取反) | !(a > 5) | 条件本身不成立 |
实例:
// 判断一个年份是不是闰年(用逻辑运算符,一行搞定)
int year;
cin >> year;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
cout << "闰年" << endl;
} else {
cout << "平年" << endl;
}对比嵌套版,逻辑运算符让复杂的条件浓缩成一行。
9.7 && 和 || 的秘密:见好就收
C++ 在计算 && 和 || 时,有个聪明的优化——见好就收:
A && B:如果 A 已经是 false,B 根本不会被计算——反正结果肯定是 false。&& 见 false 就跑,后面根本不看。A || B:如果 A 已经是 true,B 也不会被计算——反正结果肯定是 true。|| 见 true 就跑,后面根本不看。
int x = 0;
if (x != 0 && 10 / x > 5) { // x=0 时,x!=0 是 false
cout << "成立" << endl; // 10/x 不会被执行——避免了除零错误!
}这就是"见好就收"的好处——它能在无意中保护你的程序不出错。但要小心别滥用——如果 B 里有重要的副作用(比如 ++、函数调用),B 可能不被执行。
9.8 流程图:用图形说话
当逻辑变复杂时,画图比写字清楚得多。流程图用几个简单的图形就能描述程序的判断过程:
椭圆形:开始/结束
长方形:做一件事(执行语句)
菱形:判断(问一个问题,两个出口)
箭头:执行方向成绩评级的流程图:
┌──────┐
│ 开始 │
└──┬───┘
▼
┌─────────┐
│ 输入分数 │
└────┬────┘
▼
╔═══════╗
┌──→║≥90? ║──是──→ 输出"A"
│ ╚═══════╝
│ │ 否
│ ▼
│ ╔═══════╗
│ ║≥80? ║──是──→ 输出"B"
│ ╚═══════╝
│ │ 否
│ ▼
│ ...(以此类推)
│
└────────────→ ┌──────┐
│ 结束 │
└──────┘流程图是程序员的"草图"。以后遇到复杂逻辑,先画流程图再写代码,思路会清晰得多。
✋ 动手试试
试试 1:写一个程序,输入一个整数,判断它是正数、负数还是零。用 if-else if-else 结构。
试试 2:写一个"简易登录"程序。预设密码为 "cpp123"(string 类型)。用户输入密码,正确显示"登录成功",错误显示"密码错误"。(提示:string 类型可以用 == 直接比较。)
试试 3:输入三个整数,找出最大的那个并输出。(提示:用嵌套 if——先比前两个,再和第三个比。)
试试 4:验证"见好就收"。运行下面的代码,看看输入 0 时会不会报错:
int x;
cin >> x;
if (x != 0 && 100 / x > 10) {
cout << "商大于10" << endl;
} else {
cout << "条件不成立(x可能是0,但没报错吧?)" << endl;
}⚠️ 你踩过这些坑吗
下面的每个坑都是前人踩烂的——看看你能跳过几个。
- [ ] 坑 1:
=当==用——if (x = 5)是赋值不是比较。除非你刻意要用赋值的副作用,否则if里永远用==。 - [ ] 坑 2:else if 顺序写反——先判
score >= 60后判score >= 90,95 分只会得 D。从大到小或从小到大排好,最严的条件放最前。 - [ ] 坑 3:花括号缩进骗了你——
if后面没花括号时,只有紧接着的一行属于if。缩进是给人看的,编译器不看缩进。永远加花括号。 - [ ] 坑 4:
&&和||搞混——"年龄在 13 到 19 之间"应该是age >= 13 && age <= 19,不是||。
📝 练习
基础题
1. 选择题
(1)判断 a 和 b 是否相等,应使用:
A. a = b B. a == b C. a != b D. a >= b
(2)!(5 > 3) 的值是:
A. true B. false C. 5 D. 3
(3)以下代码输出什么?
int x = 85;
if (x >= 90) cout << "A";
else if (x >= 80) cout << "B";
else if (x >= 70) cout << "C";
else cout << "D";A. A B. B C. C D. D
2. 填空题
(1)判断 x 在 1 到 100 之间(含两端):if (x ___ 1 ___ x ___ 100)
(2)判断 x 是偶数:if (x ___ 2 ___ 0)
(3)(3 > 5) ___ (2 < 4) 用 || 连接,结果是 _____。
3. 代码找错
以下代码有什么问题?修改成正确的版本:
int age;
cin >> age;
if (age = 18) {
cout << "你刚好成年!" << endl;
}4. 判断题
判断以下说法是否正确:
- ( )
if (x = 5)表示"如果 x 等于 5" - ( )
else if可以有任意多个 - ( )
else后面可以加条件
提高题
5. 编程题 — 绝对值
输入一个整数,输出它的绝对值。(提示:负数取反就是绝对值,如 -5 的绝对值是 5。)
6. 编程题 — 三角形判断
输入三条边 a、b、c,判断它们能否构成三角形。能构成三角形的条件是:任意两边之和大于第三边。
示例运行:
请输入三条边:3 4 5
能构成三角形7. 编程题 — 大小写转换
输入一个字符,如果是小写字母,转换成大写字母输出;如果是大写字母,转换成小写字母输出;如果不是字母,输出"不是字母"。(提示:char 类型可以用关系运算符比较,小写字母 'a'~'z',大写字母 'A'~'Z',二者相差 32。)
挑战题
8. 编程题 — 简单计算器
输入两个整数和一个运算符(+、-、*、/),输出计算结果。如果是除法且除数为 0,输出"除数不能为0"。
示例运行:
请输入算式(如 12 + 5):12 / 0
除数不能为09. 编程题 — 判断闰年(一行版)
只用 if-else 加逻辑运算符(不要嵌套),判断输入年份是不是闰年。尽量让条件写在一行里。
🧠 本章小结
┌─────────────────────────────────────────────────────────┐
│ │
│ if (条件) { ... } 单分支:成立才执行 │
│ if-else { ... } else { ... } 二选一 │
│ else if 多选一(顺序很重要!) │
│ │
│ 关系运算符:== != < > <= >= │
│ 逻辑运算符:&& (与) || (或) ! (非) │
│ │
│ && 见 false 就跑,|| 见 true 就跑——后面根本不看 │
│ │
│ 流程图:菱形 = 判断,箭头 = 走向 │
│ │
│ 铁律:if 里判断相等用 ==,不是 = │
│ │
└─────────────────────────────────────────────────────────┘📝 配套练习
共10题。if-else从二元→多元→嵌套→分段函数逐步推进。。★核心(课堂必做) ◆拓展(课后练习)
| 级别 | 题号 | 链接 | 覆盖知识点 |
|---|---|---|---|
| ★ 核心 | J0027 | https://hydro.ac/d/srqc/p/J0027 | if-else、关系运算符>、比较 |
| ◆ 拓展 | J0028 | https://hydro.ac/d/srqc/p/J0028 | if-else、逻辑&&、多条件组合 |
| ◆ 拓展 | J0029 | https://hydro.ac/d/srqc/p/J0029 | if-else嵌套、闰年四条件 |
| ◆ 拓展 | luogu-B2035 | https://hydro.ac/p/luogu-B2035 | 关系运算符、正负零三分支 |
| ◆ 拓展 | luogu-B2036 | https://hydro.ac/p/luogu-B2036 | 绝对值、if-else、三目?: |
| ◆ 拓展 | luogu-B2040 | https://hydro.ac/p/luogu-B2040 | 判断两位数、关系+逻辑&& |
| ◆ 拓展 | luogu-B2047 | https://hydro.ac/p/luogu-B2047 | 分段函数、else-if链、边界 |
| ◆ 拓展 | J0031 | https://hydro.ac/d/srqc/p/J0031 | if-else、多条件分类 |
| ◆ 拓展 | J0030 | https://hydro.ac/d/srqc/p/J0030 | if-else、字符串条件 |
| ◆ 拓展 | luogu-B2041 | https://hydro.ac/p/luogu-B2041 | 简单&&、两个bool条件 |
💡 练习建议:先完成 1 道★核心题,确保掌握本章基本方法;再完成 9 道◆拓展题,覆盖不同变式和细节。
配套练习
共10题。if-else从二元→多元→嵌套→分段函数逐步推进。★核心(课堂必做) · ◆拓展(课后练习)
| 级别 | 题号 | 链接 | 覆盖知识点 |
|---|---|---|---|
| ★ 核心 | J0027 | https://hydro.ac/d/srqc/p/J0027 | if-else、关系运算符>、比较 |
| ◆ 拓展 | J0028 | https://hydro.ac/d/srqc/p/J0028 | if-else、逻辑&&、多条件组合 |
| ◆ 拓展 | J0029 | https://hydro.ac/d/srqc/p/J0029 | if-else嵌套、闰年四条件 |
| ◆ 拓展 | luogu-B2035 | https://hydro.ac/p/luogu-B2035 | 关系运算符、正负零三分支 |
| ◆ 拓展 | luogu-B2036 | https://hydro.ac/p/luogu-B2036 | 绝对值、if-else、三目?: |
| ◆ 拓展 | luogu-B2040 | https://hydro.ac/p/luogu-B2040 | 判断两位数、关系+逻辑&& |
| ◆ 拓展 | luogu-B2047 | https://hydro.ac/p/luogu-B2047 | 分段函数、else-if链、边界 |
| ◆ 拓展 | J0031 | https://hydro.ac/d/srqc/p/J0031 | if-else、多条件分类 |
| ◆ 拓展 | J0030 | https://hydro.ac/d/srqc/p/J0030 | if-else、字符串条件 |
| ◆ 拓展 | luogu-B2041 | https://hydro.ac/p/luogu-B2041 | 简单&&、两个bool条件 |
练习建议:先在课堂完成 1 道★核心题,掌握本章基本方法;课后完成 9 道◆拓展题,覆盖不同变式和细节。
自查清单:
- [ ] 我能写出 if、if-else、else if 三种结构
- [ ] 我知道
==和=的区别,不会在 if 里写= - [ ] 我会用
&&||!组合条件 - [ ] 我理解 && 见 false 就跑、|| 见 true 就跑,知道它为什么安全
- [ ] 遇到复杂条件,我能先画流程图再写代码
🚀 下章预告:两个岔路口够用——但如果选项有七八个呢?比如自动售货机有 10 种饮料,用
else if得写一堵墙。下章学 switch-case,专门对付「多选一」的硬仗。