🐸 青蛙编程网
首页 / C# / C# 基础 / 4. 流程控制

流程控制

这是什么:流程控制——让程序"看情况办事"的语法:if/else 决定走哪条路,for/while 管重复。

为什么用:目前为止,代码都是从上往下一行行跑,可真实需求总带条件:分数够不够才发奖、要连着算十次。不学流程控制,程序就只能像复读机一样从头念到尾。

如何用:先用一个成绩判断的 if/else 走通分支,再上 for 循环重复干活。

if / else:走哪条路

int score = 75;

if (score >= 90)
{
    Console.WriteLine("优秀!");
}
else if (score >= 60)
{
    Console.WriteLine("及格,再接再厉");
}
else
{
    Console.WriteLine("不及格,补考见");
}
及格,再接再厉

条件从上往下逐个检查,命中一个就进、全不中走 else。注意:判断相等要写两个等号 ==,一个等号 = 是赋值——新手最常混的一对。

条件还能拼起来:&& 是"并且",|| 是"或者",! 是取反(Python 写 and/or/not,C# 换了长相):

写法 意思 举例
a && b 两个都成立才成立 age >= 6 && age <= 12(小学生)
a || b 有一个成立就成立 day == 6 || day == 7(周末)
!a 取反 !isVip(不是会员)

switch 表达式:多岔口的现代写法

C# 8 之后,switch 从"语句"进化成了"表达式",能直接产出一个值:

int score = 85;

string level = score switch
{
    >= 90 => "优秀",
    >= 80 => "良好",
    >= 60 => "及格",
    _     => "不及格"
};

Console.WriteLine(level);
良好
部件 含义
=> "就返回":满足条件时给出的值
>= 90 条件模式,从上往下第一个命中的生效
_ 兜底,相当于 else

记住顺序:从上往下,先满足先得——条件写反了,结果就错了。老教程里还有又长又容易忘 break 的传统 switch 语句,新版几乎一统江湖,见到老写法认识即可。

for:数着圈跑

for (int i = 1; i <= 3; i++)
{
    Console.WriteLine($"第 {i} 个俯卧撑");
}
第 1 个俯卧撑
第 2 个俯卧撑
第 3 个俯卧撑

for (初始; 条件; 更新) 三段式:i 从 1 出发,只要 i <= 3 就干活,每轮结束 i++ 加一。

for 遍历数组

string[] fruits = { "苹果", "香蕉", "橘子" };
for (int i = 0; i < fruits.Length; i++)
{
    Console.WriteLine($"第 {i} 个:{fruits[i]}");
}

while:满足就继续

int hp = 10;
while (hp > 0)
{
    hp -= 3;
    Console.WriteLine($"掉血!剩余 HP:{hp}");
}
掉血!剩余 HP:7
掉血!剩余 HP:4
掉血!剩余 HP:1
掉血!剩余 HP:-2

条件是 hp > 0,所以 -2 那次也打了出来——差一个符号,多跑一圈。另外,条件永远成立时就是"死循环",程序会卡住不动,这时按 Ctrl + C 强制停止(猜数字那章会故意用一次 while (true))。

do-while:先跑一次再判断

int i = 0;
do
{
    Console.WriteLine(i);
    i++;
} while (i < 3);
0
1
2

do-while 保证至少执行一次循环体,因为判断在最后。

foreach:挨个过一遍

要处理"一堆东西"时,foreach 最省心,不用管下标:

string[] fruits = { "苹果", "香蕉", "橘子" };
foreach (string f in fruits)
{
    Console.WriteLine($"来一个{f}");
}
来一个苹果
来一个香蕉
来一个橘子

foreach 拿不到下标。需要第几个时改用 for:for (int i = 0; i < fruits.Length; i++) 循环里 fruits[i] 就是第 i 个。

❓ 常见问题

Q1:if 里能不写大括号吗?

C# 允许只有一行时省略 {},但强烈建议永远写大括号。省略大括号容易在后续修改代码时引入难以察觉的 bug。

Q2:for 里的 i 在循环外还能用吗?

不能。for (int i = 1; ...) 里的 i 作用域仅限于循环内部,循环结束后 i 就销毁了。

Q3:switch 表达式和传统 switch 有什么区别?

switch 表达式是 C# 8+ 的新写法,能直接返回一个值,代码更简洁;传统 switch 是语句,每个 case 要写 break,容易漏写导致"穿透"。新代码优先用 switch 表达式。

⚠️ 新手翻车现场

翻车一:= 和 == 写混

// 错误:if 里用了一个等号,变成了赋值
if (score = 60) { ... }

问题:score = 60 是赋值表达式,值为 60(非零即真),if 永远成立,而且把 score 顺手改成了 60。

修正:比较要用 ==:if (score == 60) { ... }。

翻车二:while (true) 忘了 break,程序跑不停

while (true)
{
    Console.WriteLine("一直在打印…");
    // 没有 break,也没有让条件变假的代码
}

问题:这是个真正的死循环,程序不会自己停,得手动强制结束(Ctrl+C 或关闭终端)。

修正:在循环里加 break 条件,或改成 while (hp > 0) 这类会终止的条件。

翻车三:foreach 里修改集合

foreach (string f in fruits)
{
    if (f == "香蕉") fruits.Remove(f);  // ❌ 运行时报错:集合在遍历时被修改
}

问题:C# 不允许在 foreach 遍历时修改集合。

修正:用 for 倒序遍历,或先收集要删的项再统一删除。

🎯 什么时候用哪种循环

场景 推荐 原因
已知循环次数 for 三段式清晰,初始、条件、更新集中在一行
次数未知,先判断后执行 while 条件不满足时可能一次都不执行
次数未知,至少执行一次 do-while 先执行循环体,再判断条件
遍历集合/数组 foreach 最省心,不用管下标
多个固定值匹配 switch 表达式 比一串 if/else 更清晰,还能返回值

📝 本章小结

  • if/else if/else:条件带小括号,地盘用大括号
  • switch 表达式:从上往下,先满足先得,_ 是兜底
  • for:已知次数循环,三段式(初始;条件;更新)
  • while:未知次数,条件为真就转
  • foreach:遍历集合,不用管下标
  • break 跳出整个循环,continue 跳过本轮
  • 记忆口诀:if 挑路,switch 多岔口;for 数圈,while 认死理,foreach 挨个点名。

动手改

  1. 把 if 那段加一条:分数正好 59 时输出"差一分及格,惨"
  2. 用 for 输出 1~100 里所有的偶数
  3. 把 while 的条件改成 hp >= 0,数数会多打几行?体会条件边界的影响
  4. 写一个 switch 表达式,把输入 1~7 映射到"星期一"~"星期日",其他输入返回"无效"

下一章:数组与方法,把数据排排站、代码装盒子 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。