C语言复习——缓冲区

缓冲区(Buffer)又称为缓存(Cache)
缓冲区是内存空间的一部分。也就是说,计算机在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区(缓存)。
缓冲区的优点:加快了程序的运行速度,减少了硬件的读写次数,让整个计算机变得流畅起来。
全缓冲
当缓冲区被填满时才刷新缓冲区。(通常出现在文件输入中)
行缓冲
在出现换行符是时刷新缓冲区。(键盘输入通常是行缓冲,在按下Enter键后才刷新缓冲区)
无缓冲
某些环境下,我们希望程序能够立即响应用户按键(玩游戏,输入处理越快越好)

如何控制输入与输出缓冲区

  • 为什么使用scanf()函数时经常会发生一些莫名其妙的错误?原来这与缓冲区有关。
    当遇到 scanf() 函数时,程序会先检查输入缓冲区中是否有数据:
    1.如果没有,就等待用户输入。用户从键盘输入的每个字符都会暂时保存到缓冲区,直到按下回车键,产生换行符\n,输入结束,scanf() 再从缓冲区中读取数据,赋值给变量。
    2.如果有数据,那就看是否符合控制字符串的规则:
    1>如果能够匹配整个控制字符串,那最好了,直接从缓冲区中读取就可以了,就不用等待用户输入了。
    2>如果缓冲区中剩余的所有数据只能匹配前半部分控制字符串,那就等待用户输入剩下的数据。
    如果不符合,scanf() 还会尝试忽略一些空白符,例如空格、制表符、换行符等:
    a.如果这种尝试成功(可以忽略一些空白符),那么再重复以上的匹配过程。
    b.如果这种尝试失败(不能忽略空白符),那么只有一种结果,就是读取失败。

  • 输入缓冲
    scanf(),不管用户输入多少内容,只要不按下回车键,就不进行真正的读取。这是因为 scanf() 是带有行缓冲的,用户输入的内容会先放入缓冲区,直到用户按下回车键,产生换行符\n,才会刷新缓冲区,进行真正的读取。
    getche()、getch() 就不带缓冲区,输入一个字符后立即就执行了,根本不用按下回车键。

  • 清空输入缓冲区

  1. 使用 getchar() 清空缓冲区
    while((c = getchar()) != '\n' && c != EOF);
    getchar() 是带有缓冲区的,并且一切字符通吃,或者说一切字符都会读取,不会忽略。不过这种方案有个缺点,就是要额外定义一个变量 c,对于有强迫症的读者来说可能有点难受。
  2. 使用 scanf() 清空缓冲区
    scanf("%*[^\n]"); scanf("%*c");scanf("%*[^\n]");
    第一个 scanf() 将逐个读取缓冲区中\n之前的其它字符,% 后面的 * 表示将读取的这些字符丢弃,遇到\n字符时便停止读取。此时,缓冲区中尚有一个\n遗留,第二个 scanf() 再将这个\n读取并丢弃,这里的星号和第一个 scanf() 的星号作用相同。由于所有从键盘的输入都是以回车结束的,而回车会产生一个\n字符,所以将\n连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区。
    看不懂scanf用法的人可以看我上一篇博客《C语言复习——输入输出》
  • 输出缓冲
    \n会使得缓冲区刷新,将缓冲区中的所有内容都输出到显示器上。

  • 清空输出缓冲区
    fflush() 是一个专门用来清空缓冲区的函数。但是通用性非常差,不建议使用。

  • 缓冲区刷新的原则
    a.不管是行缓冲还是全缓冲,缓冲区满时会自动刷新;
    b.行缓冲遇到换行符\n时会刷新;
    c.关闭文件时会刷新缓冲区;
    程序关闭时一般也会刷新缓冲区。

  • 消除缓冲区的负面影响
    对于输出操作,清空缓冲区会使得缓冲区中的所有数据立即显示到屏幕上。很明显,这些数据没有地方存放了,只能输出了。
    对于输入操作,清空缓冲区就是丢弃残留字符,让程序直接等待用户输入,避免引发奇怪的行为。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值