"n " или 'n' или std::endl к std::cout? [дубликат]



этот вопрос уже есть ответ здесь:




  • C++: "std:: endl" vs " n"

    11 ответов



прошло много лет с тех пор, как я перестал использовать std::endl для завершения строк при записи в std::cout, и начал использовать .



но теперь я начинаю видеть больше фрагментов кода, используя 'n' вместо этого, и я начал интересно, что может быть лучше.



помимо очевидного, что один является строкой, а другой-символом, есть ли какое-либо преимущество в использовании этого:



std::cout << variable << 'n';


за это:



std::cout << variable << "n";




поздним добавлением:



когда я задал этот вопрос, я, казалось, думал, что новая строка 'n' сброс буфера. Теперь я знаю, что это зависит.



по умолчанию std::cin привязан к старому C stdinFILE* поток, и std::cout привязан к stdout. Промывка на новой линии происходит от этого связывания. По умолчанию stdout, если он подключен к терминалу, линия-буфер. Это означает, что новая строка будет очищать свои буферы. Поэтому при печати новой строки с помощью std::cout, что приведет к stdout смываться.



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

599   6  

6 ответов:

на самом деле '\n' должно быть по умолчанию. Если вы не хотите также явно очистить поток (и когда и почему вы хотите это сделать?), нет необходимости использовать std::endl на всех.1
Конечно, многие книги и учебные пособия используют std::endl по умолчанию. Это печально и может привести к серьезные ошибки производительности.

Я думаю, что есть небольшая разница между использованием '\n' или через "\n", но последний представляет собой массив (два) символы, которые должны быть напечатаны символ за символом, для которых должен быть настроен цикл, что сложнее, чем вывод одного символа. Конечно, при выполнении ввода-вывода это редко имеет значение, но если вы сомневаетесь, когда вы хотите вывести один символьный литерал, выведите символьный литерал, а не весь строковый литерал.
Хорошим побочным эффектом этого является то, что вы сообщаете в своем коде, что вы предназначены выводит только один символ, а не просто случайно сделал это.


1отметим, что std::cout связана с std::cin по умолчанию, что приводит к std::cout сбрасывается перед любой операцией ввода, так что любое приглашение будет напечатано до того, как пользователь должен что-то ввести.

они делают разные вещи. "\n" выводит новую строку (в соответствующем представлении для конкретной платформы, поэтому он генерирует "\r\n" в Windows), но std::endl тут же и смывает поток. Обычно вам не нужно немедленно смывать поток, и это будет стоить вам производительности, поэтому по большей части нет причин использовать std::endl.

нет лучшей. Вы используете то, что вам нужно :

  • '\n ' - чтобы закончить строку
  • "some string\n" - конец строки после некоторой строки
  • std::endl - чтобы закончить линию и смыть поток

Edit: я плохо сформулировал свой ответ, что, возможно, заставило людей поверить, что я думал, что "\n" на самом деле напечатал нулевой символ. Это, конечно, неправильно :)

Edit 2: посмотрев на ссылку на C++,chars передаются по ссылке в любом случае, так что нет никакой разницы. Единственное различие заключается в том, что cstring придется искать разделяющий символ. ниже не правильно из-за этого факта.

'\n' будет так немного эффективнее, чем "\n", потому что последний также содержит нулевой символ в конце, что означает, что вы отправляете char* до operator<<() (обычно 4 байта на 32-разрядной системе) в отличие от одного байта для char.

на практике это не имеет значения. Лично я следую конвенции, которую изложил Владимир Владимирович.*

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

иногда вы можете уйти без явной промывки потока самостоятельно; например, в среде linux, если cout синхронизируется с STDOUT (это по умолчанию) и пишем для терминала, то по умолчанию, поток будет линия буферизованный и будет сбрасывать автоматически каждый раз, когда вы пишете новую строку.

однако, рискованно полагаться на такое поведение. например, в той же среде linux, если вы решили запустить свою программу с stdout быть перенаправлен в файл или передается в другой процесс, то по умолчанию, поток будет блок амортизированный вместо.

аналогично, если вы позже решите отключить синхронизация с stdio (например, для эффективности), то реализации будут иметь тенденцию использовать iostreamмеханизмы буферизации, которые не имеют режима буферизации линии.

я видел много потраченной впустую производительности из-за этой ошибки; если выход должен быть виден, когда он написан, то вы должны либо использовать std::endl явно (или использовать std::flush или std::ostream::flush, но я обычно нахожу std::endl более удобно), или сделать что-то еще, что обеспечивает промывку происходит достаточно часто, например, настройка stdout для буферизации строки (при условии, что это достаточно).

  • std::cout << variable << std::endl;

    std::endl вывод новой строки, но он также сбрасывает выходной поток. Другими словами, тот же эффект, что и

    std::cout << variable << '\n'; // output newline
    std::cout.flush();      // then flush 
    
  • std::cout << variable << '\n';

    '\n' выход новой строки на char, отсюда ostream& operator<< (ostream& os, char c); будет использоваться.

  • std::cout << variable << "\n";

    "\n" это const char[2], так что ostream& operator<< (ostream& os, const char* s); будет использоваться. Мы можем себе представить, что эта функция будет содержать цикл, мы можем утверждать, что это перебор чтобы просто распечатать новую строку.

Comments

    Ничего не найдено.