"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 сломано, тогда новые строки ничего не будут смывать.
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