循环嵌套
中等5循环嵌套:让电脑帮你做“套娃”般的重复工作
同学们,你有没有玩过俄罗斯套娃?一个大娃娃里面藏着一个稍小的娃娃,小娃娃里面又藏着更小的娃娃……这就是“嵌套”的意思。
在编程里,循环嵌套就是——在一个循环的“身体”里,再放一个完整的循环。外面的循环每执行一次,里面的循环就要从头到尾完整地跑一遍。
有了循环嵌套,我们可以轻松处理那些需要“重复做某件事,而这件事本身也需要重复”的场景,比如打印一个方块、画个乘法表,甚至模拟一天的生活作息。
一、什么是循环嵌套?
简单说,就是“循环里面套循环”。外面的叫外层循环,里面的叫内层循环。
外层循环每转一圈,内层循环就要从开始到结束完整执行一圈。
这就像你每天上学:一周有5天(外层循环),每一天里你都要上8节课(内层循环)。上课内容就是内层循环体,上完一节课再上下一节,上完一天再进入下一天。
我们来看一个最直观的例子——在屏幕上打印一个 3行5列 的长方形,每行有5个星号。如果只用简单的循环,你要写3遍:
for (int i = 0; i < 5; i++) cout << "* "; // 打印一行5个星号
cout << endl;
// 再手动写下一行,太麻烦……
用循环嵌套就省事多了:
#include <iostream>
using namespace std;
int main() {
for (int row = 1; row <= 3; row++) { // 外层:行数
for (int col = 1; col <= 5; col++) { // 内层:每行5个星号
cout << "* ";
}
cout << endl; // 换行
}
return 0;
}
输出效果:
* * * * *
* * * * *
* * * * *
二、循环嵌套的执行流程(一步步拆解)
很多人刚开始会好奇:计算机到底是怎么跑这些嵌套循环的?我们用上面的长方形例子来一步一步模拟:
- 第一次外层循环(row = 1):
程序遇到内层循环,col从1开始。
col=1 → 打印“* ”;col=2 → 打印“* ”;……直到col=5,打印完毕。
内层循环结束,执行cout << endl换行。 - 第二次外层循环(row = 2):
再次进入内层循环,col重新从1开始,再重复打印5个星号,再换行。 - 第三次外层循环(row = 3):
同理,打印5个星号,换行。 - 外层循环结束(row变成4,大于3),程序退出。
关键点:内层循环的变量(如col)每次外层循环开始时都会被重新初始化(从1开始)。如果忘记初始化,第二次外层循环时内层变量可能还保留上次的值,导致循环不执行或出错。
三、生活中的嵌套例子
除了钟表(分针转一圈时针走一格),再比如学校排队打饭:
- 外层:每个班级轮流去打饭(班级1 → 班级2 → 班级3)
- 内层:班级里的每个同学依次打饭(同学1 → 同学2 → … → 同学n)
如果班级有40人,3个班,那么食堂阿姨要重复“打饭”这个动作共 3 × 40 = 120 次。这就是嵌套的威力:用两行循环就能表达“每个班每个同学”的重复。
再比如课表:
- 外层:周一到周五(5天)
- 内层:每天上午四节课,下午两节课(6节课)
每天的上课节数固定,但每节课内容不同,循环嵌套帮我们把结构清晰地描述出来。
四、常见错误(新手一定要看)
1. 忘记在最外层循环开始时重置内层循环变量
int row = 1, col = 1; // 错误:col只初始化一次
for (row = 1; row <= 3; row++) {
for (col = 1; col <= 5; col++) {
cout << "* ";
}
cout << endl;
}
这样写其实也没错,因为内层循环的 col 每次都在 for 括号里被重新赋值为1。但是如果你把 col = 1 写在循环外面,比如:
int col = 1; // 错误的初始化位置
for (int row = 1; row <= 3; row++) {
for ( ; col <= 5; col++) { // 内层循环不初始化col
cout << "* ";
}
cout << endl;
}
第一次外层循环,内层正常执行,col跑到了6。第二次外层循环时,col还是6,不满足条件,内层循环一次都不执行!结果只打印了一行星号。正确做法:内层循环变量必须在内层 for 括号里初始化,或者在内层循环开始前重置。
2. 内外层循环的条件弄反
比如你想要一个3行5列的长方形,却写成了:
for (int col = 1; col <= 5; col++) { // 外层变成列?
for (int row = 1; row <= 3; row++) {
cout << "* ";
}
cout << endl;
}
这时候输出的是5行3列,形状变了。要分清哪个控制行,哪个控制列。
3. 换行语句放错位置
有时你会把 cout << endl; 放在内层循环里面,导致每个星号后面都换行,打印成一列。记住:换行应该属于外层循环的“善后工作”,内层循环负责打印一行里的所有内容,换行交给外层。
4. 死循环(条件永远满足)
比如内层循环变量忘记更新:
for (int i = 1; i <= 5; ) { // 漏了 i++
for (int j = 1; j <= 3; j++) {
// ……
}
}
外层循环的 i 永远不变,程序卡死。检查循环变量是否有自增(++或 +=1)。
五、完整示例:打印多种图形
例1:打印直角三角形(左对齐)
行数:5行,第1行1个星,第2行2个星,……第5行5个星。
#include <iostream>
using namespace std;
int main() {
int lines = 5; // 总行数
for (int row = 1; row <= lines; row++) { // 外层:行号从1到5
for (int star = 1; star <= row; star++) { // 内层:每行星号数量等于行号
cout << "* ";
}
cout << endl; // 每行结束换行
}
return 0;
}
输出:
*
* *
* * *
* * * *
* * * * *
例2:9×9乘法表(你熟悉的那个)
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++) { // i:被乘数
for (int j = 1; j <= i; j++) { // j:乘数,只到i(下三角)
cout << j << "x" << i << "=" << i*j << " ";
}
cout << endl; // 每行结尾换行
}
return 0;
}
输出前几行:
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
……
例3:打印空心长方形(结合条件判断)
这个例子展示了循环嵌套可以和 if 语句配合使用,让图案更丰富。
#include <iostream>
using namespace std;
int main() {
int rows = 4, cols = 6; // 4行6列
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= cols; c++) {
// 如果是第一行、最后一行、第一列、最后一列,打印星号,否则打印空格
if (r == 1 || r == rows || c == 1 || c == cols) {
cout << "* ";
} else {
cout << " "; // 两个空格占位
}
}
cout << endl;
}
return 0;
}
输出:
* * * * * *
* *
* *
* * * * * *
六、相关指引(下一步学什么)
学完循环嵌套,你还可以继续探索:
- 多重循环(三层、四层):比如打印一个三维数组的每一层,或者模拟多个嵌套的日程表。
break和continue在嵌套循环中的用法:break只跳出它所在的那一层循环,continue跳过本次循环的剩余部分。要注意它们的作用范围。- 循环嵌套与数组结合:比如用双层循环遍历一个二维数组(像表格一样的数据),处理成绩表、迷宫、图像等。
- 优化循环嵌套:过多的嵌套会使程序变慢,学习如何减少不必要的内层循环(比如用公式代替部分循环)。
循环嵌套是编程里非常实用的工具,学会它,很多看似复杂的事情都能轻松搞定。自己动手敲一敲上面的例子,再试试打印一个倒三角形、菱形,或者模拟一个班级的课表吧!
例题精讲
以下嵌套循环中,内层循环总共执行多少次? for(int i=1;i<=3;i++) for(int j=1;j<=i;j++) cout<<"*";
在嵌套循环中,break语句只会跳出包含它的最内层循环。
以下代码用于打印一个3行5列的矩形星号阵,请填空。
for(int i=1;i<=3;i++){
for(int j=1;j<=___;j++){
cout<<"*";
}
cout<<endl;
}执行以下代码后,输出结果中数字5出现的次数是? for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ if(i*j==5) cout<<i*j<<" "; } }
以下代码用于输出1到100之间的所有质数,请填空。
for(int i=2;i<=100;i++){
bool isPrime=true;
for(int j=2;j<=sqrt(i);j++){
if(___==0){
isPrime=false;
break;
}
}
if(isPrime) cout<<i<<" ";
}