第 18 课:循环嵌套
和选择结构的 if 语句一样,循环也是能够嵌套的。
循环嵌套是指在一个循环结构的循环体中又包含了另一个或多个循环结构的程序结构。这些被包含的循环就像"俄罗斯套娃"一样,一层套一层,每一层循环都有自己独立的循环条件和执行语句。
18.1 循环嵌套的基本操作
我们可以先写一个循环,功能是从 1 到 10 进行输出,将此循环计作循环 a。如果想让这个程序(循环输出 1 到 10)执行 5 次,则只需要再写一个循环,功能是循环 5 次,计作 b。然后把循环 a 放入循环 b 中即可,代码如下:
#include <iostream>
using namespace std;
int main()
{
// 循环 b,执行 5 次
for (int i = 1; i <= 5; i++)
{
// 循环 a,从 1 到 10 进行输出
for (int j = 1; j <= 10; j++)
{
cout << j << " ";
}
// 每次内层循环结束后换行,使输出更清晰
cout << endl;
}
return 0;
}输出结果:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 1018.2 实例讲解
例 1:数字矩形
输入两个正整数 m 和 n,请你从 n 到 1 一共打印 m 行。
【输入格式】输入一行,两个用空格隔开的整数 m、n(1 ≤ m ≤ 15,1 ≤ n ≤ 15)。
【输出格式】输出 m 行,每行有 n 个用空格隔开的整数,从 n 输出到 1。
【输入样例】3 5
【输出样例】
5 4 3 2 1
5 4 3 2 1
5 4 3 2 1注:原书输出样例仅剩 1 行(其余行跨页丢失),此处按题意(共 m = 3 行)补全。
解析
- 外层循环:外层循环控制行数,一共有 m 行,每行输入结束会换行。所以外层循环为:
for (int i = 1; i <= m; i++)
{
cout << endl; // 结束换行
}- 内层循环:内层循环控制输出 n 个数,并且是从 n 开始到 1 结束,用空格隔开。因此,在外层循环中的换行前写上:
for (int j = n; j >= 1; j--)
{
cout << j << ' ';
}参考代码
#include <iostream>
using namespace std;
int main()
{
int m, n;
cin >> m >> n;
for (int i = 1; i <= m; i++)
{
for (int j = n; j >= 1; j--)
{
cout << j << ' ';
}
cout << endl;
}
return 0;
}例 2:星号三角形
输入整数 n,请你打印 n 行的 * 号三角形。
【输入格式】输入一行,一个整数 n(1 ≤ n ≤ 20)。
【输出格式】输出 n 行,其中第 i 行有 i 个 * 号。
【输入样例】3
【输出样例】
*
**
***解析
- 假设 i 代表行,当 i = 1 的时候,第 1 行有一颗 *,当 i = 2 的时候,第 2 行有两颗 *,当 i 等于 n 的时候,第 n 行有 n 颗 *。
第 1 行:*
第 2 行:**
第 3 行:***
第 4 行:****- 外层循环同上题,内层循环每 i 行输出 i 个 * 号,行跟 * 是对应的,所以控制内层循环的 j 从 1 颗 * 开始,当 j 等于 i 的时候就是输出当前行的最后一个 * 号,即:
for (int j = 1; j <= i; j++)
{
cout << '*';
}参考代码
#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++)
{
cout << '*';
}
cout << endl;
}
return 0;
}例 3:乘法口诀表
蛙蛙最近在学习数学知识,对乘法口诀表特别感兴趣。
他想要通过打印乘法口诀表来加深记忆。现在请你帮蛙蛙一个忙,当蛙蛙输入一个整数 n 时,打印出前 n 行的乘法口诀表,让蛙蛙能更方便地学习乘法。
【输入格式】输入一行,一个正整数 n(1 ≤ n ≤ 20)。
【输出格式】输出 n 行,格式参考样例,式子之间用 3 个空格隔开,每个式子中的数字和字符隔一个空格。
【输入样例】3
【输出样例】
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9解析
要输出的乘法口诀表如表 3-1 所示。
表 3-1 要输出的乘法口诀表
| 第 1 列 | 第 2 列 | 第 3 列 | |
|---|---|---|---|
| 第 1 行 | 1 * 1 = 1 | ||
| 第 2 行 | 1 * 2 = 2 | 2 * 2 = 4 | |
| 第 3 行 | 1 * 3 = 3 | 2 * 3 = 6 | 3 * 3 = 9 |
i 代表行,j 代表列,第 1 列第 1 行的算式为 1 * 1,第 1 列第 2 行的算式为 1 * 2,第 2 列第 2 行的算式为 2 * 2……第 j 列第 i 行的算式为 j * i。
与前面两题相似,外层循环控制行,内层循环控制列,关系式为"j * i"等于"j * i 的结果"并空 3 个格,即:
for (int j = 1; j <= i; j++)
{
cout << j << " * " << i << " = " << j * i << " ";
}参考代码
#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++)
{
cout << j << " * " << i << " = " << j * i << " ";
}
cout << endl;
}
return 0;
}例 4:字母倒三角
输入整数 n,参考样例格式,打印 n 行字母三角形。
【输入格式】输入一行,一个整数 n(1 ≤ n ≤ 26)。
【输出格式】输出 n 行,格式参考样例,字母用空格隔开,第一行打印从 a 到第 n 个字母,第二行打印从 a 到第 n − 1 个字母,第三行打印从 a 到第 n − 2 个字母……
【输入样例】4
【输出样例】
a b c d
a b c
a b
a解析
以 n = 4 为例,将要输出的字母三角形列成表,如表 3-2 所示。
表 3-2 要输出的字母三角形
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 第 1 行 | a | b | c | d |
| 第 2 行 | a | b | c | |
| 第 3 行 | a | b | ||
| 第 4 行 | a |
- 假设 n 代表输入的行数,共有 4 行,即 n = 4。通过表 3-2 得知,第 1 行有 4 个字母,第 2 行有 3 个字母,第 3 行有 2 个字母,第 4 行有 1 个字母。
由此可以找出规律,第 i 行有 n − i + 1 个字母。
- 通过上述内容继续推导,已知第 1 行有 n 个字母,而第 n 行有 1 个字母,所以外层循环变量 i 应从 n 开始,代表 n 个字母,每次减 1,到 1 结束,每输出一行内容就需要换一行,即:
for (int i = n; i >= 1; i--)
{
cout << endl;
}- 第 1 行,内层循环要输出 n 个字母,此时外层循环变量 i 的值为 n。若内层循环每次要循环输出 i 个字母,可设变量 j 的初始值为 1,j 是小于或等于 i 的,j 每次加 1,则内层循环可以循环 i 次,即:
for (int j = 1; j <= i; j++)- 内层循环体内从 a 开始输出,所以要声明一个字符型变量并将其初始化为 a,内层循环体内每输出一次,用空格隔开,字母就加 1,即:
char a = 'a';
for (int j = 1; j <= i; j++)
{
cout << a << ' ';
a++;
}参考代码
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
for (int i = n; i >= 1; i--)
{
char a = 'a';
for (int j = 1; j <= i; j++)
{
cout << a << ' ';
a++;
}
cout << endl;
}
return 0;
}