# 第20节教案 —— 嵌套循环——循环里面套循环（60分钟）
> **GESP等级：一级 | 考级考点：GESP Python 一级**


> **核心文件**：`05_nested_loop.py`
> **本课定位**：在前4节学会用 for 做单层循环后，引入"循环套循环"——让程序的外层管"几个"，内层管"什么"
> **GESP 考点**：#11 嵌套循环
> **记忆钩子**："外层管几个，内层管什么" / "嵌套=乐高拼装"
> **核心策略**：先画正方形(内层)重复画12次(外层)→拆成两层循环→理解执行顺序

---

## 教学目标

- **知识层**：能说出嵌套循环中外层和内层各自的职责；能准确计算嵌套循环的总执行次数（外层次数 × 内层次数）
- **技能层**：能用两层 for 循环画出"12个正方形围一圈""8个三角形围一圈"等重复图案
- **思维层**：遇到"重复做某件事 N 次，而每件事本身又包含重复步骤"的需求时，能自然想到嵌套循环
- **情感层**：体验"用几行代码指挥海龟画出漂亮图案"的成就感——两层循环就能创造复杂图形

---

## 教学节奏（60分钟）

---

### 00:00-10:00 导入：画12个正方形围一圈

#### 00:00-03:00 发布任务 + 制造认知冲突

> "同学们，上节课我们学了 range 的步长——正着走、跳着走、倒着走。今天我们来做一件更酷的事——画12个正方形，围成一圈！就像这样："

**老师先在黑板上画出效果示意图**（12个小正方形围成一个圆环）：

```
  □ □ □ □
 □       □
□         □
□         □
 □       □
  □ □ □ □
```

> "想象一下：海龟先画一个正方形，然后右转30°（因为 360÷12=30），再画一个正方形，再转30°……一共画12个！"

#### 03:00-06:00 先让学生尝试 + 发现痛点

> "大家想想，不用嵌套循环，只用我们学过的 for 循环，怎么实现？"

**引导学生思考**：
- 画一个正方形：`for i in range(4): forward(50); right(90)`
- 然后右转30°
- 再画一个正方形……
- 重复12次

> "如果不用嵌套循环，我们需要把同样的代码复制12遍——太蠢了吧？"

**板书冗余代码**：
```python
# 画第1个正方形
for i in range(4):
    forward(50); right(90)
right(30)
# 画第2个正方形
for i in range(4):
    forward(50); right(90)
right(30)
# 画第3个正方形
# ……（复制到第12个）
```

> "老师——我手都酸了！有没有办法让代码重复执行这4条边+旋转的步骤？"

> "有！——这就是今天的主角：**嵌套循环**！循环里面再套一个循环。"

#### 06:00-10:00 引出嵌套循环概念

**板书大字**：

```
┌─────────────────────────────────────┐
│         嵌套循环 = 乐高拼装          │
│                                      │
│   外层循环：决定"拼几个零件"          │
│   内层循环：决定"每个零件怎么拼"      │
│                                      │
│   画12个正方形围一圈：                 │
│   外层：for j in range(12):   ← 12次 │
│       内层：for i in range(4): ← 正方形4条边 │
│           forward(50)                 │
│           right(90)                   │
│       right(30)     ← 转30°再画下一个 │
└─────────────────────────────────────┘
```

> "**外层管'几个'，内层管'什么'**——全班跟我念三遍！"

---

### 10:00-30:00 知识点讲解

#### 10:00-16:00 知识点①：外层管"几个"，内层管"什么"

##### 10:00-12:00 拆解"12个正方形围一圈"

**逐层分析**（边讲边板书）：

| 层级 | 问题 | 答案 | 代码 |
|:---:|:----|:----|:----|
| 整体 | 要画几个图形？ | 12个正方形 | `for j in range(12):` |
| 内层 | 每个图形怎么画？ | 画一个正方形 | `for i in range(4):` `forward(50); right(90)` |
| 连接 | 画完一个后做什么？ | 右转30° | `right(30)` |

> "**外层决定做几次，内层决定每次做什么**。就像包饺子——外层管包多少个饺子，内层管每个饺子怎么包（擀皮→放馅→捏口）。"

**类比表格**：

| 场景 | 外层（几个） | 内层（什么） |
|:----|:-----------|:-----------|
| 12个正方形围一圈 | 画12次 | 每次画一个正方形（4条边） |
| 包12个饺子 | 包12个 | 每个：擀皮→放馅→捏口 |
| 写5行字 | 写5行 | 每行：写10个字 |
| 上5天课 | 上5天 | 每天：上6节课 |

##### 12:00-14:00 乐高拼装比喻

**实物演示**（带上乐高或积木到课堂）：

> "搭一个乐高城堡——你要先决定搭几层（外层），然后每一层怎么搭（内层）。如果外层是'搭3层'，内层是'每层搭4块积木'——那就是 3×4=12 块积木。外层管个数，内层管细节。"

**板书**：

```
  外层（几层）    ×    内层（每层几块）   =    总积木数
     3                  4                   12
```

> "嵌套循环也是一样的道理——外层循环的次数 × 内层循环的次数 = 总执行次数。"

##### 14:00-16:00 身体记忆法：全班齐做

> "全班起立！我们来做嵌套循环的身体操："

- "**外层**：左臂画大圈——1圈、2圈、3圈……（代表外层执行次数）"
- "**内层**：右臂快速画小圈——转4次完整的小圈才停止（代表内层完整执行）"
- "**顺序**：先左臂画1个大圈（外层第1次）→右臂快速画4个小圈（内层完整4次）→左臂画第2个大圈→右臂再画4个小圈……"

> "看到了吗？外层的1次，对应内层的"完整"执行。不是外层做一下、内层做一下、再外层做一下——而是外层做一次，内层从1到4全部做完！"

**关键板书**：

```
外层第1次 → 内层第1次 → 内层第2次 → 内层第3次 → 内层第4次（内层结束）
外层第2次 → 内层第1次 → 内层第2次 → 内层第3次 → 内层第4次（内层结束）
外层第3次 → 内层第1次 → 内层第2次 → 内层第3次 → 内层第4次（内层结束）
……
```

---

#### 16:00-24:00 知识点②：执行顺序——外层一次→内层完整→外层一次→内层完整

##### 16:00-20:00 用"打印数字"推导执行顺序

> "图形太抽象？我们先看打印数字——用 print 看清楚嵌套循环的执行顺序。"

**运行以下代码**（先展示在 PPT 或黑板上）：

```python
for j in range(3):            # 外层3次
    print("===== 外层第", j, "次 =====")
    for i in range(4):        # 内层4次
        print("  内层第", i, "次")
    print("===== 内层结束 =====")
```

**让学生预测输出**（2分钟讨论）：

| 预测问题 | 答案 |
|:--------|:----|
| "外层第0次"出现几次？ | 1次 |
| "内层第0次"出现几次？ | 3次（每轮外层都有完整的内层） |
| 总共打印几行？ | 3×(1+4+1) = 18行 |
| "内层结束"出现在什么时候？ | 每次内层循环结束后 |

**上机验证**：

```
===== 外层第 0 次 =====
  内层第 0 次
  内层第 1 次
  内层第 2 次
  内层第 3 次
===== 内层结束 =====
===== 外层第 1 次 =====
  内层第 0 次
  内层第 1 次
  内层第 2 次
  内层第 3 次
===== 内层结束 =====
===== 外层第 2 次 =====
  内层第 0 次
  内层第 1 次
  内层第 2 次
  内层第 3 次
===== 内层结束 =====
```

> "看到了吗？顺序不是 '外0→内0→外1→内1'，而是 **外层走一步，内层跑完全程**！记住：**外层一次，内层一轮**！"

##### 20:00-24:00 执行次数 = 外层 × 内层

**关键问题**：

> "外层循环 j 从 0 到 2（共3次），内层循环 i 从 0 到 3（共4次），那么 '在内层打印' 这句话总共执行了多少次？"

**推导**：
```
外层第0次 → 内层执行了4次
外层第1次 → 内层执行了4次
外层第2次 → 内层执行了4次
总次数 = 3 × 4 = 12 次
```

**公式板书**：

```
嵌套循环总执行次数 = 外层循环次数 × 内层循环次数
```

> "这个公式非常非常重要，GESP 必考！跟着我算几个："

| 外层次数 | 内层次数 | 总次数 |
|:-------:|:-------:|:------:|
| 5 | 3 | 15 |
| 6 | 4 | 24 |
| 10 | 7 | 70 |
| n | m | n × m |

> "全班跟我念：**外层管几个，内层管什么；外乘内，得总数！**"

---

### 30:00-40:00 演示：12个正方形围一圈（完整代码）

#### 30:00-35:00 先执行内层——单独画一个正方形

> "写嵌套循环有个技巧：**先写好内层，再包上外层**。我们先确保内层能正确画出一个正方形。"

```python
import turtle
t = turtle.Turtle()
t.speed(5)

# 先写内层——画一个边长为50的正方形
for i in range(4):
    t.forward(50)
    t.right(90)
```

> "运行——海龟画了一个正方形。好的，内层没问题。"

#### 35:00-38:00 包上外层——画12次

> "现在我们要画12个正方形围一圈——那就是把上面的整个过程重复12次，每次画完后右转30°。"

```python
for j in range(12):           # 外层：画12次
    # 内层：画一个正方形
    for i in range(4):
        t.forward(50)
        t.right(90)
    # 画完一个，右转30°
    t.right(30)
```

> "仔细看——内层循环需要缩进4个空格，外层循环的代码也要缩进。内层的 `forward` 和 `right(90)` 缩进更多（两层缩进），`right(30)` 只缩进一层（属于外层）。"

**强调缩进层级**：

```
for j in range(12):          ← 外层，顶格
    for i in range(4):       ← 内层，缩进1层
        t.forward(50)        ← 内层内部，缩进2层
        t.right(90)          ← 内层内部，缩进2层
    t.right(30)              ← 外层内部（不在内层），缩进1层
```

> "缩进决定代码属于哪一层——这是 Python 最重要的规则！缩进错了，代码就错了。"

#### 38:00-40:00 观察效果 + 参数微调

**运行完整代码**，海龟画出12个正方形围成一圈。

> "太神奇了！四行代码（不算 import）就画出了12个正方形！如果我们想画24个正方形呢？"

> "只要把外层的 `range(12)` 改成 `range(24)`，转角的 `right(30)` 改成 `right(15)`（因为 360÷24=15°）。"

> "**外层改个数，内层不用动**——这就是嵌套循环的威力！"

---

### 40:00-55:00 实操环节（3道题）

#### 40:00-45:00 实操① —— 填空：外层管___ 内层管___

> "独立完成填空，不能讨论。这是对刚才知识点的检查。"

**填空题**（发纸或投屏）：

```
1. 在嵌套循环中，外层循环管"______"，内层循环管"______"。
2. 嵌套循环的执行顺序是：外层____次 → 内层______ → 外层____次 → 内层______
3. 如果外层循环执行 6 次，内层循环执行 4 次，内层代码总执行次数 = ____ × ____ = ____ 次。
4. 画12个正方形围一圈，外层 range(____)，内层 range(____)，转角 = ____°
5. 画8个三角形围一圈，外层 range(____)，内层 range(____)，转角 = ____°
```

**答案速查**（2分钟同桌互批）：

| 题号 | 答案 |
|:---:|:-----|
| 1 | 几个，什么 |
| 2 | 一，完整，一，完整 |
| 3 | 6 × 4 = 24 |
| 4 | 12, 4, 30 |
| 5 | 8, 3, 45 |

> "全对的举手！错1个以上的，课后要重看知识点。注意第5题——三角形是3条边，所以内层 range(3)，转角 360÷8=45°。"

#### 45:00-50:00 实操② —— 预测总次数

> "不要打开电脑！用你的大脑运行这段代码，预测输出结果。"

```python
total = 0
for j in range(5):           # 外层5次
    for i in range(3):       # 内层3次
        total = total + 1
print(total)
```

> "`total` 最后等于多少？"

**小组讨论（2分钟）** → 举手回答。

**推导**：
- 外层5次，内层3次
- total = total + 1 被执行了 5 × 3 = 15 次
- total 从0开始，每次加1 → 最终 total = 15

**验证**：
```python
print(5 * 3)    # 15
```

> "这个推理过程很重要——**外层次数 × 内层次数 = 内层代码执行次数**。GESP 的嵌套循环题考的就是这个！"

**进阶题**（如果时间充裕）：

```python
total = 0
for j in range(3):
    for i in range(4):
        total = total + 1
        print("第", total, "次：外层j=", j, "内层i=", i)
```

> "预测输出！注意观察 j 和 i 的变化规律：j 变化慢（外层慢），i 变化快（内层快）。"

**关键观察**：
- j = 0 时，i 从 0→1→2→3（内层完整走完）
- j = 1 时，i 再次从 0→1→2→3
- j = 2 时，i 再次从 0→1→2→3
- 总共 3×4 = 12 行输出

#### 50:00-55:00 实操③ —— 画8个三角形围一圈

> "终极挑战！用嵌套循环画出8个等边三角形围成一圈。给你3分钟，在电脑上完成。"

**引导提示**：
- 外层：画8次 → `for j in range(8):`
- 内层：画一个三角形 → `for i in range(3): forward(60); right(120)`
- 转角：360° ÷ 8 = 45° → `right(45)`
- 颜色：建议用彩色区分不同三角形

**参考答案**：

```python
import turtle
t = turtle.Turtle()
t.speed(5)

for j in range(8):             # 外层：画8个
    t.color(["red", "orange", "gold", "green",
             "blue", "purple", "pink", "cyan"][j])
    for i in range(3):         # 内层：每个三角形3条边
        t.forward(60)
        t.right(120)
    t.right(45)                # 转45°画下一个
```

**拓展思考**：

> "如果我不想让三角形围成一圈，而是让它们排成一排呢？"
> - 外层 `range(8)` 不变
> - 画完一个三角形后，不是 `right(45)`，而是 `penup(); forward(80); pendown()`

> "如果我想画6个六边形围成一圈呢？"
> - 外层 `range(6)`
> - 内层 `range(6)`，转角 60°
> - 整体转角 360÷6 = 60°

---

### 55:00-60:00 小测 + 总结

#### 55:00-57:00 当堂小测

> **"外层循环执行6次，内层循环执行4次，内层代码总共执行多少次？"**

**选项**：
A. 10 次
B. 24 次
C. 6 次
D. 4 次

**答案**：B. 24 次（6 × 4 = 24）

> "为什么是乘不是加？因为外层每执行1次，内层就要完整地执行4次。外层6次 × 内层4次 = 24次。"

**第二题**：

> **"以下代码会画出什么图案？"**

```python
for j in range(6):
    for i in range(4):
        forward(40)
        right(90)
    right(60)
```

**选项**：
A. 6个正方形排成一排
B. 6个正方形围成一圈
C. 4个正方形围成一圈
D. 4个三角形排成一排

**答案**：B. 6个正方形围成一圈

> "内层 range(4) 画正方形，外层 range(6) 画6次，转角 360÷6=60°——所以是6个正方形围一圈。"

#### 57:00-59:00 记忆钩子整理

**黑板大字（全班齐读三遍）**：

```
┌──────────────────────────────────────┐
│       嵌套循环 记忆钩子              │
│                                      │
│   📌 外层管"几个"，内层管"什么"      │
│   📌 嵌套 = 乐高拼装                 │
│   📌 外层一次 → 内层完整              │
│   📌 总次数 = 外层 × 内层             │
│   📌 外层变化慢，内层变化快            │
└──────────────────────────────────────┘
```

**身体记忆法（全班起立）**：

| 口诀 | 动作 |
|:----|:-----|
| "外层管几个" | 左手画大圈 |
| "内层管什么" | 右手画小正方形 |
| "外层一次内层完整" | 左臂大圈1次 → 右臂快速画4次小圈 |
| "外层×内层=总次数" | 双手比划乘号（交叉手臂） |

**同桌互讲（1分钟）**：
> "给你的同桌用一句话讲清楚：什么是嵌套循环？"

**参考回答**：
> "嵌套循环就是一个循环里面还有一个循环。外层管一共做几次，内层管每次做什么。外层做一次，内层完整做完所有次。总次数 = 外层 × 内层。"

#### 59:00-60:00 结课 + 预告

> "今天我们学会了一招'降维打击'——用嵌套循环，几行代码就能画出复杂的重复图案。12个正方形围一圈、8个三角形围一圈——都不在话下！"
>
> "回忆一下我们学过的内容：第20节学了重复代码→引出 for 循环；第20节学了 range(n)；第20节学了 range(start,stop,step)；第20节学了正多边形公式；第20节（今天）学了嵌套循环。"
>
> "下一节课——我们要综合运用所有知识，完成一个创意大挑战！下节课见！"

---

## 板书设计

```
┌────────────────────────────────────────────────────────────┐
│        第20节  嵌套循环——循环里面套循环                │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  ① 什么是嵌套循环？                                       │
│     ┌─ 外层管"几个"（重复次数）                            │
│     └─ 内层管"什么"（每次做什么）                          │
│                                                            │
│  ② 执行顺序                                               │
│     外层第1次 → 内层完整(1,2,3,4…) → 外层第2次 → 内层完整 │
│     口诀：外层一次，内层一轮                               │
│                                                            │
│  ③ 总次数公式                                             │
│     总次数 = 外层次数 × 内层次数                          │
│     例：外层6次 × 内层4次 = 24次                          │
│                                                            │
│  ④ 经典案例                                               │
│     12个正方形围一圈：                                      │
│     for j in range(12):          ← 外圈12次               │
│         for i in range(4):       ← 正方形4边              │
│             forward(50)                                    │
│             right(90)                                      │
│         right(30)                ← 转角30°                │
│                                                            │
│     8个三角形围一圈：                                       │
│     for j in range(8):           ← 外圈8次                │
│         for i in range(3):       ← 三角形3边              │
│             forward(60)                                    │
│             right(120)                                     │
│         right(45)                ← 转角45°                │
│                                                            │
│  记忆钩子：                                                 │
│  📌 "外层管几个，内层管什么"                                │
│  📌 "嵌套=乐高拼装"                                        │
│  📌 "总次数=外层×内层"                                     │
└────────────────────────────────────────────────────────────┘
```

---

## GESP 考点对照

| GESP编号 | 考点内容 | 本关对应 |
|:--------:|:--------|:--------|
| #11 | 嵌套循环 | 全部内容：外层内层职责、执行顺序、总次数计算 |

---

## 易错点速查

| 错误 | 原因 | 纠正 |
|:----|:----|:------|
| 内层和外层的缩进搞反 | 不理解缩进决定层级 | 用"冒号后缩进"规则，内层比外层多缩进4空格 |
| 以为"外层1次→内层1次→外层1次→内层1次"交替执行 | 不理解"外层一次内层完整" | 用print代码演示执行顺序，亲眼观察 |
| 总次数用加法（6+4=10）而不是乘法（6×4=24） | 把"一次"理解成"一对一" | 身体演示：左臂画6个大圈，每1个大圈对应右臂画4个小圈 |
| 忘记内层结束后需要转角度（right(θ)） | 以为内层画完自动换位 | 对比：不转角度→所有正方形重叠在一起 |
| 所有图形重叠在一起看不出是"围一圈" | 忘记每画一个后海龟要转角度 | 强调"画完一个→转θ°→画下一个"的逻辑 |
| 内层循环的变量和外层循环的变量重名 | 都用 i 导致冲突 | 使用不同变量名：外层用 j，内层用 i |

---

## 配套资源

| 文件 | 用途 |
|:----|:-----|
| `05_nested_loop.py` | 课堂演示代码 |
| `课堂练习册_第20节_嵌套循环.md` | 学生课堂练习 |
| `课后练习卡_第20节_嵌套循环.md` | 课后巩固作业 |
