【问题标题】:What does this part from the book C++ Primer 5ed mean (portion in description)? [duplicate]C++ Primer 5ed 一书中的这一部分是什么意思(描述中的部分)? [复制]
【发布时间】:2017-02-04 12:15:34
【问题描述】:
std::cout << "Enter two numbers:";
std::cout << std:endl;

这段代码sn-p后面有两段和一个警告说明,其中第一段我看懂了,但第二段和注释都不明白。正文如下-

"第一个输出运算符向用户打印一条消息。该消息 是一个字符串文字,它是一个包含在 双引号。引号之间的文字是 打印到标准输出。

第二个操作符打印endl, 这是一个称为 ma​​nipulator 的特殊值。写endl有 结束当前行并刷新缓冲区的效果 与该设备相关联。冲洗缓冲区可确保所有 到目前为止程序生成的输出实际上被写入 输出流,而不是坐在内存中等待写入。

警告 程序员经常在调试过程中添加打印语句。这样的语句应该总是刷新流。否则,如果 程序崩溃,输出可能留在缓冲区中,导致 关于程序崩溃位置的错误推断。”

所以我不明白endl的部分,也不了解下面的警告。任何人都可以尽可能明确地向我解释这一点,并尽量保持简单。

【问题讨论】:

  • 你有什么问题?
  • 引用部分直接出自书,什么意思?
  • 什么意思?话很直白。哪些在上下文中没有意义?
  • @Bathsheba 没有“最好的工具”。有很多方法,根据情况各有利弊。
  • @xaxxon,如果这对我来说很简单,我就不会在这里问了。我想要的只是有人向我解释文本。我不知道这有什么模棱两可的。至于这里的答案,我发现他们每个人都非常有见地和相似。

标签: c++


【解决方案1】:

假设您有一些代码在某处崩溃,而您不知道在哪里。所以你插入一些打印语句来缩小问题范围:

std::cout << "Before everything\n";

f1();

std::cout << "f1 done, now running f2\n";

f2();

std::cout << "all done\n";

假设程序在评估f1()f2() 期间崩溃,您可能看不到任何输出,或者您可能会看到具有误导性的部分输出——例如你只能看到"Before everything",即使崩溃发生在f2()。这是因为输出数据可能正在缓冲区中等待,并且实际上并未写入输出设备。

因此,Primer 的建议是刷新每个输出,您可以使用 endl 方便地实现这一点:

std::cout << "Before everything" << std::endl;

f1();

std::cout << "f1 done, now running f2" << std::endl;

f2();

std::cout << "all done" << std::endl;

另一种方法是将调试输出写入std::cerr,默认情况下不会缓冲(尽管您以后可以随时更改任何 ostream 对象的缓冲)。

一个更现实的用例是当您想要循环打印进度条时。通常,换行符 (\n) 会导致打印基于行的输出,但是如果您想打印单个字符以进行进度,则可能在所有工作完成之前根本看不到它打印,除非您刷新:

 for (int i = 0; i != N; ++i)
 {
     if (i % 1000 == 0)
     {
         std::cout << '#';   // progress marger
         std::cout.flush();
     }

     do_work();
 }

 std::cout << '\n';

【讨论】:

  • 所以 endl 确保在移动到 endl 之后的语句之前打印所有内容,并且 /n 仅将光标移动到下一行,而 endl 所做的称为刷新。谢谢你的解释,我想我明白了。
【解决方案2】:

嗯,简单地说:

std::cout << "Hello world!";

将打印“Hello world!”并将保持在同一行。现在如果你想换行,你应该使用:

std::cout << "\n";

std::cout << std::endl;

在我解释区别之前,你必须知道一件更简单的事情:当你使用std::cout 流发出打印命令时,不会立即打印内容。它们存储在一个缓冲区中,并且在某个时候该缓冲区被刷新,无论是在缓冲区已满时,还是在您强制它刷新时。

第一种\n不会刷新,但第二种std::endl会换行+刷新。

【讨论】:

    【解决方案3】:

    操作系统会缓冲 IO。也就是说,当您的程序输出某些内容时,他们不一定立即将它放在应该去的地方(即磁盘或终端),他们可能会决定将数据保存在内部内存缓冲区中一段时间在设备上执行实际 IO 操作之前。

    他们这样做是为了优化性能,因为在 chunks 中执行 IO 比在有几个字节要写入时立即执行要好。

    刷新缓冲区意味着要求操作系统立即执行 IO 操作而无需任何等待。当程序员知道等待更多数据没有意义时,他会这样做。

    第二个注释说endl 不仅打印一个换行符,还提示cout 刷新它的缓冲区。

    第 3 条注释警告说,如果程序崩溃而错误消息仍在缓冲区中(尚未已刷新),则调试错误如果已缓冲且未立即刷新,则可能不会看到。 p>

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 2020-03-24
      • 2011-04-21
      • 2014-05-22
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 2011-09-25
      相关资源
      最近更新 更多