C语言Scanf函数剖析以及数字求和算法

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/archi_Xiao/article/details/45601983

在C语言里,字符的输入都是通过调用函数来实现的:getchar( )、scanf( )
其中,getchar 函数只能处理单个字符的输入与输出,函数体本质上与scanf函数是一致的,都是阻塞式函数。
阻塞函数是指当这个函数不执行完,函数所在的线程就一直停止不动,直到获得函数结果。例如
int number;
scanf(“%d”,&number);//请用户输入一个数字

假设我们输入数字123,
执行的步骤是:
1.控制台一次输入:12334()
2.敲下回车,告诉计算机,输入结束(若不按回车需要用户不断输入)

此时,scanf()函数会做两件事情
一:
将我们输入的所有数据都存取到一个缓存中。从逻辑上来说,我们想传递的是一个3位数字:123,但是笨笨的计算机不这么认为,在缓存中它存取的是:1 、2、3、\n 四个字符,其中‘\n’代表我们最后敲下的回车即换行符

二:
因为我们是以%d的格式,希望计算机能以int 类型的格式存储到我们的变量number中,所以scanf()函数会依次从缓存中读取数据,首先是‘1’,是int类型的,符合我们的格式,然后继续读取‘2’,也是符合的…直到读取到最后的‘\n’,scanf()函数发现它不是我们想要的int类型,所以就扔在缓存里,并将前3个字符打包成我们想要的数据:123 ,最后scanf()函数结束

若缓存中是空的,scanf()函数读取不到任何数据,才会要求用户在控制台进行输入,比如在我们第一次输入的时候。下面我们通过案例,再加深下理解
输入三个字符

控制台输入:ab ----并按回车结束

我们会发现系统只让我们进行了一次输入操作,由于我们是以%c的格式,希望计算机从内存中读取一个字符赋给变量。因此scanf()函数会依次从缓存中读取数据。当把字符‘a’赋给了number1时,缓存中仍存在数据(不会要求用户再次输入),所以将字符‘b’赋值给number2,最后将回车符赋给number3,此时缓存中没有任何数据
这里写图片描述
从这里可以看到,最后一个数据是一个“换行符”

利用scanf()函数的这种特性,我们可以研究出一些新的算法,比如:
题目要求:要求用户输入一个3位数字,统计出这个数字的各个位数和

输入:123
输出:6

数学思路解法:
int number , temp , sum = 0;
scanf(“%d”,&number);
while(number!=0)
{
temp = number %10;
number /= 10;
sum += temp;
}
printf(“各个位数的和是%d”,sum);



利用scanf()函数特性:
char temp;
int sum = 0;
while(1){
temp = getchar(); -----//从缓存中读取一个字符出来
if(temp ==’\n’) ----- //循环结束的判断条件
break;
else
sum +=(temp-48);-----//将字符转化为数字,进行求和
}
printf(“各个位数之和是%d\n”,sum);

在后一种算法中,我们通过getchar()函数,来从缓存中读取数据,每次读取一个字符,由于读取的是字符,字符的ASCII码比我们的实际数字大48,所以每次需要减去48,若读取到了换行符,就跳出循环,打印出结果。

第二种算法的优势在于处理很大的数据时候,例如当我们碰到一个位数较多的数据时:12321321321321321311111111111111111312312321312321321312312321312312323…,如果采用第一种算法我们会发现该数据已经超过了int long类型的范围,如果使用double类型的数据,却又不支持整除并且存在误差,就会出现下面的错误情况:
这里写图片描述



好的idea来自思想的交流与碰撞

展开阅读全文

没有更多推荐了,返回首页