第 08 课:循环结构(二)——读入 n 个数,逐个处理

本课定位:第 07 课的循环,是让循环变量 i 自己从 1 数到 n,i 本身就是要处理的数据。可是有一类题目长得不一样:“先给一个 n,接下来给 n 个数,请你对每个数做判断”。这时数不是我们数出来的,而是一个一个读进来的。本课就专门练这个高频模式:读 n 个数,对每个数做点事——求和、计数、比大小(求最值),再到综合应用。

前置条件:第 07 课全部内容——while / for、循环三要素、累加器 sum、计数器 cnt;第 04、05 课的分支与逻辑运算符。

0. 本节知识地图

第 07 课:循环变量自己就是数据

        i = 1 ─► 处理 1
        i = 2 ─► 处理 2
        i = 3 ─► 处理 3      (i 从 1 数到 n,处理的就是 i 自己)
        ...
        i = n ─► 处理 n

第 08 课:循环变量只是“第几个”,数据每次从键盘读进来

        i = 1 ─► 读入 x ─► 处理 x
        i = 2 ─► 读入 x ─► 处理 x
        i = 3 ─► 读入 x ─► 处理 x   (i 只管“数到第几次了”,x 才是数据)
        ...
        i = n ─► 读入 x ─► 处理 x

                  一句话骨架

        cin >> n;                                 // 先知道一共有几个
        for (int i = 1; i <= n; i++) {
            int x;
            cin >> x;                             // 每轮读一个新的进来
            // 对 x 做点什么:求和 / 判断 / 比大小……
        }

学完本课,学员要能一眼认出“先给 n、再给 n 个数”这类题目,并立刻把上面这个骨架写出来。

1 复习:循环的三要素

上节课反复强调,任何循环都离不开三要素:

要素 作用 例子
起点(初值) 循环变量从几开始 int i = 1;
条件 满足什么就继续循环 i <= n
步进(变化) 每轮结束后循环变量怎么变 i++

写成 for 就是这一行:

for (int i = 1; i <= n; i++) {
    // 处理 i
}

上节课里,“要处理的数”就是 i 自己:i 是 1 就处理 1,i 是 2 就处理 2。今天换一种玩法:i 不再是要处理的数,它只负责数“这是第几个”。真正要处理的数,每一轮从键盘读进来。

2 新问题:不知道有几个数,题目先告诉我们

看一道新题:

读入一个整数 n,再读入 n 个整数,求它们的和。

和上节课不一样的地方在于:要算的数不是一个一个自己数出来的,而是等着读进来的。而且 n 事先不知道是几——可能 n = 3,也可能 n = 10000。我们不可能写死 “cin >> x1 >> x2 >> x3”,因为不知道到底要读几个。

但换个角度想:题目已经告诉我们一共有 n 个数,那我们只要重复读 n 次、每读一个就处理一个就行了。这正是循环最擅长的。

3 核心模式:先读 n,再循环 n 次读 x

把上面的想法写出来,就是本课的万能骨架:

int n;
cin >> n;                       // 第一步:先知道一共有几个数

for (int i = 1; i <= n; i++) {  // 第二步:循环 n 次
    int x;
    cin >> x;                   // 每一轮读一个新的数进来
    // 第三步:对 x 做处理(求和 / 判断 / 比大小……)
}

它在计算机眼里是这样执行的: