流程控制
这是什么:流程控制——让程序"看情况办事"的语法: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 挨个点名。
动手改
- 把 if 那段加一条:分数正好 59 时输出"差一分及格,惨"
- 用 for 输出 1~100 里所有的偶数
- 把 while 的条件改成
hp >= 0,数数会多打几行?体会条件边界的影响 - 写一个 switch 表达式,把输入 1~7 映射到"星期一"~"星期日",其他输入返回"无效"
下一章:数组与方法,把数据排排站、代码装盒子 🐸