跳转至

while 循环的应用01-输入与最值

不定次输入

输入若干个整数,求它们的和,但没有给出个数。

可以一直读,直到读不到下一个整数,再停下来。

输入:1 7 3 4 5
输出:20
int x;
long long sum = 0;
while (cin >> x) {
    sum += x;
}
cout << sum;

cin >> x 返回输入流,放在条件里,会根据流的状态判断读取是否成功。

使用 scanf,也可以这样写

// 使用scanf、printf,需要头文件<cstdio>
int x;
long long sum = 0;
while (scanf("%d", &x) == 1) {
    sum += x;
}
printf("%lld", sum);

scanf 返回成功读入并赋值的项数。这里每次读一个整数,成功就返回 1。

按回车,不代表输入结束。

整数输入会跳过空格、换行,继续等待下一个数。看起来没有反应,其实是在等你输入。

终端里,要发送“输入结束”信号,不是输入字母 EOF。

  • Windows:通常在新行按 Ctrl + Z,再回车。
  • macOS、Linux:通常在空行按 Ctrl + D。

不同 IDE 的运行窗口,操作可能不同。

image-2025101111305781

从文件读入,freopen

不定次输入,在本地调试时,可以搭配 freopen,从文件读,读到文件末尾就结束。

#include <iostream>
#include <cstdio>

using namespace std;

int main() {
    freopen("1.in", "r", stdin);

    int x;
    long long sum = 0;
    while (cin >> x) {
        sum += x;
    }
    cout << sum;

    return 0;
}

把测试数据写进 1.in。程序运行时,从文件里读,不再等键盘输入。

1.in 按程序的当前工作目录查找,不一定是源代码所在目录。找不到文件时,先检查这个位置。

创建、编辑输入文件

  1. 新建一个文本文档,命名为 1.in。
  2. 注意检查完整文件名,别变成 1.in.txt。
  3. 拖进 Dev-C++,编辑并保存测试数据。

image-2026051114022577

freopen 的三个参数

freopen("文件名", "模式", 标准流);
freopen("1.in", "r", stdin);   // 从1.in读入
freopen("1.out", "w", stdout); // 向1.out输出

w 会覆盖输出文件原来的内容。

提交前,看清输入输出要求。

要求标准输入输出,就去掉本地调试用的 freopen;要求文件输入输出,文件名必须与题目一致。

打擂台,求最大值和最小值

什么时候用?

看到“最高分”“最低温度”“最大值”“最小值”,可以想到打擂台。

像比赛一样,一个一个比较

有 4 个数:6 3 9 7。先请第一个数 6 当“擂主”。后面的数依次挑战,谁大谁留下。

这次读到的数 发生了什么 目前最大值
6 第一个数,先当擂主 6
3 比擂主小,不换 6
9 比擂主大,换擂主 9
7 比擂主小,不换 9

maxn 记住“到目前为止最大的数”。要找最小值,就把比较方向反过来。

同时找最大值和最小值

先输入个数 n,再输入 n 个整数,输出最大值和最小值。

这里保证 n >= 1,每个数在 -10^9 到 10^9 之间。

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    long long x;
    cin >> x; // 第一个数已经读过了
    long long maxn = x, minn = x;

    for (int i = 2; i <= n; i++) {
        cin >> x;
        if (x > maxn) {
            maxn = x;
        }
        if (x < minn) {
            minn = x;
        }
    }
    cout << maxn << ' ' << minn;
    return 0;
}

输入:

4
6 3 9 7

输出:

9 3

为什么不用 0 当第一个擂主?

如果所有数都是 -8 -3 -10,把最大值初始化成 0,就会错误地输出没出现过的 0。

让第一个输入的数当擂主,不用猜数据有多大或多小。但是必须保证至少有一个数;n = 0 时没有最大值或最小值,需要按题意另行处理。

不用把所有数字都存起来,只要记住当前的最大值和最小值。

如果还要知道“第几个”?

在循环前设 int pos = 1;,更新最大值时,同时更新位置。

if (x > maxn) {
    maxn = x;
    pos = i;
}

用 >,并列最大值保留最早的位置;用 >=,保留最后的位置。题目要求哪个,就选哪个。