前言:
这篇博客的来源呢,源于一个同学在学习群里发出一段代码,他对代码有疑惑,疑惑的是,为什么只有输出三行,而不是四行?实际上误打误撞的巧合。我在看完那段代码和他的问题之后,和他一起探讨和发挥猜想,更进一步的了解了scanf的使用。
1.了解scanf()、getchar()和putchar
这段代码相信大家都能懂,如果能让你有点不懂的那就是忘记了getchar()和putchar的一些使用方法 。嗯我们循序渐进,跟着我一起思考!
2.scanf输入的奇怪现象
其实,我想说的是这个b里的10并不是随机来的,我们还敲了个回车,这时你就问,敲回车不只是为了让scanf确认读取吗?还能有其它作用?
补充:换行符('\n')的ASCII码值为10,回车('\r')的ASCII码值为13,我们日常说的回车和ASCII码值是不一样,口头说的回车是换行的意思。
我这补充一说,大家伙可能就知道b里的10怎么来的了吧,没错,就是回车被getchar()读走了。
输入缓冲区:当我们用在输入的时候,是有这样一块区域存在的,它用来存放你输入的信息,scanf()和getchar()看到这块区域没有内容,就会停下来等你输入。
3.scanf格式对回车的处理
我们看这段,当我们输入5然后回车,第二个scanf并没有让我们等待,而是直接跳过,来到getchar()这等待,因为缓冲区里有回车,并且是scanf("%c", &b);想要的内容,它就直接读取了,而且不需要你回车,这点可以用后面的getchar()等待来证明。
那这两个连续的输入是怎么实现的呢?当我输入一个5和回车的时候,到第二个scanf("%d", &b);不应该是直接就跳过了吗,因为我缓冲区里有回车在呀,那为什么还要我们输入?
答案是:缓冲区里面确实是有回车,但是我们要的是"%d",回车不是scanf要的类型,它丢弃掉这个回车后就没有内容了,所以就停下来等我们继续输入。看下面的代码:
这里是来解释为什么是丢弃的原因,对比看。上面是scanf后,getchar读得到,下面是最后一个getchar要等待,如果我们没有丢弃的话,第二次输入应该是:回车 + 6 + 回车(确认读取),读掉6后还剩两个回车,那我没下面两个getchar没有任何一个需要等待。
总结一下:scanf输入确实是需要看格式限制的,格式不对,它就不读取,如果还是个回车,那它还会丢弃掉它,如果格式是对的,比如是字符格式,缓冲区里有回车,那它既把回车看成是要读取的内容还看成是结束的标志。
我们反回去剖析一下,首先输入5回车,等待输入,其实(等待输入前还有一步就是丢弃上次遗留下来的回车),6回车,读取6,此时缓冲区里还有个回车在。
最后一个10是自己蹦出来的
4.小谈一下:
到这里你以为就完了吗,不不不,还有的,否则怎么能令博主奔溃呢,博主崩溃的原因是因为在边写的过程中,觉得scanf有好多种情况,边写边觉得有好多种都可以解释。。。ok,继续。
5.格式对scanf的重要性
这就是同学在群里发的代码,因为输入的情况读者可能不清楚,我来说一下,在输入5后回车,跳到下一行我再输入一个6后回车,来到下一行有整数B:,然后我输入了7后回车,最后就出结果啦。
大家有疑惑没?如果你把格式里的"%d\n"里的\n看成printf("\n"),那就是你输入5回车,然后换行,再输入6,再换行,也就是4行。我敲出来哈!
就是他的想法是这样的,但scanf格式里的"%d\n"可不是打印函数里的"\n"噢,可不敢这么想!
这里面也有学问在!那就是,你有没有看到结果是0.833333,很明显是5.0/6的结果,如果我们看向的是整数A:5和整数B:7这两个数字,5.0/7的结果可是0.714286噢。为什么,听我慢慢道来。
我们最先输入了5和回车('\n'),scanf在缓冲区里只看到5,而回车是我们用来确认的,所以scanf没找到自己格式要的内容,所以要我们继续要输入,但我们回车了,窗口就到下一行了,接着我们在第二行输入6和回车,这下就不一样了,缓冲区里的内容是5'\n'6和一个确认的回车,scanf看到5'\n',那好scanf说:我就读走了,但是存到a里的是5'\n'吗,不是,就是5,%d,其它的只是格式。
到第二个scanf了,这个时候缓冲区里有6'\n',当我们输入7回车,它就读走了6'\n',也就是把6放进了c。所以结果就是5.0/6啦。
读完后,希望读者对scanf有更多一点的理解!
好啦,这就是本节的内容,同以前一样,文章排版,内容分布,或有错误的,都可以在评论中告诉博主,博主也好改正。
求点赞,求点赞,求点赞!