Використовуєте маніпулятор потоку (endl) або символ втечі нового рядка (\ n)?


12

У мене немає конкретного контексту, в якому я задаю питання, але, читаючи книгу-початківця на C ++, я помітив використання як маніпулятора потоку endl, так і символу втечі нового рядка при роботі з об'єктом потоку.

Приклад такий:

cout << "Hello World" << endl;
cout << "Hello World\n";

Мої запитання:

  1. Чи доцільніше використовувати маніпулятор потоку (endl) у певній ситуації, а символ втечі в іншій?
  2. Чи є недоліки ефективності розумного використання одного з двох?
  3. Вони повністю взаємозамінні?
  4. Я читав, що послідовність евакуації зберігається в пам'яті як один символ. Чи означає це, що доцільніше використовувати endl, якщо ви збираєтесь із низьким рівнем споживання пам'яті?
  5. Чи потік маніпулятора endl використовує пам'ять будь-яким чином, якщо це більше, ніж послідовність відходу?

Дякую, StackExchange Вибачення, якщо я розмістив це в неправильному розділі, я вважав, що це враховується як структури даних.


2
endl також спричиняє вимивання в деяких потоках, '\ n' ні.
Джеймс

Відповіді:


12

o << std::endl еквівалентний наступному коду:

o.put(o.widen('\n'));
o.flush();

Іншими словами, ви повинні використовувати лише std::endlтоді, коли вам потрібно промити потік. Наприклад:

  • Ви збираєтеся виконати трудомістку операцію і хочете переконатися, що ви відображаєте повідомлення, перш ніж робити це.
  • Ще один процес очікує на ваш вихід.
  • Якщо працює декілька потоків або процесів, можливо, вам знадобиться промити вихід, щоб результат кожного потоку або процесу відображався правильно. (В іншому випадку у вас можуть з’явитися наче випадкові блоки виводу, переплетені через незручні інтервали.)

Якщо вам не потрібно промивати потік, використовуйте \nзамість цього std::endl. Додаткові дзвінки до flushможе погіршити продуктивність (іноді значно).

Детальніше див. На cppreference.com .

Що стосується використання пам’яті: турбуватися про \nпорівняно std::endlмайже напевно є непотрібною мікрооптимізацією, але в цілому я б розраховував \nзаймати менше пам’яті. \nє лише ще одним байтом в кінці рядкового літералу, тоді як запис std::endlперекладається компілятором у (ймовірно, вбудований) функцію викликів до putта flush.

Платформа-специфічні відмінності в закінченнях рядків (Windows \r\nпроти Linux і OS X \n) обробляються на більш низькому рівні , ніж std::endlта \n:

  • Якщо потік відкритий у текстовому режимі, тоді, якщо ви пишете \n, він автоматично переводить його у відповідний рядок, що залежить від платформи. Якщо ви читаєте, що закінчується певний рядок платформи, потік автоматично переводить його в \n.
  • Якщо потік відкритий у двійковому режимі, вони переносять будь-які закінчення рядків через дослівний перелік, і це залежить від вас.
  • Для std::coutі , std::cinзокрема, вони розглядаються , як якщо б вони в текстовому режимі.

1

1) Для портативності використовуйте endl. Нові рядки Windows - це \r\nLinux \nта Mac \r. Редагувати: Відповідно до коментарів, специфічні закінчення для рядків обробляються на нижчому рівні.

2) endlпромиває потік, "\n"не робить.

3) Залежить від портативності.

Щодо використання пам’яті, ви можете мінімізувати її, переносячи на інший сховище якомога частіше endl. Однак це знизить продуктивність.

Редагувати: очистити деякі помилки.


2
Mac заснований на Unix з OS X, і тому він також є \nна будь-якій сучасній машині.

7
Вибачте, але це неправильно. endlі \nє рівнозначними щодо конкретних платформних закінчень; різниці платформ обробляються на нижчому рівні.
Джош Келлі

2
Ваш перший пункт неправильний. endl () надсилає '\ n' в потік (на додаток до його промивання). Символ '\ n' перетворюється на конкретну платформу End of line sequence(припускаючи текстовий режим). End of line sequenceПеретвориться назад в «\ n` при читанні з файлу. Пункт 3) сумнівний. І останній абзац знову помиляється: промивання не заощадить вам місця, а промивання більше, ніж потрібно, сповільнить ваш код (суть буфера полягає в підвищенні ефективності запису на повільному пристрої).
Мартін Йорк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.