循环与跳转
本教程共 100 篇 · 第 19 篇 · 更新于 2026-07-31 · 约 10 分钟阅读
19. 循环与跳转
本节目标:学完能针对不同场景选用合适的循环,并用 break/continue/return 精确控制循环的进出。
很多事要「重复做」:打印 100 行、把数组里每个数加一、一直读输入直到用户退出。靠复制粘贴不现实,循环(loop)才是正解。本章讲四种循环,以及几个控制流程的跳转语句。
一、for:知道要跑多少圈
for 最适合「次数确定」的循环,三个部分写在一行:(初始化; 条件; 迭代)。
for (int i = 1; i <= 5; i++)
{
Console.WriteLine($"第 {i} 次");
}
执行顺序是:先 int i = 1 只跑一次;每次循环前检查 i <= 5;循环体结束后执行 i++,再回到条件检查。所以这里正好打印 5 次。
Note
i++放在循环体之后,所以即便循环体里有continue,迭代步骤仍会执行(对比while要注意这点)。下标i只在for内部可见,循环外访问不到。
二、foreach:挨个遍历集合
当你只想知道集合里每一项,不在乎下标时用 foreach,最安全也最简洁。
int[] numbers = [1, 2, 3];
foreach (int n in numbers)
{
Console.WriteLine(n * 2); // 输出 2、4、6
}
它适用于任何可枚举的对象(数组、List<T>、字符串等)。好处是不会越界,不必手写下标。
Tip经验法则:遍历但不改结构、不需要下标 → 用
foreach;需要在循环里按位置改元素、或倒序遍历 → 用for。foreach里不能增删集合元素,否则会报错。
三、while:条件满足就一直跑
while 先判断条件,为真才执行。它适合「次数未知、靠条件退出」的场景,比如读输入直到合法。
int count = 0;
while (count < 3)
{
Console.WriteLine("循环中");
count++;
}
如果条件一开始就是假,循环体一次都不执行。新手常忘在循环里推进条件,导致「死循环」——程序永远停不下来。务必保证某处会让条件变假。
四、do-while:至少跑一次
do-while 把条件检查放到循环体之后,所以无论条件如何,至少执行一次。
int n = 0;
do
{
Console.WriteLine("我至少出现一次");
n++;
} while (n < 0); // 条件为假,但上面已执行过
典型用途是「先做个动作,再问要不要继续」,比如菜单交互:先显示一次,再判断是否重复。
Note
while与do-while的核心区别就一句话:可能零次 vs 至少一次。需要「先斩后奏」才用do-while。
五、break:立刻跳出循环
break 终止最内层的循环(或 switch),直接跳到循环后面的代码。
int[] numbers = [1, 2, 3, 4, 5];
foreach (int n in numbers)
{
if (n == 3) break; // 遇到 3 就停
Console.WriteLine(n); // 输出 1、2
}
嵌套循环里,break 只跳出它直接所在的那一层。C# 14 不支持带标签的 break/continue,所以要从多层里一起跳出,更常见的做法是把内层循环抽成一个带 return 的方法,或用布尔标志(flag)控制外层何时退出。
六、continue:跳过本次,进入下一轮
continue 不终止循环,只跳过本轮剩余代码,立刻开始下一次迭代。
for (int i = 1; i <= 5; i++)
{
if (i % 2 == 0) continue; // 偶数跳过
Console.WriteLine(i); // 输出 1、3、5
}
Tip
break是「到此为止」,continue是「这轮算了,下一轮继续」。两者配合能把「过滤掉不符合条件」的逻辑写得很干净。
七、return:结束整个方法
return 不光用于返回值,还会直接结束当前方法。在循环里遇到 return,循环和方法一起停。
int FindFirstEven(int[] nums)
{
foreach (int n in nums)
{
if (n % 2 == 0) return n; // 找到第一个偶数就返回,循环也结束
}
return -1; // 没找到
}
Console.WriteLine(FindFirstEven([1, 3, 4, 6])); // 输出 4
八、goto:了解即可,尽量不用
goto 能无条件跳到带标签的语句。它是语言的一部分,但随意使用会让代码像意大利面一样难读。
// 仅作了解,日常几乎不用
goto End;
Console.WriteLine("这行被跳过");
End:
Console.WriteLine("跳到这里");
在 switch 里 goto case 或 goto default; 是合法且偶尔有用的,但普通业务逻辑中,用 break/return 或把循环抽成方法,通常比 goto 更清晰。
Note现代 C# 编程的共识:
goto能不用就不用。需要「从深层跳出」时,优先靠return、提前return或方法拆分来解决。
九、四种循环怎么挑
| 场景 | 首选 |
|---|---|
| 次数明确、需要下标 | for |
| 遍历集合每一项 | foreach |
| 次数不定、先判断再跑 | while |
| 至少跑一次、先执行再判断 | do-while |
Tip不论哪种循环,都要确保「有办法让循环结束」。写
while/do-while时,先想清楚:哪一行让条件最终变假?想不清就容易死循环。
十、为什么需要循环:动机与类比
不理解循环的人,往往会写出「复制粘贴十遍」的代码:打印 10 行就写 10 句 Console.WriteLine。这有三个致命问题:行数爆炸、想改格式得改十处、要打印 1000 行根本不可能手写。
把一批同类型的数据想象成银行一排带编号的储物柜:循环就是你请来的一个管理员,按编号从 1 走到 n,对每个柜子做同一件事。你只要告诉管理员「从几号到几号、每柜干啥」,不用自己跑 n 趟。因此,凡是「对一批数据做同样处理」的需求,第一反应就应该是循环。
十一、for 循环的进阶写法
for 的三个部分其实都很灵活,不一定非得是 i++:
- 一次声明多个变量:
for (int i = 0, j = 10; i < j; i++, j--) - 条件可省略:
for (int i = 0; ; i++)这种「没有条件」会变成死循环,必须靠break出来。 - 最经典的死循环写法:
for (;;)三个部分全空,等价于「永远跑」,常用在「服务器一直等消息」这类场景,靠内部break退出。
int i = 1;
for (;;)
{
if (i > 3) break; // 自己控制退出
Console.WriteLine(i);
i++;
}
Note
while (true)和for (;;)意思完全一样,都是「死循环 + 内部退出」。团队里挑一种统一即可,不必混用。
十二、foreach 的两个坑
foreach 虽好,有两处新手常栽跟头:
- 遍历时不能增删集合:在
foreach里对集合Add或Remove,会立刻抛InvalidOperationException。要边遍历边删,改用for倒序遍历,或先把要删的收进另一个集合再统一删。 - 它也能遍历字符串:
foreach (char c in "你好")会逐个拿出字符。记住这时拿到的是char,不是string。
string text = "你好";
foreach (char c in text)
{
Console.WriteLine(c); // 输出 你、再 好
}
十三、常见错误与 WARNING
- 差一错误(off-by-one):想跑 5 次却写成
i < 4,或想从 0 数到 n 却写成i <= n。记住「< 长度」覆盖 0 到 长度-1,正好全部。 - 死代码:
break/return之后的语句永远执行不到,编译器会警告「无法访问的代码」。写了就删掉,别留着。 while忘记推进条件:循环里不改任何会影响条件的变量,程序卡死。写while时先确认「哪行让条件终会变假」。
Warning在
foreach里修改(增删)正在遍历的集合,是运行时才会炸的坑,编译发现不了。一旦需要「边遍历边改」,立刻换成for循环或先收集再处理,别抱侥幸。
小结
四种循环各有主场:for 管已知次数且要下标,foreach 管只读遍历,while 管条件退出,do-while 管至少一次。break/continue/return 负责在循环里精确转向。
下一章进入数组,把「一堆同类型数据」用一种变量整齐地装起来。