关于c++输入输出缓冲区,和IO加速流的一些理解

1DeomS2 / 2024-04-22 / 原文

首先,让我们来介绍一下这个函数

ios::sync_with_stdio();

这个函数在缺省状态下默认为true,即开启,这个函数的作用是同步c和c++的缓冲区

这个操作是c++为了兼容c而做出的保守决定,即将c和c++的缓冲区合并为一个,但是这样会带来性能上的开销

为什么呢?因为这个兼容缓冲区先执行c的输入输出操作再执行c++的输入输出操作

题主猜测是因为判断输入输出是来源于c/c++的操作造成了开销

当ios::sync_with_stdio(false); 接收false时,c与c++的缓冲区分离为两个独立的区

c的IO函数会将数据存入c的缓冲区

c++的IO函数会将数据存入c++的缓冲区

但是因为c和c++清空缓冲区的条件不一样,所以在分离缓冲区情况下混用c和c++的IO流会出现输出顺序不一样的情况(所以关闭兼容之后最好用纯c++,不要用任何c库函数中关于IO的函数,尤其注意getchar,应该换成cin.get())

在这里引用一篇博客作为例子

https://blog.csdn.net/xiunai78/article/details/2584621?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171370365216800225541332%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171370365216800225541332&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-2584621-null-null.142^v100^control&utm_term=cout%20printf%E6%B7%B7%E7%94%A8&spm=1018.2226.3001.4187

再就是cin.tie(0); cout.tie(0);这两个函数

首先我们要了解一下一个特性

就是cin和cout是绑定的

在cin读取数据时,cout会连带刷新输出缓存区

这样就带来了性能开销

cin.tie(0); cout.tie(0);这两个函数就是让cin与cout解绑

使得cin与cout的效率更近一步

再就是endl和'\n'这两个的区别

其实 endl='\n'+flush 也就是说endl在实现换行功能的同时刷新了缓冲区

频繁刷新缓冲区这个操作在ACM等算法竞赛中不仅没有必要而且还带来了不小的性能开支

所以再将endl换成'\n'可以使得cin cout的效率几乎与scanf printf无异而且在大数据输入输出时还可能反超

再就是cin输入时的一些理解

cin不能读入空白符,而且cin在缓冲区中读入数据时会自动忽略前导空白符,直至遇到合法数据

但是cin成功读入后,缓冲区剩余的空白符会保留,cin不做处理,

比如int a; cin>>a后

再getline时就会读入缓冲区中遗留的\n