众所周知,endl和’\n’都有换行的作用,但两者是有区别的。
每一个输出流都有一个缓冲区,用来保护程序读写的数据。执行下面的代码:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
};
"Hello World!"会被立即打印出来,这里的输出流对象是cout,但如果不用endl:
#include <iostream>
int main() {
std::cout << "Hello world!\n";
return 0;
};
文本可能在执行完这条语句后立即打印出来,但也可能被保存在缓冲区中。操作系统可能会将多个输出操作组合成一次写操作。可以理解为每输出一次操作系统都要进行一次写操作,不如先放在缓冲区,到时写一次搞定,提高性能。
cout << '\n’的作用就只是单纯地输出换行符,而endl的作用是输出一个换行符,并刷新缓冲区,输出的内容会立刻打印。
导致缓冲区刷新的原因有:
程序正常结束,比如在main函数return后,系统隐式调用**exit(0)**退出程序
#include <iostream>
int main() {
std::cout << "hello world";
return 0; //此时缓冲区没满,但程序结束导致其刷新
};
缓冲区满时
#include <iostream>
int main() {
std::cout << "hello";
std::cout << "hello";
std::cout << "hello";
std::cout << "hello";
std::cout << "hello"; //假如缓冲区可能在这里刚好就满了,刷新,并打印前五个hello
std::cout << "hello";
std::cout << "hello";
return 0; //程序结束,缓冲区刷新,并打印后两个hello
};
unitbuf设置流的内部状态后每次的输出操作
#include <iostream>
int main() {
std::cout << std::unitbuf;
std::cout << "hello"; //刷新,并立即打印
std::cout << "hello"; //刷新,并立即打印
std::cout << "hello"; //刷新,并立即打印
return 0; //刷新
};
被关联的流刷新,默认cin和cerr都关联到cout
#include <iostream>
int main() {
int n;
std::cout << "hello"; //假如缓冲区在这里没满,不刷新
std::cin >> n; //cin是默认关联cout的,执行cin操作会刷新cout缓冲区,故hello立即被打印在屏幕上
return 0;
};
举个例子,你可能就懂了。
假如正常情况下,缓冲区满了才会打印内容到屏幕上:
#include <iostream>
int main() {
int n = 0;
std::cout << "hello"; //假如缓冲区从这里开始是空的,把"hello"放进去也没满
n = 1;
std::cout << "world"; //假如再把"world"放进去刚好满了,缓冲区在这里刷新
n = 2;
return 0;
};
程序会在执行完 std::cout << "world" 操作之后才把 helloworld 一起打印出来。所以 hello 是在 n = 1 之后打印到屏幕上的。
求点赞、收藏!!!
作者水平有限,如果有误,欢迎指正!
编译环境:Visual Studio 2019