前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >[c语言日寄] 刷题-检查点重复次数不定的解决方案:scanf的返回值 [牛客网BC49 判断两个数的大小关系]

[c语言日寄] 刷题-检查点重复次数不定的解决方案:scanf的返回值 [牛客网BC49 判断两个数的大小关系]

作者头像
siy2333
发布2025-02-05 12:46:17
发布2025-02-05 12:46:17
7500
代码可运行
举报
文章被收录于专栏:来自csdn的博客来自csdn的博客
运行总次数:0
代码可运行

事情是这样的,在今天的快乐刷题中,我遇见了一个题目:

试题内容

37f0d22c75b1494280774470d12f2cdb.png
37f0d22c75b1494280774470d12f2cdb.png

试题以及部分检查点

错误思路

第一次尝试

ummm,看上去很简单:int的范围是 -2^31 到 2^31 - 1,所以直接定义两个整形变量,然后用scanf函数进行值传递,最后使用多个并列if似就可以解决这个问题。

于是我满怀信心给出了第一版答案:

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
int main() {

    int a, b;
    scanf("%d%d", &a, &b);
    if (a > b) printf("%d>%d\n", a, b);
    if (a == b) printf("%d=%d\n", a, b);
    if (a < b) printf("%d<%d\n", a, b);

    return 0;
}

结果却出错了。

23bacce70dd1499ab6b3e3afbd38529c.png
23bacce70dd1499ab6b3e3afbd38529c.png

第一次错误

第二次尝试

观察了一下,原来是需要添加一个循环。

此时我还没有意识到事情的严重性,高高兴兴的添加了一个for()循环结构,然后在printf()中添加转义字符”\n“进行换行。

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
int main() {
    for (int i = 0; i < 3; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a > b) printf("%d>%d\n", a, b);
        if (a == b) printf("%d=%d\n", a, b);
        if (a < b) printf("%d<%d\n", a, b);
    }
    return 0;
}

很好,第二次提交。

结果却让我不寒而栗:

260e47e5c7bd4a76a19af68bdd6529a6.png
260e47e5c7bd4a76a19af68bdd6529a6.png

第二次错误

啊?不是?为什么会这样?

输入的次数不确定?

为什么scanf在没有接受到新的值的时候还会执行下一步?

啊?这是什么题?我没见过啊?

正确解法

要解决这个问题,我们需要一个模块判断scanf函数是否成功接受到数值。

那么,这就要依靠scanf本身的性质了。

突破口

通过复习scanf的性质,我发现了一个突破口:

scanf 函数的返回值是成功匹配并赋值的输入项的数量。

如果输入失败或者遇到文件结束(EOF),返回值将小于预期的输入项数量。

很好,这就是我们所需要的!

基于这个性质,我编写了一个while循环

代码语言:javascript
代码运行次数:0
复制
while(scanf("%d%d", &a, &b) == 2){}

这个循环首先会调用scanf函数,然后对scanf的返回值进行值判断,当scanf成功接收了2个参数时,判断的值就为真,循环执行。

正确代码

我将代码整理出来,再次上传,果然成功了。

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
int main() {
    int a = 0, b = 0;
    while(scanf("%d%d", &a, &b) == 2) {
        if (a > b) printf("%d>%d\n", a, b);
        if (a == b) printf("%d=%d\n", a, b);
        if (a < b) printf("%d<%d\n", a, b);
    }
    return 0;
}
de7b2c70a8614f54a726bb52c77ff383.png
de7b2c70a8614f54a726bb52c77ff383.png

进一步优化

那么,这段代码还有没有进一步优化的空间呢?

当然有,你会发现,三个if并列的结构会导致程序至少执行3次判断。

如果我们使用if-else if进行优化,那么程序执行判断的次数就变为1-3次。

代码语言:javascript
代码运行次数:0
复制
#include <stdio.h>
int main() {
    int a = 0, b = 0;
    while(scanf("%d%d", &a, &b) == 2) {
        if (a > b) printf("%d>%d\n", a, b);
        else if (a < b) printf("%d<%d\n", a, b);
        else if (a == b) printf("%d=%d\n", a, b);
    }
    return 0;
}
c988e7d0fbbe45eeb86752e3498b75f7.png
c988e7d0fbbe45eeb86752e3498b75f7.png

可以看到,运行时间和占用内存都有明显的优化。

总结

知识点

scanf 函数的返回值是成功匹配并赋值的输入项的数量。如果输入失败或者遇到文件结束(EOF),返回值将小于预期的输入项数量。如果遇到文件结束符(EOF)或者读取出错,返回值将是 EOF(通常是 -1)。

灵活应用

输入验证

检查用户输入是否符合预期的格式。如果返回值与预期的输入项数量不符,说明输入可能不正确或不完整。

错误处理

当scanf返回EOF或者一个负值时,可以进行特定的错误处理,比如提示用户重新输入或者结束程序。

动态输入处理

在处理动态数量的输入时,scanf的返回值可以用来确定实际读取了多少个输入项,从而进行相应的处理。

数据转换和存储

在将输入的数据存储到数组或其他数据结构之前,可以根据scanf的返回值来确定需要存储的数据项数量。有助于避免数组越界或者未初始化的内存访问。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 试题内容
  • 错误思路
    • 第一次尝试
    • 第二次尝试
  • 正确解法
    • 突破口
    • 正确代码
    • 进一步优化
  • 总结
    • 知识点
    • 灵活应用
      • 输入验证
      • 错误处理
      • 动态输入处理
      • 数据转换和存储
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档