我们在最初学习C++语言时就接触到"cout<<endl;"这样的语句。我们都知道endl表示换行的意思。我一直习惯这样使用,却并不是清楚其内部实现是怎么样的。
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
return 0;
}
首先,endl是一个操作符(Manipulators),但我们必须知道endl是一个什么类型的变量。endl是跟在”<<“运算符后面,故endl应该是一个参数。其实endl是一个函数名,它是一个"<<"运算符重载函数中的参数,参数类型为函数指针。下面我们看下内部函数实现。
1 ostream& ostream::operator << ( ostream& (*op) (ostream&)) 2 { 3 // call the function passed as parameter with this stream as the argument 4 return (*op) (*this); 5 }
1 std::ostream& std::endl (std::ostream& strm) 2 { 3 // write newline 4 strm.put('\n'); 5 // flush the output buffer 6 strm.flush(); 7 // return strm to allow chaining 8 return strm; 9 }
可以看出,运算符重载函数中的函数参数为一个函数指针,其指向一个输入输出均为ostream类引用的函数。而endl正是这样一个函数。所以我们在运行"cout<<endl;"语句时,endl是一个函数参数,类型为函数指针。然后会执行”return (*endl) (*this);“语句,即执行endl函数。endl函数输出一个换行符,并刷新输出缓冲区。
这样我们知道在标准库中endl是作为一个函数实现的,显然我们也可以直接调用这一函数。我们看下面的测试程序:
1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 cout<<endl; 7 endl(cout); 8 return 0; 9 }
其输出为两个空行。”cout<<endl"中,endl是一个类型为函数指针的函数参数,通过运算符重载函数间接调用了endl函数。而“endl(cout)”中,endl是函数名,直接调用了endl函数。
如果用在输出到显示器的场合,最好用endl。如要接受延迟显示,并且兼顾代码的执行效率的时候,可以考虑\n,这样不刷新缓冲区,性能会更快。