重复的力量 - 循环

专栏导航

← 上一篇:数学运算与逻辑判断 - 运算符与条件语句

← 第一篇:编程世界初探
专栏目录

重复的力量 - 循环

生活中有很多重复的事情,比如每天刷牙、每周工作。程序也是如此,循环让代码可以重复执行,大大提高效率!

什么是循环?

循环是一种控制结构,可以让一段代码重复执行多次,而不需要手动编写重复的代码。

生活中的循环例子

  • 每天刷牙:重复相同的动作
  • 播放列表:一首接一首地播放
  • 数数:从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() 不支持 breakcontinue
  • 如果需要更复杂的遍历逻辑,优先使用传统的 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 遍历集合/数组 输出数组元素

常见错误

  1. 忘记更新循环变量
csharp 复制代码
int i = 1;
while (i <= 10)
{
    Console.WriteLine(i);
    // 忘记 i++,死循环!
}
  1. 循环条件错误
csharp 复制代码
// 永远为 false
for (int i = 1; i < 1; i++)
{
    Console.WriteLine(i);  // 不会执行
}
  1. 混淆 ===
csharp 复制代码
// 错误:赋值
while (i = 1)  // 错误语法

// 正确:比较
while (i == 1)  // 正确

本章总结

  • ✅ 掌握了 for 循环:适合已知循环次数
  • ✅ 学会了 while 循环:适合不确定循环次数
  • ✅ 初步了解了 foreach 循环:用于遍历集合
  • ✅ 理解了 break 和 continue 的用法
  • ✅ 学会了嵌套循环
  • ✅ 实践了九九乘法表和猜数字游戏
相关推荐
Liust3 小时前
扩展方法+泛型+委托+Lambda 联合使用
.net
一叶星殇8 小时前
C# .NET 如何解决跨域(CORS)
开发语言·前端·c#·.net
weixin_4219947810 小时前
数学运算与逻辑判断 - 运算符与条件语句
.net·.netcore
许泽宇的技术分享10 小时前
当 AI Agent 遇上 .NET:一场关于智能体架构的技术探险
人工智能·架构·.net
一个帅气昵称啊13 小时前
基于 .NET 的 AI 流式输出实现AgentFramework+SignalR
人工智能·.net
呆萌哈士奇1 天前
告别 throw exception!为什么 Result<T> 才是业务逻辑的正确选择
c#·.net
喵叔哟3 天前
66.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--自动记账
微服务·架构·.net
故事不长丨3 天前
C#log4net详解:从入门到精通,配置、实战与框架对比
c#·.net·wpf·log4net·日志·winform·日志系统
bjzhang754 天前
OneAuthCenter——一款基于 .NET打造的企业级 OAuth 2.0 / OpenID Connect 认证中心
.net·认证中心