GESP 二级 第 07 讲:多重循环与嵌套

本讲定位二级最难的一讲,也是二级编程题的主要考点。官方大纲要求”掌握多层循环结构,掌握 for 语句、while 语句、do...while 语句,及相互嵌套的方法”。一级第 08 讲学的是”一段代码跑 n 遍”;这一讲要理解的是”跑 n 遍的那段代码,本身又跑了 m 遍”——总共 $n \times m$ 遍。学生在这里的掉队率比一级第 08 讲还高,因为两个循环变量同时在动,脑子跟不上。本讲的解法只有一个:手工模拟表,而且要画得比一级更细。

对应官方大纲:二级知识块 7「多层循环语句」——while 循环、do...while 循环、for 循环的嵌套。

前置知识:一级第 08 讲(三种循环、break/continue、手工模拟表)、二级第 06 讲(嵌套的层次梳理)。一级第 08 讲没吃透的学生,本讲必然崩盘——请先回去补。

代码说明:本讲所有代码均已用 g++ 11.5(-std=c++11)编译运行验证,输出结果即为文中标注结果。


1. 先看一道真题

下面程序的输出是什么?

for (int i = 1; i <= 2; i++) {
    for (int j = 1; j <= 3; j++) {
        cout << i << j << " ";
    }
}

学生的典型错误答案是 11 22(以为两个循环变量”手拉手”一起走)。

正确答案:

11 12 13 21 22 23

规律:外层 i 每取一个值,内层 j 要把 1、2、3 完整跑一遍**。** 所以一共输出 $2 \times 3 = 6$ 组。

这就是循环嵌套的全部秘密,本讲剩下的内容都是它的应用。


2. 嵌套循环的执行规律

2.1 三句口诀

外层走一步,内层走一圈。总执行次数 = 外层次数 × 内层次数。内层的循环变量,每次进入内层都要重新初始化。

2.2 完整的手工模拟表

这是本讲的核心工具,比一级的模拟表多了一列。

以第 1 节的代码为例:

外层 i 内层 j 输出 说明
1 1 11 内层第 1 圈开始
1 2 12
1 3 13
1 4 4 <= 3 假,内层结束,回外层
2 1 21 ⚠️ j 重新从 1 开始
2 2 22
2 3 23
2 4 内层结束
3 3 <= 2 假,外层结束

⚠️⚠️ 表中标 ⚠️ 的那一行是全讲最重要的一行外层进入第 2 轮时,j 又变回 1 了。因为 for (int j = 1; ...) 这句初始化,每次进入内层循环都会重新执行一次

学生最常犯的错就是以为 j 会接着上次的 4 继续走。画表时一定要把这一步显式写出来。

2.3 嵌套的顺序:外层慢,内层快