Home Articles

“C Primer 5ed”一书的这一部分是什么意思(描述部分)? [重复]

Asked
Viewed 1997 times
-2

这个问题在这里已有答案:

std::cout << "Enter two numbers:";
std::cout << std:endl;

这段代码片段后跟两段和一个警告说明,其中我理解了第一段,但第二段和注释都没有 . 案文如下 -

“第一个输出操作符向用户输出一条消息 . 该消息是一个字符串文字,是用双引号括起来的一系列字符 . 引号之间的文本打印到标准输出 . 第二个操作符打印endl写入endl具有结束当前行并刷新与该设备关联的缓冲区的效果 . 刷新缓冲区确保程序到目前为止生成的所有输出实际上都写入输出流而不是坐在内存中等待写入 . 警告程序员经常在调试期间添加print语句 . 这样的语句应该总是刷新流 . 否则,如果程序崩溃,输出可能会留在缓冲区中,导致不正确的推断程序崩溃了 . “

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

3 Answers

  • 2

    操作系统执行缓冲IO . 也就是说,当你的程序输出一些东西时,它们不一定要把它放在它应该去的地方(即磁盘或终端),它们可能决定在执行实际的IO操作之前将数据保留在内部存储器缓冲区中一段时间 . 装置 .

    他们这样做是为了优化性能,因为只要有几个字节要写,就可以立即执行块中的IO .

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

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

    第3个注释警告,如果程序崩溃,而错误消息仍在缓冲区中(尚未刷新),则可能无法看到调试错误(如果缓冲且未立即刷新) .

  • 0

    想象一下,你有一些崩溃的代码,你不知道在哪里 . 因此,您插入一些打印语句来缩小问题范围:

    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() . 实际上's because the output data may be waiting in a buffer and hasn' t已写入输出设备 .

    因此,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';
    
  • 0

    嗯,简单地说:

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

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

    std::cout << "\n";
    

    要么

    std::cout << std::endl;
    

    在我解释差异之前,你必须知道更简单的事情:当你用 std::cout 流发出打印命令时,事情不会立即打印出来 . 它们存储在缓冲区中,并且在某些时候,当缓冲区已满或者强制它进行刷新时,将刷新此缓冲区 .

    第一种, \n ,不会刷新,但第二种 std::endl ,将进入新线冲洗 .

Related