Files
project1/第03课-嵌套循环与图形打印/教案-教师版.md

311 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第5课嵌套循环与图形打印
## 教学目标
- 理解嵌套循环的执行流程(外层管行、内层管列)
- 能分析图形规律,写出对应的行列公式
- 掌握矩形、直角三角形、等腰三角形、菱形的打印方法
- 掌握多层循环以及分支与循环相互嵌套的二级必考写法
## 核心考点:嵌套循环中的行列关系
### 考什么
题目会给出矩形、三角形或菱形,要求分析每一行应输出多少空格和符号,再用嵌套循环打印。考试重点不是背某个图形,而是能从行号推导本行各部分的数量。
### 必须理解
外层循环每执行一次就完成一整行,因此负责行数;内层循环在当前行中重复输出,负责列数或某种字符数量。解决图形题应先列出“第 i 行有多少空格、多少星号”,再把数量写成关于 i 和总行数 n 的公式。例如等腰三角形第 i 行:前导空格 `n-i` 个,星号 `2*i-1` 个。每一类字符分别使用一个内层循环,行末统一换行。
### 核心写法
```cpp
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) cout << ' ';
for (int j = 1; j <= 2 * i - 1; j++) cout << '*';
cout << endl;
}
```
外层的 i 表示当前行,两个内层循环的上界由 i 决定,所以每行形状都会变化。
### 常见错误
- 把换行写进内层循环,导致每输出一个字符就换行。
- 内层循环上界始终写 n无法随行号改变图形。
- 行号从 0 开始,却直接套用从 1 开始推导的公式。
- 只凭眼睛试代码,不先写出行号与数量表。
### 判断是否掌握
面对新图形时,能先列前三行的空格数和符号数,推导出关于 i 的公式,再独立写出外层、内层和换行代码。
---
## 题目一:打印实心矩形
### 核心代码(一句话)
> 嵌套循环的核心:**外层循环管行数,内层循环管列数**,两层 `for` 一套就行。
### 自然语言思路
我们要打印一个 n 行 m 列的矩形,全是星号。
第一步确定要印几行n 行,所以外层循环从 1 到 n。
第二步每一行里面要印几个星号m 个,所以内层循环从 1 到 m。
第三步,每印完一行,记得换行 `cout << endl`
第四步,把上面三步写成代码 —— 外层 `for` 套一个内层 `for`,里面 `cout` 星号,外面 `cout` 换行。
> 想象你在一行一行地写字:外层决定写几行,内层决定每行写几个字。
### 伪代码
```
1. 输入 n, m
2. for i = 1 到 n // 外层:控制行
3. for j = 1 到 m // 内层:控制列
4. 输出 "* "
5. 输出换行
```
### 真实代码
```cpp
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) { // 外层循环n 行
for (int j = 1; j <= m; j++) { // 内层循环:每行 m 个
cout << "* ";
}
cout << endl; // 每行结束换行
}
return 0;
}
```
### 注意点
1. **内层循环变量名**:习惯用 `j`,因为 `i` 已经被外层用了。不要在外层和内层用同一个变量名。
2. **换行位置**`cout << endl` 放在外层循环里面、内层循环外面,每行结束只换一次。
3. **嵌套理解口诀**:外层每走一步,内层跑完全程。就像时钟——时针走一格,分针转一整圈。
---
## 题目二:直角三角形(左下 + 右下)
### 核心代码(一句话)
> 直角三角形的核心:**第 i 行打印 i 个星号**,内层循环的终止条件用 `j <= i`。
### 自然语言思路
**左下直角三角形**
第一步观察规律第1行1个星第2行2个星第3行3个星……第 i 行 i 个星。
第二步,每行的星号数量**等于行号**。
第三步,内层循环写成 `for (j = 1; j <= i; j++)`,就搞定了。
**右下直角三角形**
第一步先看空格第1行前面有 n-1 个空格第2行前面有 n-2 个空格……第 i 行前面有 n-i 个空格。
第二步,空格用**另一个内层循环**先打印:`for (j = 1; j <= n - i; j++)`
第三步,再打印星号,和第 i 行 i 个星一样。
第四步,每行顺序:先空格、后星号、再换行。
### 伪代码
**左下直角三角形**
```
1. 输入 n
2. for i = 1 到 n
3. for j = 1 到 i // 第 i 行 i 个星
4. 输出 "* "
5. 输出换行
```
**右下直角三角形**
```
1. 输入 n
2. for i = 1 到 n
3. for j = 1 到 n-i // 先打 n-i 个空格
4. 输出 " " // 两个空格(跟星号对齐)
5. for j = 1 到 i // 再打 i 个星
6. 输出 "* "
7. 输出换行
```
### 真实代码
**左下直角三角形**
```cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) { // 关键j <= i
cout << "* ";
}
cout << endl;
}
return 0;
}
```
**右下直角三角形**
```cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
// 先打空格
for (int j = 1; j <= n - i; j++) {
cout << " "; // 两个空格,跟 "* " 宽度一致
}
// 再打星号
for (int j = 1; j <= i; j++) {
cout << "* ";
}
cout << endl;
}
return 0;
}
```
### 注意点
1. **空格数量要对齐**:如果星号之间用 `"* "`(星号+空格),那么空格也要打印两个空格 `" "`,否则对不齐。
2. **左下直角三角形最简单**:第 i 行 = i 个星,这是所有图形打印的母题,先把这个吃透。
3. **右下 = 左下 + 空格**:右下直角就是把左下直角往右推,推的力度 = 前面的空格数。
---
## 题目三:等腰三角形与菱形
### 核心代码(一句话)
> 等腰三角形的核心:第 i 行有 **2i - 1** 个星号,前面的空格数为 **n - i**;菱形 = 正等腰 + 倒等腰。
### 自然语言思路
**等腰三角形**
第一步观察规律n=5 时第1行1个星第2行3个星第3行5个星……每行多2个星。
第二步,归纳公式:第 i 行星号数 = `2 * i - 1`
第三步,空格规律和右下直角一样:第 i 行前面 n-i 个空格。
第四步,先打空格,再打星号,换行,搞定。
**菱形**
第一步,把菱形拆成两半:上半 = n 行等腰三角形,下半 = n-1 行倒等腰三角形。
第二步,上半直接复用等腰三角形代码。
第三步,下半倒过来:从第 n-1 行开始,递减到第 1 行。空格和星号公式不变,只是循环方向反过来。
第四步,上下拼起来就是菱形。
### 伪代码
**等腰三角形**
```
1. 输入 n
2. for i = 1 到 n
3. for j = 1 到 n-i // 空格n-i 个
4. 输出 " "
5. for j = 1 到 2*i-1 // 星号2i-1 个
6. 输出 "*"
7. 输出换行
```
**菱形**
```
1. 输入 n上半部分行数
2. // 上半:正等腰三角形
3. for i = 1 到 n
4. 打空格、打星号、换行(同上)
5. // 下半:倒等腰三角形
6. for i = n-1 递减到 1
7. 打空格、打星号、换行(同上)
```
### 真实代码
**等腰三角形**
```cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
// 空格
for (int j = 1; j <= n - i; j++) {
cout << " ";
}
// 星号2i - 1
for (int j = 1; j <= 2 * i - 1; j++) {
cout << "*";
}
cout << endl;
}
return 0;
}
```
**菱形**
```cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
// 上半部分:正等腰三角形
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) cout << " ";
for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
cout << endl;
}
// 下半部分倒等腰三角形n-1 行)
for (int i = n - 1; i >= 1; i--) {
for (int j = 1; j <= n - i; j++) cout << " ";
for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
cout << endl;
}
return 0;
}
```
### 注意点
1. **等腰三角形星号公式 `2*i-1`**这是最核心的公式建议学生背下来。推导第1行1个每行多2个 → 等差数列 → 1 + 2×(i-1) = 2i-1。
2. **菱形下半部分循环递减**`for (i = n-1; i >= 1; i--)`,注意从 `n-1` 开始,不是 `n`,否则中间那行会重复。
3. **空格只用一个空格**:等腰三角形通常用一个空格 `" "` 而不是两个,因为星号之间不加空格。
4. **如果 n=1**:下半部分 `i = 0``0 >= 1` 为假,不执行,只打印一行星号,也是对的。
---
## 图形打印技巧总结
| 图形 | 第 i 行星号数 | 第 i 行空格数 | 关键点 |
|------|-------------|-------------|--------|
| 左下直角三角形 | `i` | 0 | 最简单,母题 |
| 左上直角三角形 | `n - i + 1` | 0 | 倒过来即可 |
| 右下直角三角形 | `i` | `n - i` | = 左下 + 空格 |
| 右上直角三角形 | `n - i + 1` | `i - 1` | = 左上 + 空格 |
| 等腰三角形 | `2i - 1` | `n - i` | 核心公式 |
| 倒等腰三角形 | `2i - 1` | `n - i` | i 递减即可 |
| 菱形 | 上同等腰,下同倒等腰 | 同上 | 上下拼接 |
---
## 本课打油诗
> 外层循环管行数,内层循环管列数。
> 图形打印找规律,行列关系是正路。
> 第 i 行星号看公式,空格星号分清楚。
> 等腰三角二 i 减一,菱形上下拼一處。
---
## 课后作业
1. 输入 n打印左上直角三角形第1行 n 个星第2行 n-1 个星……)
2. 输入 n打印数字三角形第1行1第2行1 2……
3. 输入 n 和 m打印 n 行 m 列的空心矩形(只有边框有星号)
4. 输入 n打印九九乘法表第 i 行输出 i 个乘法式子)