循环控制:(第4题)有关区分字符型与整型的题目

1.题目再现:

2.题目分析:

这道题主要解决的问题非常明显。1.区分输入的是字符还是整型数据 2.区分是正数还是负数 3.利用循环求出桃子数。

(1)针对问题一

这里先补充一下scanf的三种返回值:

1.输入成功:返回输入成功的变量个数

2.输入失败:类型不匹配,就会返回0 

3.缓冲区中没有数据:返回EOF

我们知道scanf("%d",&days)只能读取整型数据。当我们输入字符时会因为不匹配而无法输入。这时scanf的返回值就是0。我们也正是通过这一点,区分输入的是字符还是整型数据。

所以在程序刚进入循环时,我们就可以判断scanf的返回值是否等于0。当判断等于0时,我们就用while语句清空输入缓冲区中剩余的字符,直到遇到换行符('\n')为止。同时为days重新赋值。

(2)针对问题二

用if语句判断输入的数是否大于0,如果小于0,用continue语句跳过本次循环。

(3)针对问题三

由题目得,第n天的桃子数为一。所以我们对sum初始化为1,进入循环后令sum=(sum+1)*2.

days=days-1当days<1时跳出循环,打印sum。

3.代码展示

#include <stdio.h>
int main()
{
    int days = 0;
    while (1)
    {
        printf("Input days:\n");
        int check = scanf("%d", &days);

        //如果输入失败,则重新输入
        while (check ==0) {
            while (getchar() != '\n');
            printf("Input days:\n");
            check = scanf("%d", &days);
        }

        if (days > 0)
        {

            int sum = 1;
            while (days > 1)
            {
                sum = (sum + 1) * 2;
                days--;
            }
            printf("x=%d\n", sum);
            break;
        }
        else if (days <= 0)
            continue;
    }
    return 0;
}

4.典型错误分析

在2.1中我提到要优先判断输入数据的类型。如果没有这样做就会出现以下这种情况。

#include <stdio.h>
int main()
{
    int days = 0;

    while (1)
    {
        printf("Input days:\n");
        scanf("%d", &days);
        if (days > 0)
        {

            int sum = 1;
            while (days > 1)
            {
                sum = (sum + 1) * 2;
                days--;
            }
            printf("x=%d\n", sum);
        }
        else if (days <= 0)
            continue;
        else if (scanf("%d", &days) != 1)
        {
            while (getchar() != '\n');
            continue;
        }
    }
    return 0;
}

当我们输入正数或者负数时,代码都能正常运行。可是一但输入字符,就会死循环。

   

大家可能会疑惑,我们不是有while(getchar()!='\n')这段代码来清空缓冲区的字符,为什么代码不能重新进入while循环,让我们再次输入呢。

其实这是因为当scanf没有正确读取时就会把days赋值为0。当days等于0,代码就运行else if语句。又通过continue跳过while(getchar()!='\n')这段代码,导致缓冲区一直没被清理。再次循环时缓冲区里依然是字符,scanf依然读取失败进而再次循环,重复打印Input days。正如调试结果:

5.总结复盘

本题看似简单,实际上考察了循环、getchar清空缓冲区字符、scanf返回值等多方面的知识。学生只有对scanf在不同情况下的返回值有所了解才能正确地找到本题的代码思路。当然我们不要忘了应当首先判断输入字符与给定的占位符是否匹配。

本章内容到此结束。谢谢大家!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值