Что лучше printf или cout
«printf» против «cout» в C ++
В чем разница между printf() и cout в C ++?
Реальные различия
растяжимость
Однако я сомневаюсь, что многие люди захотят расширить ostream (честно говоря, я редко видел такие расширения, даже если их легко сделать). Тем не менее, это здесь, если вам это нужно.
Синтаксис
Хотя это не кажется слишком сумасшедшим (просто в два раза дольше), все становится более сумасшедшим, когда вы на самом деле форматируете аргументы, а не просто печатаете их. Например, печать чего-то подобного 0x0424 просто сумасшедшая. Это вызвано std::cout смешиванием состояния и фактических значений. Я никогда не видел языка, в котором что-то вроде std::setfill бы было типом (кроме C ++, конечно). printf четко разделяет аргументы и фактический тип. Я действительно предпочел бы сохранить его printf версию (даже если она выглядит несколько загадочно) по сравнению с iostream версией (поскольку она содержит слишком много шума).
Перевод
Не нужно запоминать / искать определенный синтаксис целочисленных типов
Вы не можете напечатать байт NUL, \0
Поскольку printf используются строки C, а не строки C ++, он не может печатать NUL-байт без специальных уловок. В некоторых случаях можно использовать %c с ‘\0’ качестве аргумента, хотя это явно хак.
Различия никого не волнуют
Представление
Вы можете легко заметить, что две строки и 2 (число) выдвигаются в качестве printf аргументов. Это об этом; больше ничего нет Для сравнения, это iostream скомпилировано в сборку. Нет, там нет встраивания; каждый отдельный operator вызов означает другой вызов с другим набором аргументов.
наследование
Тип безопасности
Правда, списки аргументов переменной длины не имеют никакой безопасности, но это не имеет значения, так как популярные компиляторы C могут обнаружить проблемы со printf строкой формата, если вы включите предупреждения. На самом деле, Clang может сделать это без включения предупреждений.
Повысить безопасность типов, уменьшить количество ошибок, расширить возможности и обеспечить наследуемость.
Что лучше использовать: cout / wcout или printf? [закрыт]
Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме.
Собственно, вопрос в заголовке. Пожалуйста, дайте подробный ответ.
1 ответ 1
Как завещал нам Страуструп, лучше потоки чем printf. Ибо потоки, как минимум, типобезопасны.
Представим, что в процессе работы пришлось сменить тип переменной (это встречается сплошь и рядом):
Как видно, при использовании потока ничего не поменялось. А при использовании printf пришлось править форматную строку. Если printf много в коде, то везде править форматную строку во всех printf очень утомительно и черевато ошибками.
Уж не знаю насколько потоки следствие идеи перегрузки операций. Может быть это и так. В любом случае, в варианте с printf тип операнда указывается два раза. Один раз в форматной строке, а второй раз собственно имя переменной говорит компилятору какой это тип. А два раза повторять одну и ту же информацию не есть хорошо. Потому что править приходится в двух местах, а не в одном месте. Так что идея с потоками (независимо от источника ее появления, будь то перегрузка операций или просто желание избавится от форматной строки) еще позволила избавится от ненужного дублирования информации.
Кстати, перегрузить операции можно было бы и с printf. Или в потоках оставить форматную строку. Ну если все делать через одно место конечно.
Что касается квалификации персонала, то квалификация постоянно растет. Старая школа может долбать любимый printf до посинения, пока самим не надоест вылавливать ошибки форматов. Новое поколение не знает таких ужасов и весело применяет потоки.
Кстати, вывод через потоки в общем случае быстрее, чем вывод через printf. Объясняется это тем, что при выводе через потоки разбор типов происходит на этапе компиляции и в рантайме разбора типов нет, а там есть только вывод значения. В случае же с printf происходит разбор форматной строки в рантайме, то есть компилированный код передает управление интерпретатору форматной строки. А, как известно, интерпретатор работает в 100-1000 раз медленнее, чем компилированный код.
Ранние трансляторы С++ создавали потоковый вывод как надстройку над выводом printf и разницы в скорости не было (но все равно была разница в типобезопасности, так как форматные строки формировались автоматически). Современные трансляторы С++ делают потоковый вывод как надо, без использования printf. И это (теоретически) повышает быстродействие вывода.
Так что скорость вывода это еще один аргумент, который заставляет программистов выбирать потоки вместо старого подхода с printf.
Но и объем скомпилированного кода больше.
Объем скомпилированного кода при выводе в поток не больше, чем при использовании printf.
В этом примере строки вывода
разворачиваются в обычные вызовы подпрограмм вывода, а вовсе не в последовательные повторения кода.
скорость встроенных при компиляции (как следствие реализации templates) преобразований выше.
Скорость вывода при использовании printf меньше именно из-за того, что разбор форматной строки происходит в рантайме. В случае использования потоков нет разбора форматной строки в рантайме и также нет оверхеда из-за шаблонов потому что там вставляется не шаблон, а обычный вызов подпрограммы вывода для соответствующего типа. Это легко проверить, если посмотреть ассемблерный код простого примера, приведенного выше. Транслятор Visual Studio 2017.
разворачивается в обычный вызов подпрограммы
и никаких шаблонов тут нет.
мы пишем программы не для компьютера, а для других программистов
Довольно спорное утверждение. Проще переписать весь код, чем править чужое. Ибо невозможно до конца понять, какие мысли (часто неверные) были у человека, когда он писал код.
Поэтому, используйте те конструкции, что вам представляются наиболее подходящими для понимания конкретного кода.
Нет, надо не только использовать то, чем владеешь, но и осваивать новые, более продвинутые инструменты вроде потоков, которые для нас придумывают разные головастые страуструпы. Если бы мы не осваивали новые инструменты, то мы бы до сих пор программировали в машинных кодах.
printf vs. std::cout [duplicate]
If I just want to print a string on screen, I can do that using those two ways:
7 Answers 7
Here’s an interesting example that I found here.
printf and its associated friends are C functions. They work in C++, but do not have the type safety of C++ std::ostream s. Problems can arise in programs that use printf functions to format output based on user input (or even input from a file). For example:
C++ has much stronger type safety (and a std::string class) to help prevent problems like these.
I struggle with this very question myself. printf is in general easier to use for formatted printing, but the iostreams facility in C++ has the big advantage that you can create custom formatters for objects. I end up using both of them in my code as necessary.
The problem with using both and intermixing them is that the output buffers used by printf and cout are not the same, so unless you run unbuffered or explicitly flush output you can end up with corrupted output.
My main objection to C++ is that there is no fast output formatting facility similar to printf, so there is no way to easily control output for integer, hex, and floating point formatting.
Java had this same problem; the language ended up getting printf.
Actually for your particular example, you should have asked which is preferable, puts or cout. printf prints formatted text but you are just outputting plain text to the console.
For general use, streams (iostream, of which cout is a part) are more extensible (you can print your own types with them), and are more generic in that you can generate functions to print to any type of stream, not just the console (or redirected output). You can create generic stream behaviour with printf too using fprintf which take a FILE* as a FILE* is often not a real file, but this is more tricky.
Streams are «typesafe» in that you overload with the type you are printing. printf is not typesafe with its use of ellipses so you could get undefined results if you put the wrong parameter types in that do not match the format string, but the compiler will not complain. You may even get a seg-fault / undefined behaviour (but you could with cout if used incorrectly) if you miss a parameter or pass in a bad one (eg a number for %s and it treats it as a pointer anyway).
printf does have some advantages though: you can template a format string then reuse that format string for different data, even if that data is not in a struct, and using formatting manipulations for one variable does not «stick» that format for further use because you specify the format for each variable. printf is also known to be threadsafe whereas cout actually is not.
boost has combined the advantages of each with their boost::format library.
The printf has been borrowed from C and has some limitations. The most common mentioned limitation of printf is type safety, as it relies on the programmer to correctly match the format string with the arguments. The second limitation that comes again from the varargs environment is that you cannot extend the behavior with user defined types. The printf knows how to print a set of types, and that’s all that you will get out of it. Still, it for the few things that it can be used for, it is faster and simpler to format strings with printf than with c++ streams.
So what should you use? In general I prefer using streams, as overloading operator for my own types is simple and they can be used uniformly with all types.
cout vs printf
printf > cout
Помогите переделать printf(«| %3.2f | %3.1f | %7.5f |\n»,a,b,y); на cout.
Cout в printf
Здравствуйте, может кто-нибудь помочь переделать cout в printf на 87-88 строках в данной программе.
В C++ и всё будет отлично работать.
Не печатает ‘\0’ А кому надо это печатать?! Если вы воспользуетесь функцией putchar, то она вам его напечатает.
Тоже должна его напечатать.(я не проверял, но думаю должна). Хотя что у вас будет на терминале не знаю. Потому что первые 32 символа непечатные, некоторые управляющие, но не этот. Если их начать печатать с терминалом начнут происходить всякие странные вещи. иногда оч полезное. Например если попробовать напечатать «\033[1mPiter\033[0m» то вы увидите слово Piter напчатаное жирным шрифтом. Можно сделать инверсию, мигание, расцечивать всякими цветами вплоть до rgb и всё с помощью печати esc последовательностей. Есть лр последовательности переключающие режимы терминала но ни в одну из них не входит символ ‘\0’
можно написать ненужное кол-во аргументов и их типы
да можно, но на каком нибудь оч древнем компиляторе потому что любой
не оч старый компилятор всегда не только ругнётся, но и скажет что именно не так. Если вы конечно не отключили предупреждения. но это уже вы сами виноваты.
Любой аргумент против можно разбить в пух и прах если только подумать, а не слушать всяких непонятных личностей ссылающихся на америкосов о том, что всё не так. своя голова на плечах должна быть! В этом всё дело.
printf работает в среднем раз в 10 быстрее чем cout. это известный факт. По сути cout это оч тормознутая штука.
printf гораздо старше чем cout итам уже всё давно исправлено и доведено до совершенства. а cout иногда глючит.
printf гораздо удобнее чем cout, потому что все действия пишутся водном формате где есть всё. и нчиего больше. Если вам надо выводить элементы в cout не по default режиму это заставвит вас применять многочисленные манипуляторы, что оч неудобно. а иногда даже не работает. Приходится выяснять почему.
printf есть вещи, недоступные в cout, например нумерация аргументов вывода с помощью %$1-$n вместо %. И это позволяет вам печатать аргументы не по порядку, а по номерам. некоторые можно печатаь по 2 и более раз если указать в формате один и тот же номер аргумента. Можно печатать число в локальном представлении, если указать флаг ‘ или локальный набор цифр с помощью флага I
ну и конечно вы можете динамически управлять точностью задав в формате *. В cout это тоже можно, но в printf удобнее
Не печатает объекты. Представьте себе cout их тоже не печатает. Если конечно вы не перегрузите специальный оператор 0
Русские Блоги
Дети учатся C ++ (22): сравнение эффективности cin и scanf, cout и printf
1. Генерация тестовых данных
Сначала запишите 10 миллионов тестовых данных в data.txt
Конфигурация компьютера представляет собой процессор i7, память 16 ГБ, а время работы составляет около 5 секунд. Размер сгенерированного файла data.txt составляет 77040 КБ, что составляет около 77 МБ.
Во-вторых, сравнение эффективности cin и scanf
(2) Ускорение вращения
Следующие две строки кода могут улучшить эффективность cin и cout
Три, анализ sync_with_stdio и cin.tie
(1) ios :: sync_with_stdio ()
Значение по умолчанию для параметра sync_with_stdion равно true, что означает, что cin и scanf синхронизированы, а cout и printf синхронизированы.
Что означает синхронизация?
Например, несколько человек стоят в очереди за водой, и есть только один кран. Тогда только человек впереди может допить воду до человека сзади, в этом случае человек спереди должен закончить воду перед человеком сзади.
Соответствующая синхронизация асинхронная (асинхронная), что асинхронная?
Например, несколько человек стоят в очереди, чтобы набрать воды, и есть много кранов. Тогда человек впереди не может допить воду до человека сзади. Например, человек с номером 1 выбрал кран № 1, а человек с номером 2 немедленно выбрал кран № 2. Если скорость подачи воды из крана № 2 намного выше, чем у крана № 1, то человек получил оценку № 2 Он допьет воду до первого лица.
(Два) cin.tie (0)
Связывание здесь означает привязку. По умолчанию cin привязывается к cout. Каждый раз, когда выполняется оператор cout Также может быть написано как cin.tie()
cin.tie (0) эквивалентен cin.tie (NULL), что означает, что он не связан ни с одним выходным потоком, то есть cout по умолчанию не связан.
Если вы используете его в это время cin.tie() Компилятор сообщит об ошибке.
Следующие процедуры могут быть использованы для углубления понимания:
результат операции:
напечатано на консоли
Также генерируется файл test.out, содержимое которого
4. Сравнение эффективности между cout и printf
(1) Вывести 100 000 данных на консоль для тестирования
Видно, что эффективность работы cout выше, чем у printf, что является результатом оптимизации cin и cout компилятором G ++.
(Два) ускорить кут
Видно, что после ускорения cout работает быстрее.
V. Вывод
(1) Scanf / printf должен форматировать символы% d,% f,% c и т.п., что не так удобно, как cin / cout
(2) Cout очень неудобен при управлении выводом десятичных разрядов. Нужно сделать так
(3) Для некоторых компиляторов, которые оптимизируют cin и cout (например, G ++), эффективность работы cin / cout выше, чем scanf / printf.
Но для компиляторов, которые не были оптимизированы, эффективность scanf / printf намного выше, чем у cin / cout. Это почти всегда относится к статьям, найденным в Интернете. Это полная противоположность экспериментальным результатам в этой статье.
(4) Для неалгоритмических игр не имеет значения, используете ли вы cin / cout или scanf / printf.
(5) Но для игр с алгоритмами из-за большого объема данных это часто приводит к тайм-ауту (превышен лимит времени TLE). В настоящее время scanf / printf можно использовать равномерно или использовать plus ios::sync_with_stdio(false); cin.tie(0) Cin / соиЬ.
TopCoder & Codeforces & AtCoder Exchange QQ Группа: 648202993
Для получения дополнительной информации, пожалуйста, следуйте общедоступной учетной записи WeChat.
Интеллектуальная рекомендация
Tree Дерево отрезков линии】 COGS 2632
Ссылочный блогАвтор:dreaming__ldxИсточник: CSDN Портал последовательности операций 【Название описания】 Последовательность длины n, вес порядкового номера в начале равен 0, есть m операций Поддерживают.
PAT-A-1046 кратчайшее расстояние [префикс и]
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits. Input Specification: Each input fi.
Как нарисовать несколько линий ROC на одном графике?
Класс коллекции JAVA
Резюме JAVA-коллекции Один, коллекция 1. Характеристики коллекций: коллекции используются только для хранения объектов, длина коллекции является переменной, и в коллекции могут храниться объекты разны.
MySQL репликация главный-подчиненный + переключатель главный-подчиненный
MySQL репликация главный-подчиненный + переключатель главный-подчиненный 05 января 2018 10:46:35Протрите протирать прыжок Количество просмотров: 5183Более Персональная категория:база данныхЭксплуатаци.