专栏导航
← 上一篇:数学运算与逻辑判断 - 运算符与条件语句
重复的力量 - 循环
- 专栏导航
生活中有很多重复的事情,比如每天刷牙、每周工作。程序也是如此,循环让代码可以重复执行,大大提高效率!
什么是循环?
循环是一种控制结构,可以让一段代码重复执行多次,而不需要手动编写重复的代码。
生活中的循环例子
- 每天刷牙:重复相同的动作
- 播放列表:一首接一首地播放
- 数数:从1数到100,每次加1
编程中的循环
csharp
// 不使用循环(重复代码)
Console.WriteLine("第1次");
Console.WriteLine("第2次");
Console.WriteLine("第3次");
// ... 写100次?
// 使用循环(简洁高效)
for (int i = 1; i <= 100; i++)
{
Console.WriteLine($"第{i}次");
}
for 循环
for 循环是最常用的循环方式,适合已知循环次数的场景。
基本语法
csharp
for (初始化; 条件; 迭代)
{
// 循环体:重复执行的代码
}
执行流程
1. 执行初始化(只执行一次)
2. 检查条件
- 如果条件为 true,执行循环体,然后执行迭代
- 如果条件为 false,退出循环
3. 回到步骤2
示例
csharp
// 输出 1 到 5
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(i);
}
逐行解析:
csharp
for (int i = 1; i <= 5; i++)
// └─ 初始化 └── 条件 ──┘ └── 迭代 ──┘
// 第1次循环:i = 1, 1 <= 5 (true), 输出 1, i 变为 2
// 第2次循环:i = 2, 2 <= 5 (true), 输出 2, i 变为 3
// 第3次循环:i = 3, 3 <= 5 (true), 输出 3, i 变为 4
// 第4次循环:i = 4, 4 <= 5 (true), 输出 4, i 变为 5
// 第5次循环:i = 5, 5 <= 5 (true), 输出 5, i 变为 6
// 第6次检查:i = 6, 6 <= 5 (false), 退出循环
输出结果:
1
2
3
4
5
常见用法
csharp
// 倒序输出
for (int i = 10; i >= 1; i--)
{
Console.WriteLine(i);
}
// 输出:10, 9, 8, 7, 6, 5, 4, 3, 2, 1
// 步长为 2
for (int i = 0; i <= 10; i += 2)
{
Console.WriteLine(i);
}
// 输出:0, 2, 4, 6, 8, 10
// 计算累加和
int sum = 0;
for (int i = 1; i <= 100; i++)
{
sum += i; // sum = sum + i
}
Console.WriteLine($"1到100的和:{sum}");
// 输出:5050
循环变量的作用域
csharp
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
// Console.WriteLine(i); // 错误!i 在循环外部不可访问
int j;
for (j = 0; j < 5; j++)
{
Console.WriteLine(j);
}
Console.WriteLine(j); // 正确,j 在循环外部可访问
while 循环
while 循环在条件为 true 时持续执行,适合不确定循环次数的场景。
基本语法
csharp
while (条件)
{
// 循环体:重复执行的代码
}
示例
csharp
// 输出 1 到 5
int i = 1;
while (i <= 5)
{
Console.WriteLine(i);
i++; // 重要:更新循环变量,避免死循环
}
执行流程:
1. 检查条件:i = 1, 1 <= 5 (true)
2. 执行循环体:输出 1,i 变为 2
3. 检查条件:i = 2, 2 <= 5 (true)
4. 执行循环体:输出 2,i 变为 3
...
7. 检查条件:i = 6, 6 <= 5 (false)
8. 退出循环
for 循环 vs while 循环
csharp
// for 循环:适合已知循环次数
for (int i = 1; i <= 10; i++)
{
Console.WriteLine(i);
}
// while 循环:适合不确定循环次数
int i = 1;
while (i <= 10)
{
Console.WriteLine(i);
i++;
}
何时使用哪个?
- 使用
for:明确知道要循环多少次 - 使用
while:根据条件决定何时停止
foreach 循环
foreach 循环用于遍历集合或数组中的每个元素,是最简洁的遍历方式。
基本语法
csharp
foreach (元素类型 变量名 in 集合/数组)
{
// 循环体
}
示例(初步介绍)
csharp
// 遍历数组
string[] names = { "张三", "李四", "王五" };
foreach (string name in names)
{
Console.WriteLine(name);
}
输出:
张三
李四
王五
更详细的介绍将在后续集合章节
List 的 ForEach() 扩展方法
除了 foreach 循环,List<T> 还提供了 ForEach() 扩展方法,它是一种更简洁的遍历方式。
基本用法
csharp
using System.Collections.Generic;
List<string> names = new List<string> { "张三", "李四", "王五" };
// 使用 ForEach() 方法
names.ForEach(name =>
{
Console.WriteLine($"你好,{name}!");
});
// 单行语句可以省略大括号
names.ForEach(name => Console.WriteLine(name));
输出:
你好,张三!
你好,李四!
你好,王五!
foreach vs ForEach() 对比
csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 方式1:foreach 循环(更传统)
foreach (int num in numbers)
{
Console.WriteLine(num * 2);
}
// 方式2:ForEach() 方法(更简洁)
numbers.ForEach(num => Console.WriteLine(num * 2));
两种方式的对比:
| 特性 | foreach 循环 | ForEach() 方法 |
|---|---|---|
| 适用范围 | 任何可枚举的集合 | 仅 List |
| 语法风格 | 传统的循环语句 | 方法调用 + Lambda 表达式 |
| 代码简洁度 | 需要大括号和循环体 | 一行代码即可 |
| break/continue | 支持 | 不支持 |
| 修改集合 | 可以修改元素 | 可以修改元素 |
实际应用示例
csharp
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
List<int> scores = new List<int> { 65, 72, 88, 45, 93, 57 };
Console.WriteLine("原始成绩:");
scores.ForEach(score => Console.Write($"{score} "));
Console.WriteLine("\n");
// 给每个人加分(修改元素值)
scores.ForEach(score => Console.Write($"{score + 5} "));
Console.WriteLine("\n");
// 筛选及格成绩(结合条件判断)
Console.WriteLine("及格的成绩:");
scores.ForEach(score =>
{
if (score >= 60)
{
Console.WriteLine(score);
}
});
// 处理字符串列表
List<string> fruits = new List<string> { "apple", "banana", "cherry" };
Console.WriteLine("\n大写的水果名:");
fruits.ForEach(fruit => Console.WriteLine(fruit.ToUpper()));
}
}
输出:
原始成绩:
65 72 88 45 93 57
70 77 93 50 98 62
及格的成绩:
65
72
88
93
大写的水果名:
APPLE
BANANA
CHERRY
ForEach() 的限制
csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// ✅ 正确:遍历并修改元素
numbers.ForEach(n => Console.WriteLine(n * 2));
// ❌ 错误:不能在 ForEach 中添加或删除元素
numbers.ForEach(n =>
{
if (n == 3)
{
numbers.Remove(n); // 运行时会抛出异常!
}
});
// ✅ 如果需要修改集合结构,使用 foreach
List<int> toRemove = new List<int>();
foreach (int n in numbers)
{
if (n == 3)
{
toRemove.Add(n);
}
}
toRemove.ForEach(n => numbers.Remove(n));
重要提示:
ForEach()是List<T>特有的方法,不是所有集合都支持- 在
ForEach()中不能添加或删除元素,只能修改元素值 ForEach()不支持break和continue- 如果需要更复杂的遍历逻辑,优先使用传统的
foreach循环
死循环
当循环条件永远为 true 时,就会形成死循环,程序永远不会停止。
死循环示例
csharp
// 永远为 true
while (true)
{
Console.WriteLine("永远运行...");
}
// 条件永远不会满足
int i = 1;
while (i > 0)
{
Console.WriteLine(i);
i++; // i 会一直增加,永远大于 0
}
如何避免死循环
✅ 正确做法:
csharp
int i = 1;
while (i <= 10)
{
Console.WriteLine(i);
i++; // 更新循环变量,使条件最终为 false
}
❌ 错误做法:
csharp
int i = 1;
while (i <= 10)
{
Console.WriteLine(i);
// 忘记更新 i,形成死循环
}
break 语句
使用 break 可以立即退出循环。
csharp
for (int i = 1; i <= 10; i++)
{
if (i == 5)
{
break; // 当 i = 5 时,退出循环
}
Console.WriteLine(i);
}
// 输出:1, 2, 3, 4
continue 语句
使用 continue 跳过本次循环,直接进入下一次循环。
csharp
for (int i = 1; i <= 5; i++)
{
if (i == 3)
{
continue; // 跳过 i = 3
}
Console.WriteLine(i);
}
// 输出:1, 2, 4, 5
嵌套循环
一个循环内部可以包含另一个循环。
示例
csharp
// 打印 3x3 的数字矩阵
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
Console.Write($"{i}{j} ");
}
Console.WriteLine(); // 换行
}
输出:
11 12 13
21 22 23
31 32 33
执行过程
i = 1: j = 1, 2, 3
i = 2: j = 1, 2, 3
i = 3: j = 1, 2, 3
实践:打印九九乘法表
csharp
using System;
namespace Week4Practice
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("===== 九九乘法表 =====");
Console.WriteLine();
// 外层循环:行
for (int i = 1; i <= 9; i++)
{
// 内层循环:列
for (int j = 1; j <= i; j++)
{
// 输出乘法算式
Console.Write($"{j}×{i}={i * j}\t");
}
// 换行
Console.WriteLine();
}
}
}
}
输出结果:
===== 九九乘法表 =====
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
代码说明
- 外层循环
i控制行数(1-9) - 内层循环
j控制每行的列数(1到i) \t是制表符,用于对齐Console.Write()输出不换行Console.WriteLine()输出后换行
实践:猜数字游戏
csharp
using System;
namespace Week4Practice
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
int target = random.Next(1, 101); // 生成 1-100 的随机数
Console.WriteLine("===== 猜数字游戏 =====");
Console.WriteLine("我想了一个 1 到 100 之间的数字,你能猜到吗?");
Console.WriteLine();
int attempts = 0; // 猜测次数
int guess = 0;
while (guess != target)
{
attempts++;
Console.Write($"第{attempts}次猜测,请输入数字(1-100):");
string input = Console.ReadLine();
guess = int.Parse(input);
if (guess < target)
{
Console.WriteLine("太小了!再试试。");
}
else if (guess > target)
{
Console.WriteLine("太大了!再试试。");
}
else
{
Console.WriteLine($"🎉 恭喜你猜对了!答案就是 {target}!");
Console.WriteLine($"你一共猜了 {attempts} 次。");
}
}
}
}
}
运行示例:
===== 猜数字游戏 =====
我想了一个 1 到 100 之间的数字,你能猜到吗?
第1次猜测,请输入数字(1-100):50
太小了!再试试。
第2次猜测,请输入数字(1-100):75
太大了!再试试。
第3次猜测,请输入数字(1-100):62
太大了!再试试。
第4次猜测,请输入数字(1-100):56
太小了!再试试。
第5次猜测,请输入数字(1-100):59
太大了!再试试。
第6次猜测,请输入数字(1-100):58
🎉 恭喜你猜对了!答案就是 58!
你一共猜了 6 次。
代码说明
Random.Next(1, 101):生成 1 到 100 的随机数while (guess != target):只要没猜中就继续- 每次给出提示:"太小了"、"太大了"
- 猜中后输出恭喜信息
循环使用技巧
何时使用哪种循环
| 循环类型 | 适用场景 | 示例 |
|---|---|---|
for |
已知循环次数 | 输出 1 到 100 |
while |
不确定循环次数 | 猜数字游戏 |
foreach |
遍历集合/数组 | 输出数组元素 |
常见错误
- 忘记更新循环变量
csharp
int i = 1;
while (i <= 10)
{
Console.WriteLine(i);
// 忘记 i++,死循环!
}
- 循环条件错误
csharp
// 永远为 false
for (int i = 1; i < 1; i++)
{
Console.WriteLine(i); // 不会执行
}
- 混淆
=和==
csharp
// 错误:赋值
while (i = 1) // 错误语法
// 正确:比较
while (i == 1) // 正确
本章总结
- ✅ 掌握了 for 循环:适合已知循环次数
- ✅ 学会了 while 循环:适合不确定循环次数
- ✅ 初步了解了 foreach 循环:用于遍历集合
- ✅ 理解了 break 和 continue 的用法
- ✅ 学会了嵌套循环
- ✅ 实践了九九乘法表和猜数字游戏