许多c++书籍包含这样的示例代码…

std::cout << "Test line" << std::endl;

...所以我也一直这么做。但我看到过很多开发者写的这样的代码:

std::cout << "Test line\n";

是否有技术上的原因,更喜欢其中一个,或者只是编码风格的问题?


当前回答

可能存在性能问题,std::endl强制刷新输出流。

其他回答

我记得在标准中读到过这个,所以是这样的:

参见C11标准,它定义了标准流的行为,作为c++程序接口的CRT, C11标准应该管理这里的刷新策略。

ISO/IEC 9899:201x 7.21.3 §7 At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device. 7.21.3 §3 When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.

这意味着当且仅当std::cout和std::cin引用非交互设备时,它们将被完全缓冲。换句话说,如果stdout附加到终端,那么行为上没有区别。

然而,如果std::cout.sync_with_stdio(false)被调用,那么'\n'即使对交互设备也不会导致刷新。否则'\n'等同于std::endl,除非管道到std::endl上的files: c++ ref。

如果您同时使用Qt和endl,您可能会意外地使用不正确的endl,从而得到非常令人惊讶的结果。请看下面的代码片段:

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

注意,我写了endl而不是std::endl(这将是正确的),显然有一个endl函数定义在qtextstream.h(这是QtCore的一部分)。

使用“\n”而不是endl完全避免了任何潜在的名称空间问题。 这也是一个很好的例子,说明为什么把符号放到全局命名空间(就像Qt默认做的那样)是一个坏主意。

不同的行结束字符无关紧要,假设文件以文本模式打开,除非您要求二进制,否则您将得到文本模式。编译后的程序将为被编译的系统写出正确的东西。

唯一的区别是std::endl会刷新输出缓冲区,而'\n'不会。如果不希望频繁刷新缓冲区,请使用'\n'。如果你这样做(例如,如果你想获得所有的输出,而程序是不稳定的),使用std::endl。

这种差异可以用下面的例子来说明:

std::cout << std::endl;

等于

std::cout << '\n' << std::flush;

So,

使用std::endl如果您想强制立即刷新输出。 如果担心性能问题,请使用\n(如果使用<<操作符,则可能不是这样)。

我在大多数行上使用\n。 然后在段落末尾使用std::endl(但这只是一个习惯,通常不是必需的)。

与其他声明相反,\n字符仅当流去往文件(std::cin和std::cout是特殊的,但仍然是文件(或类文件)时才会映射到行序列的正确平台末端。

如果你要使用std::endl,这里隐含了另一个函数调用

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

A)呼叫操作员<<一次。 B)呼叫操作员<<两次。