1. 入门
先来个问题:为啥要把一个循环套进另一个循环里?其实很多时候,我们的数据或者任务不是一条线排的,而是像表格、网格,甚至多维结构。比如你想在屏幕上输出乘法表,遍历二维数组,或者统计所有元素对的交集。这种时候,一个循环肯定不够用——得循环里套循环。
在编程里,嵌套循环就像两个闹钟:外面的先响,里面的每次都要响一遍,只要外面的还在响。也就是说,每次外层循环迭代,内层循环都会完整跑一遍(而且每次外层都要重新来一次)。
举个例子——小时和分钟。小时是外层循环,从0到23,分钟是内层循环,从0到59。每次外层变一次,内层都能把所有值跑一遍。
2. 嵌套循环的语法
在C#里,嵌套循环的语法和普通循环没啥区别——你只要在另一个循环体里写一个循环就行。来看下for和while的例子:
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
这里外层循环控制变量i(从0到2),内层循环控制变量j(从0到3)。每个i的值,内层循环都会从j=0跑到j=3。你运行下这段代码,会看到一个很整齐的坐标表:
0,0 0,1 0,2 0,3
1,0 1,1 1,2 1,3
2,0 2,1 2,2 2,3
用while写法也一样:
int i = 0;
while (i < 3)
{
int j = 0;
while (j < 4)
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
i++;
}
注意:每次外层循环的时候,内层循环的变量(j)都要重新初始化,不然你只会看到一行!
3. 嵌套循环的例子
例子1:输出棋盘(8x8)
第一个任务——在屏幕上输出经典的棋盘,用黑白格子表示(比如#是黑格,_是白格)。用for嵌套循环来实现:
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 8; col++)
{
if ((row + col) % 2 == 0)
Console.Write("_");
else
Console.Write("#");
}
Console.WriteLine();
}
效果:
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
重点:嵌套保证了每一行(row)都能完整遍历所有列(col)。没嵌套你只能得到一行或者一列,根本不是棋盘。
例子2:乘法表
最经典的嵌套循环用法之一!来输出1-9的乘法表:
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
Console.Write($"{i * j,3} ");
}
Console.WriteLine();
}
${i * j,3}这个格式化是为了让表格看起来更整齐。
效果:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
...
9 18 27 36 45 54 63 72 81
4. 嵌套循环的控制细节
关于break和continue在嵌套循环里的作用
很多新手会在这里踩坑!如果你在内层循环用break或者continue,它们只影响内层循环。外层循环还是会继续跑。
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
if (j == 3)
break; // 只跳出内层循环!
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
效果:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
如果你想一次性跳出两个嵌套循环(比如在表格里一找到就立刻结束),一般会用个flag或者特殊写法(比如return——如果都在函数里)。
5. 嵌套循环的可视化
有时候很难“看见”嵌套循环的执行顺序。来看下面这个流程图:
表格形式——如果i从1到3,j从1到4,一共多少次迭代?
| i | j(每个i都遍历) | 内层循环迭代次数 |
|---|---|---|
| 1 | 1, 2, 3, 4 | 4 |
| 2 | 1, 2, 3, 4 | 4 |
| 3 | 1, 2, 3, 4 | 4 |
| 总共:3 × 4 = 12 |
6. 嵌套循环常见错误和坑
常见错误——内层循环变量初始化不对。比如在外层循环外面声明变量,但每次没重置。结果内层循环可能根本不跑,或者跑错了。
int j = 0;
for (int i = 0; i < 3; i++)
{
while (j < 4) // 哎呀!j在第一次循环后可能已经等于4了。
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
}
这样循环只会跑一次。记得内层循环变量要在外层循环里初始化!
还有,如果你不小心写了两个嵌套循环用一样的变量名,编译器会报错:变量已经定义过了。
for (int i = 0; i < 3; i++)
{
for (int i = 0; i < 3; i++)
{
Console.Write($"{i},{i} ");
}
Console.WriteLine();
}
GO TO FULL VERSION