C++启蒙课程:第5章  循环和关系表达式

我们将为程序安装“自动化引擎”和“逻辑传感器”,让程序学会重复和判断!

🏭

机器人工厂:for循环

学习使用“任务计时器”`for`来执行精确次数的重复任务。

💃

不同舞步:while/do while

掌握“忠诚守卫”`while`和“先斩后奏”`do while`的区别。

🧱

立体魔方:嵌套循环

学习如何用循环“套”循环,来处理表格和二维数组。

课时一:机器人工厂的自动化:for循环

(覆盖知识点 5.1.1 - 5.1.13)

5.1.1 “任务计时器” for

`for` 循环有三部分:初始化 (只做1次)、测试 (每轮前检查)、更新 (每轮后执行)。

// 1. 初始化: int i = 0 // 2. 测试: i < 3 // 3. 更新: i++ for (int i = 0; i < 3; i++) { cout << "i is " << i << endl; }

5.1.2 关系超级英雄

关系运算符 (`<`, `==`, `!=`...) 是循环的“守卫”。它们比较值并返回 `true` (放行) 或 `false` (停止)。

int i = 5; bool result = (i < 10); // result is true string word = "hello"; bool check = (word == "done"); // check is false

5.1.13 红色警告:= vs ==

陷阱! 绝对不能用 `=` (赋值) 代替 `==` (比较)。`=` 会修改变量并返回 `true`,导致无限循环!

int x = 5;
int x = 5; // 错误!这是赋值,不是比较 // 它会把 10 赋给 x,并且 if(10) 永远为 true if (x = 10) { // ... DANGER! }

课时二:时间魔法师:递增/递减与复合语句

(覆盖知识点 5.1.5 - 5.1.11)

5.1.5 前缀(++x) vs 后缀(x++)

前缀 `++x`: 先修改,后使用。
后缀 `x++`: 先使用 (原值),后修改。

x = 5
y = ?
int x = 5; // 后缀: y 得到原值 5, x 变为 6 int y = x++; int a = 5; // 前缀: a 变为 6, z 得到新值 6 int z = ++a;

5.1.11 逗号运算符 (,)

逗号运算符 (,) 允许你在 `for` 循环的“初始化”和“更新”部分执行多个操作。

// 使用逗号在初始化和更新中处理两个变量 for (int i=0, j=4; i < j; i++, j--) { cout << "i=" << i << ", j=" << j << endl; }

5.1.10 “语句包裹” {}

循环体默认只能是一条语句。花括号 { } 像一个“包裹”,把多条语句组合成一条“复合语句”。

for (int i = 0; i < 2; i++) { // <-- 包裹开始 cout << "Round " << i << endl; cout << "Hello!" << endl; } // <-- 包裹结束

5.1.6 副作用与顺序点

副作用是修改变量的值 (如 `x++`)。顺序点 (如分号 ;) 确保所有副作用在下一步前完成。

陷阱: 永远不要在一条语句中对同一个变量多次使用副作用,这会导致“不确定的行为”。
// 副作用 (x被修改) x++; // 顺序点 (分号) // 危险!结果不确定! y = x * x++; // 安全 y = x * x; x++;

课时三:不同节奏的舞步:while与do while

(覆盖知识点 5.2 - 5.4)

5.2 “忠诚的守卫” while

`while` 是**入口条件**循环。守卫在放行(执行循环体)*之前*,必须先检查条件。

Key = 0
GATE
int key = 3; // 1. 测试: key > 0 (true) // 2. 执行: ... // 3. 测试: key > 0 (true) ... while (key > 0) { cout << "Key is " << key << endl; key--; }

5.3 “先斩后奏” do while

`do while` 是**出口条件**循环。它先执行一次循环体,*然后*才检查条件。至少执行一次。

Key = 0
GATE
int key = 0; do { // 1. 执行: (即使 key 是 0) cout << "Key is " << key << endl; key--; } while (key > 0); // 2. 测试: -1 > 0 (false) // 循环只执行了一次

5.1.14 字符串比较

C-风格字符串(char[]) 必须用 strcmp()。现代 string 类可以直接用 ==

char s1[] = "Hi";
char s2[] = "Hi";
#include // For strcmp #include // C-风格: 比较地址 (false) char s1[] = "Hi"; char s2[] = "Hi"; // if (s1 == s2) ... // 错误! // C-风格: 比较内容 (true) if (strcmp(s1, s2) == 0) ... // string 类: 直接比较内容 (true) string str1 = "Hi"; if (str1 == "Hi") ...

5.4 “懒人循环” (C++11)

基于范围的 `for` 循环会自动遍历数组或容器中的每一个元素,无需手动管理下标 `i`。

int scores[] = {10, 20, 30};
int scores[] = {10, 20, 30}; // C++11 风格 // x 会依次变为 10, 20, 30 for (int x : scores) { cout << x << endl; }

课时四:循环中的交互与高级应用

(覆盖知识点 5.5 - 5.6)

5.5 "挑食" vs "不挑食"

`cin >> ch` 是“挑食机器人”,它**跳过**空格和换行。`cin.get()` 是“不挑食机器人”,它**读取**所有字符。

输入流:
A B
char ch; // 挑食: 跳过 ' ', '↵' // 读取到 A, B while (cin >> ch) { ... } // 不挑食: 读取 A, ' ', B, '↵' while (cin.get(ch)) { ... }

5.6 立体魔方 (嵌套循环)

嵌套循环是一个循环“套”着另一个循环。外层循环控制“行”,内层循环控制“列”。

// 外层循环 (行) for (int i = 1; i <= 4; i++) { // 内层循环 (列) for (int j = 0; j < i; j++) { cout << "*"; } cout << endl; }

编程实践与作业 (5.10)

是时候检验你作为“自动化引擎”工程师的实力了!

练习 1:反向打印单词 (课时一)

任务:

编写一个程序,要求用户输入一个单词,然后使用 `for` 循环和下标,以相反的顺序打印该单词。

点击查看参考答案
#include <iostream> #include <string> using namespace std; int main() { string word; cout << "请输入一个单词: "; cin >> word; int length = word.length(); cout << "反向打印结果: "; // 5.1.4/5.1.2 循环从后向前访问 for (int i = length - 1; i >= 0; i--) { cout << word[i]; } cout << endl; return 0; }
练习 2:逗号运算符反转 (5.10 练习 3)

任务:

编写一个程序,使用 `for` 循环和**逗号运算符**,将用户输入的字符串内容(一个单词)原地反转并打印。

点击查看参考答案
#include <iostream> #include <string> using namespace std; int main() { string word; cout << "请输入一个单词: "; cin >> word; // 5.1.11 使用逗号运算符 for (int j = 0, i = word.length() - 1; j < i; j++, i--) { // 5.1.10 复合语句 char temp = word[j]; word[j] = word[i]; word[i] = temp; } cout << "反转后的单词是: " << word << endl; return 0; }
练习 3:循环直到 "done" (5.10 练习 9)

任务:

编写一个程序,使用 string 对象,要求用户输入单词直到输入“done”为止。计算用户输入了多少个单词(不包括“done”)。

点击查看参考答案
#include <iostream> #include <string> using namespace std; int main() { string word; int count = 0; cout << "请输入单词(输入 'done' 结束):" << endl; // 5.2/5.1.15 使用 while 循环 while (cin >> word && word != "done") { count++; } cout << "您总共输入了 " << count << " 个单词。" << endl; return 0; }
练习 4:句点与星号 (5.10 练习 10)

任务:

编写一个使用嵌套循环的程序,要求用户输入一个值 N,然后显示 N 行,每行的总字符数都等于 N,星号前用句点填充。

(例如 N=3):
..*
.**
***

点击查看参考答案
#include <iostream> using namespace std; int main() { int rows; cout << "请输入要显示的行数 N: "; cin >> rows; // 5.6 嵌套循环 // 外层循环:控制行数 i for (int i = 1; i <= rows; i++) { // 内层循环 1: 打印句点 (N - i 个) for (int j = 0; j < rows - i; j++) { cout << "."; } // 内层循环 2: 打印星号 (i 个) for (int k = 0; k < i; k++) { cout << "*"; } cout << endl; // 每行结束换行 } return 0; }

本章知识点总结与复习

核心概念 解释/功能 关键用法/运算符
`for`循环计数循环,入口条件循环。for (init; test; update)
`while`循环入口条件循环,用于次数不确定的循环。while (test)
`do while`循环出口条件循环,保证至少执行一次。do { ... } while (test);
关系表达式比较两个值,结果为 `bool` (`true`/`false`)。<, ==, !=, >=
递增/递减`++x` (先改后用) vs. `x++` (先用后改)。++x, x++
复合语句使用 `{}` 将多条语句组合成一条语句块。{ ... }
逗号运算符连接多个表达式,是顺序点。exp1, exp2
文本输入`cin >> ch` (跳过空白);`cin.get()` (读取所有)。while (cin.get(ch))
嵌套循环循环中的循环,用于处理二维数据。for(...) { for(...) }