【问题标题】:Using '\n' instead of endl affects output, why?使用 '\n' 而不是 endl 会影响输出,为什么?
【发布时间】:2014-05-16 15:43:38
【问题描述】:

所以我在 C++ 中创建了一个未初始化的数组并尝试打印最后一个元素以查看输出是什么。未初始化数组中的每个元素的值都应该是 0(对吗?),但我得到的输出是别的东西。这是 main 函数的样子:

int main() {
    int i[5];
    cout << i[4] << '\n';
}

运行此输出1606416656(每次相同的数字)并带有换行符。但是,将'\n' 更改为endl 会将输出更改为0,并带有换行符。

这是为什么呢?

此外,即使使用'\n',尝试打印i[3] 而不是i[4] 也会正确输出0。为什么?

我做了一些研究并在某处读到 '\n' 不会“刷新缓冲区”,而 endl 会。这个“刷新流”实际上是什么意思,这是影响输出的原因吗?

【问题讨论】:

标签: c++ newline line-breaks flush endl


【解决方案1】:

未初始化数组中的每个元素的值都应为 0(对吗?)

不,它们具有不确定的值。使用这些值会产生未定义的行为,这就是为什么会得到不可预测的输出。

“刷新流”实际上是什么意思,这是否会影响输出?

当您写入流时,输出存储在内存缓冲区中,不一定会立即发送到最终目的地(控制台、文件或其他任何东西);这可以带来很大的性能优势,但也可能意味着您在需要时看不到最终输出。刷新流会将您写入的数据推送到最终目的地。

【讨论】:

  • “到最终目的地”:不完全是。它将数据推送到操作系统;大多数操作系统也有内部缓冲:操作系统将(或应该)让它看起来像是数据被推送到同一台机器上的其他程序的最终目的地,但如果系统崩溃,你仍然不能保证信息已经到达在最终目的地。
【解决方案2】:

您认为堆栈上新创建的数组初始化为零的假设不成立。因此,您的输出是随机的。更改程序会重新排序内存布局,因此您会看到不同的结果。

int main() {
    int i[5];
    for (int k = 0; k < 5; ++k)
        i[k] = 0;
    cout << i[4] << '\n';
}

无论使用 '\n' 还是 endl,都应该给你预期的结果

【讨论】:

    【解决方案3】:

    您的数组仍未初始化。你得到的任何价值都是巧合。 std::endl 放入换行符并刷新输出流缓冲区。这就是 std::endl 操纵器和只打印换行符的区别。

    【讨论】:

    • 感谢您的回答(尽管它并没有完全解释我的主要问题)。我现在意识到未初始化数组中的元素是巧合的,不一定只是 0。
    • @zenith 好吧,刷新缓冲区是 std::endl 完成的附加任务。这意味着,无论您推动打印到 std::cout 的任何内容,都将保持缓冲直到满。冲洗使实际打印发生。
    • 你是对的,但在我的程序中,刷新并不是将输出从 1606416656 更改为 0 的原因。
    • @zecith 是的,但由于内容未初始化,内容无法预测,因此内容可能会有所不同。
    猜你喜欢
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 2022-11-06
    • 2018-12-23
    • 1970-01-01
    • 2015-11-26
    相关资源
    最近更新 更多