Собственно, вопрос в заголовке. Пожалуйста, дайте подробный ответ.
Как завещал нам Страуструп, лучше потоки чем printf. Ибо потоки, как минимум, типобезопасны.
Например есть код:
int i;
cout<<i;
printf("%i",i);
Представим, что в процессе работы пришлось сменить тип переменной (это встречается сплошь и рядом):
float i;
cout<<i;
printf("%f",i);
Как видно, при использовании потока ничего не поменялось. А при использовании printf пришлось править форматную строку. Если printf много в коде, то везде править форматную строку во всех printf очень утомительно и черевато ошибками.
UPD1:
Предположить легко. Однако, на самом деле это последствие идеи предоставления пользователям языка средств для его расширения -- т.е. конструирования собственных типов данных и операций над ними, что влечет перегрузку операций (т.е. одно и то же обозначение операций в зависимости от типов операндов дает разный результат). Хорошо это или плохо для реальной практики программирования, учитывающей качество персонала, вопрос дискуссионный
Уж не знаю насколько потоки следствие идеи перегрузки операций. Может быть это и так. В любом случае, в варианте с printf тип операнда указывается два раза. Один раз в форматной строке, а второй раз собственно имя переменной говорит компилятору какой это тип. А два раза повторять одну и ту же информацию не есть хорошо. Потому что править приходится в двух местах, а не в одном месте. Так что идея с потоками (независимо от источника ее появления, будь то перегрузка операций или просто желание избавится от форматной строки) еще позволила избавится от ненужного дублирования информации.
Кстати, перегрузить операции можно было бы и с printf. Или в потоках оставить форматную строку. Ну если все делать через одно место конечно.
Что касается квалификации персонала, то квалификация постоянно растет. Старая школа может долбать любимый printf до посинения, пока самим не надоест вылавливать ошибки форматов. Новое поколение не знает таких ужасов и весело применяет потоки.
UPD2:
Кстати, вывод через потоки в общем случае быстрее, чем вывод через printf. Объясняется это тем, что при выводе через потоки разбор типов происходит на этапе компиляции и в рантайме разбора типов нет, а там есть только вывод значения. В случае же с printf происходит разбор форматной строки в рантайме, то есть компилированный код передает управление интерпретатору форматной строки. А, как известно, интерпретатор работает в 100-1000 раз медленнее, чем компилированный код.
Ранние трансляторы С++ создавали потоковый вывод как надстройку над выводом printf и разницы в скорости не было (но все равно была разница в типобезопасности, так как форматные строки формировались автоматически). Современные трансляторы С++ делают потоковый вывод как надо, без использования printf. И это (теоретически) повышает быстродействие вывода.
Так что скорость вывода это еще один аргумент, который заставляет программистов выбирать потоки вместо старого подхода с printf.
UPD3:
Но и объем скомпилированного кода больше.
Объем скомпилированного кода при выводе в поток не больше, чем при использовании printf.
Пример:
int var1=1;
int var2=2;
cout<<var1;
cout<<var2;
В этом примере строки вывода
cout<<var1;
cout<<var2;
разворачиваются в обычные вызовы подпрограмм вывода, а вовсе не в последовательные повторения кода.
скорость встроенных при компиляции (как следствие реализации templates) преобразований выше.
Скорость вывода при использовании printf меньше именно из-за того, что разбор форматной строки происходит в рантайме. В случае использования потоков нет разбора форматной строки в рантайме и также нет оверхеда из-за шаблонов потому что там вставляется не шаблон, а обычный вызов подпрограммы вывода для соответствующего типа. Это легко проверить, если посмотреть ассемблерный код простого примера, приведенного выше. Транслятор Visual Studio 2017.
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.14.26433.0
TITLE C:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
PUBLIC ?__empty_global_delete@@YAXPAX@Z ; __empty_global_delete
PUBLIC ?__empty_global_delete@@YAXPAXI@Z ; __empty_global_delete
PUBLIC _main
EXTRN __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z:PROC
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_InitBase:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A:BYTE
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp
; COMDAT _main
_TEXT SEGMENT
_var2$ = -20 ; size = 4
_var1$ = -8 ; size = 4
_main PROC ; COMDAT
push ebp
mov ebp, esp
sub esp, 216 ; 000000d8H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-216]
mov ecx, 54 ; 00000036H
mov eax, -858993460 ; ccccccccH
rep stosd
mov DWORD PTR _var1$[ebp], 1
mov DWORD PTR _var2$[ebp], 2
mov esi, esp
mov eax, DWORD PTR _var1$[ebp]
push eax
mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
cmp esi, esp
call __RTC_CheckEsp
mov esi, esp
mov eax, DWORD PTR _var2$[ebp]
push eax
mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
cmp esi, esp
call __RTC_CheckEsp
xor eax, eax
pop edi
pop esi
pop ebx
add esp, 216 ; 000000d8H
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp
; COMDAT ?__empty_global_delete@@YAXPAXI@Z
_TEXT SEGMENT
___formal$ = 8 ; size = 4
___formal$ = 12 ; size = 4
?__empty_global_delete@@YAXPAXI@Z PROC ; __empty_global_delete, COMDAT
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?__empty_global_delete@@YAXPAXI@Z ENDP ; __empty_global_delete
_TEXT ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File c:\user\basil\rttsched\etudes\etude2\etude2\etude2\etude2.cpp
; COMDAT ?__empty_global_delete@@YAXPAX@Z
_TEXT SEGMENT
___formal$ = 8 ; size = 4
?__empty_global_delete@@YAXPAX@Z PROC ; __empty_global_delete, COMDAT
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?__empty_global_delete@@YAXPAX@Z ENDP ; __empty_global_delete
_TEXT ENDS
END
Видно, что вызов
cout<<var1;
разворачивается в обычный вызов подпрограммы
call
DWORD PTR __imp_??6?$basic_ostream@DU$char_traits@D@std@@@std@@QAEAAV01@H@Z
и никаких шаблонов тут нет.
UPD4:
мы пишем программы не для компьютера, а для других программистов
Довольно спорное утверждение. Проще переписать весь код, чем править чужое. Ибо невозможно до конца понять, какие мысли (часто неверные) были у человека, когда он писал код.
Поэтому, используйте те конструкции, что вам представляются наиболее подходящими для понимания конкретного кода.
Нет, надо не только использовать то, чем владеешь, но и осваивать новые, более продвинутые инструменты вроде потоков, которые для нас придумывают разные головастые страуструпы. Если бы мы не осваивали новые инструменты, то мы бы до сих пор программировали в машинных кодах.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
помогите разобраться с сортировкой и выводом всего этого в файл по возрастанию, пробовал реализовывать через динамические массивы, но так...
Как строить графики с помощью Qt5? Qwt3D не обновлялся с 2007 года и вроде для Qt4Находил решение от частных лиц
Цель: при изменении размера окна, изменялся размер QGridLayout
В интернете множество библиотек связанных с Blur эффектами, но почему-то я не нашел библиотек и даже способов сделать Blur в LinearLayout Background