Чем отличается endl от n
Перейти к содержимому

Чем отличается endl от n

  • автор:

The difference between \n and endl in C++

About two years ago when I took my first C++ class, I remember my professor used both \n and endl to create new lines. Having been previously acquainted with \n from Python, I wondered what difference the two had on the running of a program. One day after class, I asked him what the difference was and he told me that endl also flushes the buffer.

I wanted to find out more about this, so when I got home I checked with the all-knowing StackOverflow for more information on the two and found out that endl is a stream manipulator that forces a flush the buffer which can have a negative impact on the performance of a program. This is in contrast to \n which is a typical escape sequenceand only 1 byte (for '\n' ) or 2 bytes (for "\n" ) large. One interesting little nitpick is that using "\n" will cause the program to run just slightly slower than '\n' since "\n" is a string literal representing two characters, the '\n' newline character and the null terminator '\0' .

Therefore the wanton use of endl should be avoided in instances where performance is major issue.

Какая есть разница между /n и endl?

eush77

Если поток открыт в текстовом режиме, то ‘\n’ так же преобразуется в то, во что нужно (можете проверить сами).
Единственная разница — это отсутствие неявного вызова std::flush.

Кстати, это очень частый предмет непонимания среди начинающих разработчиков, они любят пихать везде и всюду std::endl, тогда как это может быть причиной потери производительности (сам сталкивался при написании одного алгоритма).

eush77

  • Facebook
  • Вконтакте
  • Twitter

Csklassami

eush77

@Csklassami std::flush очищает внутренний буфер стандартной библиотеки. То есть обычно при записи в поток данные не сразу передаются ОС, но накапливаются в буфере и отправляются разом.

Каждое опустошение буфера влечёт за собой системный вызов write(), а системные вызовы замедляют работу программы, поскольку процесс вынужден ожидать ядро ОС.

Размер буфера определяется реализацией, у меня BUFSIZ равен 8192, поэтому предположим, что размер буфера равен 8КБ.
Если программа выводит 64 строки длины ≤128 в поток, и в конце каждой ставит std::endl, то write() будет вызван 64 раза.
Если теперь все ендлы заменить на ‘\n’, то поскольку все строки помещаются в буфер (128⋅64=8192), write() будет вызван только один раз.
Это, должно быть, очень грубый пример, но смысл таков.

Различия между '\n' и std::endl

Я знаю, что endl делает перенос и очищает буфер ( flush ). Но почему-то не вижу разницы, что с endl , что с \n , результат один — отображается Hello, world!

Как переписать код так, чтобы увидеть разницу с endl и \n ?

αλεχολυτ's user avatar

Думаю, что проблема в буферизации вывода.

В C++ потоки ввода и вывода могут быть в одном из трёх состояний: небуферизирован (любой вывод сразу попадает в целевой файл/пайп/на консоль), буферизирован построчно (символы попадают в вывод после окончания каждой строки, исчерпания внутреннего буфера или закрытия потока), и полностью буферизован (символы попадают в вывод лишь после исчерпания внутреннего буфера или закрытия потока).

Майкрософтовская реализация стандартной библиотеки никогда не делает построчную буферизацию (почитайте ответ от Stephan T. Lavavej), имплементации на линуксе обычно делают.

В этом ответе содержится цитата из стандарта (C11 7.21.3 §7):

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

(это относится к чистому C). У C++ та же политика, согласно этому ответу:

C++11 27.4.2 [narrow.stream.objects]/3 : The object cout controls output to a stream buffer associated with the object stdout .

Это означает, что если вывод производится на консоль, а не в файл, то вы увидите всегда полную строчку после \n . А вот если вывод перенаправлен, то произойдёт буферизация.

Вот пример. Рассмотрим код:

в MSVC 2015. Если запустить программу обыкновенным образом, мы увидим сначала this is , и лишь через 10 секунд SPARTA . А если запустить программу так: a.exe >x.txt , и заглянуть через пару секунд после запуска в файл x.txt , то вы не увидите там ничего до окончания работы программы.

Если заменить «\n» на std::endl , вывод в файл работает так же, как и на консоль.

Обновление: в MSVC 2015 установить буферизацию std::cout можно вручную (идея с благодарностью украдена подсмотрена в этом ответе):

Чем отличается endl от n

endl and \n both seem to do the same thing but there is a subtle difference between them.

cout << endl inserts a new line and flushes the stream(output buffer), whereas cout << “\n” just inserts a new line.

Therefore, cout << endl; can be said equivalent to cout << ‘\n’ << flush;

Though in some use cases like competitive programming, it is better to use “\n” when the problem is not interactive, as it saves time by not flushing the entire line and thus improves the time complexity of the program.

Some other differences between endl and \n are:

Note: cout << “\n” looks performance wise better but in real cout << endl is much better in C++; As it doesn’t occupies any memory and also if flushing of stream is required.

Example 1:

We can use endl in C++ but not in C. So endl runs well in C++ but if we use C, it runs error.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *