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在不同情况下的返回值有所了解才能正确地找到本题的代码思路。当然我们不要忘了应当首先判断输入字符与给定的占位符是否匹配。
本章内容到此结束。谢谢大家!
标签:字符,题目,sum,days,while,整型,scanf,输入 From: https://blog.csdn.net/2301_80744520/article/details/136770240