记一个关于标准IO流缓冲区的有趣例子

16 篇文章 1 订阅

在编程时无意中发现一个有趣的现象,经过分析应该是标准IO流的缓冲区机制引起的。
有如下一段代码

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("#\n");
    write(1, "123", 3);
}

它的输出如下

#
123

这段程序调用了printfwrite两个函数,分别对应于带缓冲的流式IO没有缓冲的直接IO。两个函数先后向屏幕输出“#\n”“123”这两个字符串,这样的结果在我们的意料之中。

我们将上述代码中输出的字符串”#\n”改为”#” :

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("#");
    write(1, "123", 3);
}

这回的输出还和原来一样吗?非常有趣的是它的输出变成了下面这样:

123#

两个字符串实际的输出顺序竟与代码中的输出顺序相反,是什么原因造成的呢?
没错,就是缓冲区。
我们知道在一般的linux系统中,标准输出流是行缓冲的,在第一段代码中printf函数写入缓冲区的字符串“#\n”“\n”结束,代表写入的字符串已经到达一行的末尾,这时缓冲区中的内容会被立即写入标准输出,即显示在屏幕上。
而对于第二段代码printf函数向缓冲区写入字符串“#”,由于缓冲区中没有写入代表一行结束的字符‘\n’,所以缓冲区中的内容没有立即写入标准输出。之后调用write函数,由于它是直接IO,没有缓冲区,所以字符串“123”被直接写入标准输出,由于字符“\n”一直没有被写入标准输出流的缓冲区,所以直到程序结束要退出主函数时,缓冲区的内容才被写入标准输出。这就造成了我们看到的输出顺序相反的现象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值