第 4 课 · 约 14 分钟 · ← 第 3 课

循环:for、while、do-while、foreach

四种循环,一个心智模型:条件成立就重复执行一段代码。区别只在计数放在哪、以及你在遍历什么。

for:知道要跑几次

头部三个子句——起点、继续条件、步进:

for (int i = 1; i <= 5; i++)   // i 从 1 起;只要 i <= 5 就重复;每轮后 i++
{
    Console.Write(i * 2 + " ");
}
Console.WriteLine();

循环变量 i 生于 for、死于 for——循环结束后想用它就是 CS0103。

累加器模式

最有用的循环形状:变量声明在循环前,每一轮更新:

int sum = 0;                    // 累加器从 0 起步——永远
int count = 0;
for (int i = 1; i <= 5; i++)
{
    sum += i;                   // 把每个值折进来
    count++;
}
Console.WriteLine($"sum: {sum}, count: {count}");

while:不知道要跑几次

// 翻倍一个数直到超过 10——跑几轮?事先不知道
int n = 1;
while (n <= 10)
{
    Console.WriteLine(n);
    n = n * 2;          // 没有这行:无限循环(见下)
}

规则:循环体内必须有东西把条件推向假。本站的引擎有步数看门狗,失控循环会被拦下而不是冻死标签页——在 Visual Studio 里,无限循环就那么跑着。

do-while:后检查,至少跑一次

输入校验的经典——先问,再决定要不要再问:

string[] attempts = { "abc", "-5", "42" };
int pos = 0;
int value;

do
{
    int.TryParse(attempts[pos], out value);   // 试着解析下一个输入
    pos++;
} while (value <= 0);                        // 没拿到正数就再来一轮

Console.WriteLine("accepted: " + value);

普通 while 先检查——条件一开始就为假的话,循环体一次都不跑。do-while 保证至少跑一次。这正是数位数用 do-while 解决 n = 0 边界的原因。

foreach:遍历集合,完全不用数

int[] scores = { 72, 95, 88 };

foreach (int s in scores)        // "对每个元素,叫它 s"
{
    Console.WriteLine("score: " + s);
}

Console.Write("letters in Ada: ");
foreach (char c in "Ada")        // 字符串是 char 的序列
{
    Console.Write(c + " ");
}
Console.WriteLine();

break 和 continue:从内部驾驭

int[] scores = { 72, 95, 88 };

// break:整个循环当场退出(第一个命中)
for (int i = 0; i < scores.Length; i++)
{
    if (scores[i] > 90)
    {
        Console.WriteLine($"found {scores[i]} at index {i}");
        break;
    }
}

// continue:只跳过本轮剩下的部分
for (int i = 1; i <= 5; i++)
{
    if (i % 2 == 0) continue;   // 跳过偶数
    Console.Write(i + " ");
}

嵌套循环:乘法表的一角

for (int row = 1; row <= 3; row++)
{
    for (int col = 1; col <= 3; col++)
    {
        Console.Write(row * col + " ");
    }
    Console.WriteLine();       // 每行结束换行——注意它待的位置
}

外层每走一步,内层完整跑一遍:3 × 3 = 9 次打印。新手经典 bug 是把 WriteLine() 放进内层(每个数字一行)或放到两个循环外面(全挤一行)——跑一遍,挪一挪,直到形状讲得通。

哪个循环,什么时候?

循环什么时候用招牌动作
for知道次数(或范围)计数:for (int i = 0; i < n; i++)
while重复到条件变化;可能一次不跑哨兵:"直到输入合法"
do-while同样,但至少一次菜单 / 重试提示
foreach要元素本身,不要下标求和、打印集合

现在就练