首先,getchar()是标准I/O标准库里的库函数,其原型是
int getchar(void)它没有参数,原因是因为它是从stdin标准输入流中读入一个字符的函数,已经有了默认的流参数stdin了。其返回值是一个整型数,是用来表示字符用的。
刚开始学习写程序总免不了从控制台开始练习,在控制台练久了,有些函数操作的内部机制都不了解,有时候出现问题都弄不明白错在哪里。这里我来简单介绍一些IO库中输入输出函数的实现机制。
提到IO,不得不提的就是流的概念。我们都知道,输入输出往往都是内存与外设之间的数据来往,但是,内存的运行效率比外设的运行效率那要大得多,比如,从内存写一个字符到磁盘上,内存很快地传出字符数据,供给磁盘存储,磁盘花了很多的时间来存储,在这段存储的时间里,我们宝贵的内存只能干等着磁盘做完存储操作来传递下一个字符,这样的做法是非常浪费内存的。所以计算机牛人们就设计出了缓冲的概念,来缓和内存与外设之间速度不匹配的问题。这意味着程序的输入输出已经不是跟外设直接打交道了,而是从一块被称为缓冲区的内存区域来回复制数据。就C程序而言,所有的IO操作只是简单地从程序移进移出字节,这种字节流即为流。
回到getchar()函数中来,我们以下面一个程序为例。
#include<stdio.h>
void main()
{
char ch1 = getchar(); //从输入流中读取一个字符
char ch2 = getchar();
printf("%c\n",ch1);
printf("%c\n",ch2);
}
结果会显示什么呢?如果是几年前的我肯定会回答说:“当然从ch1是第一次输入的字符,ch2是第二次输入的字符呗!”真的是这样子吗?如果你实践一下马上就会出现问题:为啥控制台界面只给我一次输入的机会呢?
第一种情况:如果你的输入只有一个字符,那么肯定的,ch1的值便是这个字符,那么ch2呢?在这里别忘了,你输完前一个字符后是通过什么结束输入的?是的,是Enter,Enter肯定会说:“人家可也是个正正经经的字符啊,不要不把无字幕的字符不当字符啊!”是的,在这里是向缓冲区中输入了两个字符,而getchar()是做什么呢?前面提到了,程序可不是直接跟外设打交道的,而是跟缓冲区打交道的,所以,getchar()库函数是从缓冲区中读取字符而不是从键盘读取字符的,所以,你已经向缓冲区中输入了两个字符够上面程序中两个getchar()读的了。可以用下面的程序测试一下这种效果。
#include<stdio.h>
void main()
{
char ch1 = getchar(); //从缓冲区中读取第一个字符
char ch2 = getchar(); //从缓冲区中读取第二个字符
getchar(); //从缓冲区中读取第三个字符
printf("%c\n",ch1);
printf("%c\n",ch2);
}在上面的程序中,有三次读入,所以如果你的输入是一个字符和一个换行,那么第三个getchar()在读stdin的缓冲区的时候发现缓冲区是空的,会提示输入设备输入数据,这里便可以再次输入了。
如果在第一次输入的时候不是简单的输入一个字符和一个换行,而是啪嗒啪嗒地输入了一大堆字符,那么,这些字符将全部送往stdin流的缓冲区中,后面的所有包括getchar()的将从stdin流中读入数据的库函数将从这个缓冲区中读入数据,知道缓冲区再次为空后,才提示输入设备准备输入数据。
顺便提一下输出库函数。输出库函数的效果也只是将程序中的内容输出到缓冲区中,然后再刷新的时候输出到外设上,如果在输出的时候输出输出流stdout缓冲区中已经有了数据,那么输出的是已经有的内容,而不一定是你输出的内容。这是由缓冲区刷新的时间控制的,刷新的操作是根据具体的编译器来决定的,一般调用fflush(stdout)来刷新一下stdout缓冲区。
289

被折叠的 条评论
为什么被折叠?



