sprintf sirve que para entre ejemplos diferencia c++ printf iostream cout stdio

sirve - ''printf'' vs. ''cout'' en C++



printf y scanf (16)

¿Cuál es la diferencia entre printf() y cout en C ++?


Con los primitivos, probablemente no importa por completo cuál uses. Digo que la utilidad resulta cuando se quieren generar objetos complejos.

Por ejemplo, si tienes una clase,

#include <iostream> #include <cstdlib> using namespace std; class Something { public: Something(int x, int y, int z) : a(x), b(y), c(z) { } int a; int b; int c; friend ostream& operator<<(ostream&, const Something&); }; ostream& operator<<(ostream& o, const Something& s) { o << s.a << ", " << s.b << ", " << s.c; return o; } int main(void) { Something s(3, 2, 1); // output with printf printf("%i, %i, %i/n", s.a, s.b, s.c); // output with cout cout << s << endl; return 0; }

Ahora, lo anterior puede que no parezca tan bueno, pero supongamos que tiene que generar esto en múltiples lugares en su código. No solo eso, digamos que agrega un campo "int d". Con cout, solo tienes que cambiarlo en un solo lugar. Sin embargo, con printf, tendrías que cambiarlo posiblemente en muchos lugares y no solo eso, debes recordarte cuáles son los resultados.

Dicho esto, con cout, puede reducir la cantidad de veces que dedica al mantenimiento de su código y no solo eso, si reutiliza el objeto "Algo" en una nueva aplicación, no tiene que preocuparse realmente por el resultado.


De las preguntas frecuentes de C ++ :

[15.1] ¿Por qué debería usar <iostream> lugar del tradicional <cstdio> ?

Aumente la seguridad de los tipos, reduzca los errores, permita la extensibilidad y proporcione heredabilidad.

printf() no está roto, y scanf() es quizás habitable a pesar de ser propenso a errores, sin embargo, ambos están limitados con respecto a lo que C ++ I / O puede hacer. C ++ I / O (con << y >> ) es, en relación con C (con printf() y scanf() ):

  • Más seguro para el tipo: con <iostream> , el compilador conoce estáticamente el tipo de objeto que tiene E / S. En contraste, <cstdio> usa los campos "%" para determinar los tipos de forma dinámica.
  • Menos propenso a errores: con <iostream> , no hay tokens "%" redundantes que deban ser coherentes con los objetos reales que son E / S. Eliminar la redundancia elimina una clase de errores.
  • Extensible: el mecanismo de C ++ <iostream> permite que los nuevos tipos definidos por el usuario sean I / O''d sin romper el código existente. ¡Imagínese el caos si todos agregaran simultáneamente nuevos campos "%" incompatibles a printf() y scanf() ?
  • Heredable: El mecanismo de C ++ <iostream> se construye a partir de clases reales como std::ostream y std::istream . A diferencia del FILE* <cstdio> , estas son clases reales y, por lo tanto, heredadas. Esto significa que puedes tener otras cosas definidas por el usuario que se ven y actúan como secuencias, pero que hacen las cosas extrañas y maravillosas que deseas. Automáticamente puede usar las millones de líneas de código de E / S escritas por usuarios que ni siquiera conoce, y no necesitan saber sobre su clase de "flujo extendido".

Por otro lado, printf es significativamente más rápido, lo que puede justificar su uso con preferencia a cout en casos muy específicos y limitados. Siempre perfil primero. (Ver, por ejemplo, http://programming-designs.com/2009/02/c-speed-test-part-2-printf-vs-cout /)


Dos puntos no mencionados aquí de otra manera que me parecen significativos:

1) cout lleva una gran cantidad de equipaje si aún no está utilizando el STL. Agrega más del doble de código a tu archivo de objeto que printf . Esto también es cierto para la string , y esta es la razón principal por la que tiendo a usar mi propia biblioteca de cadenas.

2) cout utiliza operadores << sobrecargados, lo que me parece desafortunado. Esto puede agregar confusión si también está utilizando el operador << para su propósito previsto (desplazamiento a la izquierda). Personalmente no me gusta sobrecargar a los operadores con fines tangenciales a su uso previsto.

Línea inferior: cout (y string ) si ya estoy usando la STL. De lo contrario, tiendo a evitarlo.


La gente suele afirmar que printf es mucho más rápido. Esto es en gran parte un mito. Acabo de probarlo, con los siguientes resultados:

cout with only endl 1461.310252 ms cout with only ''/n'' 343.080217 ms printf with only ''/n'' 90.295948 ms cout with string constant and endl 1892.975381 ms cout with string constant and ''/n'' 416.123446 ms printf with string constant and ''/n'' 472.073070 ms cout with some stuff and endl 3496.489748 ms cout with some stuff and ''/n'' 2638.272046 ms printf with some stuff and ''/n'' 2520.318314 ms

Conclusión: si solo quieres nuevas líneas, usa printf ; de lo contrario, cout es casi tan rápido, o incluso más rápido. Más detalles se pueden encontrar en mi blog .

Para ser claros, no estoy tratando de decir que los iostream son siempre mejores que printf ; Solo trato de decir que debe tomar una decisión informada basada en datos reales, no en una suposición descabellada basada en una suposición común y engañosa.

Actualización: Aquí está el código completo que usé para las pruebas. Compilado con g++ sin ninguna opción adicional (aparte de -lrt para el tiempo).

#include <stdio.h> #include <iostream> #include <ctime> class TimedSection { char const *d_name; timespec d_start; public: TimedSection(char const *name) : d_name(name) { clock_gettime(CLOCK_REALTIME, &d_start); } ~TimedSection() { timespec end; clock_gettime(CLOCK_REALTIME, &end); double duration = 1e3 * (end.tv_sec - d_start.tv_sec) + 1e-6 * (end.tv_nsec - d_start.tv_nsec); std::cerr << d_name << ''/t'' << std::fixed << duration << " ms/n"; } }; int main() { const int iters = 10000000; char const *text = "01234567890123456789"; { TimedSection s("cout with only endl"); for (int i = 0; i < iters; ++i) std::cout << std::endl; } { TimedSection s("cout with only ''//n''"); for (int i = 0; i < iters; ++i) std::cout << ''/n''; } { TimedSection s("printf with only ''//n''"); for (int i = 0; i < iters; ++i) printf("/n"); } { TimedSection s("cout with string constant and endl"); for (int i = 0; i < iters; ++i) std::cout << "01234567890123456789" << std::endl; } { TimedSection s("cout with string constant and ''//n''"); for (int i = 0; i < iters; ++i) std::cout << "01234567890123456789/n"; } { TimedSection s("printf with string constant and ''//n''"); for (int i = 0; i < iters; ++i) printf("01234567890123456789/n"); } { TimedSection s("cout with some stuff and endl"); for (int i = 0; i < iters; ++i) std::cout << text << "01234567890123456789" << i << std::endl; } { TimedSection s("cout with some stuff and ''//n''"); for (int i = 0; i < iters; ++i) std::cout << text << "01234567890123456789" << i << ''/n''; } { TimedSection s("printf with some stuff and ''//n''"); for (int i = 0; i < iters; ++i) printf("%s01234567890123456789%i/n", text, i); } }


Me gustaría decir que la falta de extensibilidad de printf no es del todo cierto:
En C, es cierto. Pero en C, no hay clases reales.
En C ++, es posible sobrecargar el operador de conversión, por lo tanto, sobrecargar un operador char* y usar printf siguiente manera:

Foo bar; ...; printf("%s",bar);

Puede ser posible, si Foo sobrecarga al buen operador. O si hiciste un buen método. En resumen, printf es tan extensible como cout para mí.

El argumento técnico que puedo ver para las secuencias de C ++ (en general ... no solo cout.) Son:

  • Tipos de seguridad. (Y, por cierto, si quiero imprimir un solo ''/n'' uso putchar(''/n'') ... no usaré una bomba nuclear para matar a un insecto).

  • Más sencillo de aprender. (no hay parámetros "complicados" que aprender, solo usar los operadores << y >> )

  • Trabaja de forma nativa con std::string (para printf existe std::string::c_str() , pero para scanf ?)

Para printf veo:

  • Formato complejo más fácil, o al menos más corto (en términos de caracteres escritos). Mucho más legible, para mí (cuestión de gustos, supongo).

  • Mejor control de lo que hizo la función (Devuelva cuántos caracteres se escribieron y está el formateador %n : "No se imprime nada. El argumento debe ser un puntero a un int firmado, donde se almacena el número de caracteres escritos hasta ahora" ( de printf - Referencia de C ++ )

  • Mejores posibilidades de depuración. Por el mismo motivo que el último argumento.

Mis preferencias personales van a las funciones printf (y scanf ), principalmente porque me encantan las líneas cortas y porque no creo que los problemas de tipografía en la impresión de texto sean realmente difíciles de evitar. Lo único que lamento con las funciones de estilo C es que std::string no es compatible. Tenemos que pasar por un char* antes de dárselo a printf (con std::string::c_str() si queremos leer, pero ¿cómo escribir?)


Me gustaría señalar que si quieres jugar con subprocesos en C ++, si usas cout puedes obtener algunos resultados interesantes.

Considere este código:

#include <string> #include <iostream> #include <thread> using namespace std; void task(int taskNum, string msg) { for (int i = 0; i < 5; ++i) { cout << "#" << taskNum << ": " << msg << endl; } } int main() { thread t1(task, 1, "AAA"); thread t2(task, 2, "BBB"); t1.join(); t2.join(); return 0; } // g++ ./thread.cpp -o thread.out -ansi -pedantic -pthread -std=c++0x

Ahora, la salida viene todo barajado. También puede producir diferentes resultados, intente ejecutar varias veces:

##12:: ABABAB ##12:: ABABAB ##12:: ABABAB ##12:: ABABAB ##12:: ABABAB

Puede usar printf para hacerlo bien, o puede usar mutex .

#1: AAA #2: BBB #1: AAA #2: BBB #1: AAA #2: BBB #1: AAA #2: BBB #1: AAA #2: BBB

¡Que te diviertas!


Me sorprende que todos en esta pregunta afirmen que std::cout es mucho mejor que printf , incluso si la pregunta solo plantea diferencias. Ahora, hay una diferencia: std::cout es C ++ y printf es C (sin embargo, puedes usarlo en C ++, como cualquier otra cosa de C). Ahora, seré honesto aquí; Tanto printf como std::cout tienen sus ventajas.

Diferencias reales

Extensibilidad

std::cout es extensible. Sé que la gente dirá que printf es extensible, pero dicha extensión no se menciona en el estándar C (por lo que tendría que usar características no estándar, pero ni siquiera existe una característica común no estándar), y tales extensiones son una. carta (por lo que es fácil entrar en conflicto con un formato ya existente).

A diferencia de printf , std::cout depende completamente de la sobrecarga del operador, por lo que no hay problema con los formatos personalizados; todo lo que debe hacer es definir una subrutina que tome std::ostream como primer argumento y su tipo como segundo. Como tal, no hay problemas con el espacio de nombres; mientras tengas una clase (que no se limita a un solo carácter), puedes tener la sobrecarga de std::ostream para ello.

Sin embargo, dudo que muchas personas quieran extender ostream (para ser honesto, rara vez vi tales extensiones, incluso si son fáciles de hacer). Sin embargo, está aquí si lo necesitas.

Sintaxis

Como se pudo notar fácilmente, tanto printf como std::cout utilizan una sintaxis diferente. printf usa la sintaxis de la función estándar usando una cadena de patrones y listas de argumentos de longitud variable. En realidad, printf es una de las razones por las que C los tiene: los formatos de printf son demasiado complejos para poder usarse sin ellos. Sin embargo, std::cout usa una API diferente: la API del operator << que se devuelve a sí misma.

En general, eso significa que la versión C será más corta, pero en la mayoría de los casos no importará. La diferencia es notable cuando imprime muchos argumentos. Si tiene que escribir algo como Error 2: File not found. , asumiendo el número de error, y su descripción es un marcador de posición, el código se vería así. Ambos ejemplos funcionan de manera idéntica (bueno, más o menos, std::endl realidad std::endl el búfer).

printf("Error %d: %s./n", id, errors[id]); std::cout << "Error " << id << ": " << errors[id] << "." << std::endl;

Si bien esto no parece demasiado loco (solo es dos veces más largo), las cosas se vuelven más locas cuando en realidad formateas los argumentos, en lugar de solo imprimirlos. Por ejemplo, la impresión de algo como 0x0424 es una locura. Esto es causado por el estado de mezcla std::cout y los valores reales. Nunca vi un lenguaje donde algo como std::setfill sería un tipo (aparte de C ++, por supuesto). printf separa claramente los argumentos y el tipo real. Realmente preferiría mantener la versión de printf (incluso si parece algo críptica) en comparación con la versión de iostream (ya que contiene demasiado ruido).

printf("0x%04x/n", 0x424); std::cout << "0x" << std::hex << std::setfill(''0'') << std::setw(4) << 0x424 << std::endl;

Traducción

Aquí es donde radica la verdadera ventaja de printf . La printf formato printf es bien ... una cadena. Eso hace que sea realmente fácil de traducir, en comparación con el abuso de iostream del operator << . Suponiendo que la función gettext() traduce, y desea mostrar Error 2: File not found. , el código para obtener la traducción de la cadena de formato mostrada anteriormente se vería así:

printf(gettext("Error %d: %s./n"), id, errors[id]);

Ahora, asumamos que traducimos a Fictionish, donde el número de error está después de la descripción. La cadena traducida se vería como %2$s oru %1$d./n Ahora, ¿cómo hacerlo en C ++? Bueno, no tengo ni idea. Supongo que puedes hacer iostream falso que construye printf que puedes pasar a gettext , o algo así, para propósitos de traducción. Por supuesto, $ no es un estándar de C, pero es tan común que es seguro de usar en mi opinión.

No tener que recordar / buscar sintaxis de tipo entero específico

C tiene muchos tipos de enteros, y también C ++. std::cout maneja todos los tipos por usted, mientras que printf requiere una sintaxis específica dependiendo de un tipo entero (hay tipos no enteros, pero el único tipo no entero que usará en la práctica con printf es const char * (cadena C, Puede obtenerse usando el método to_c de std::string )). Por ejemplo, para imprimir size_t , necesita usar %zd , mientras que int64_t requerirá usar %"PRId64" . Las tablas están disponibles en printf() y http://en.cppreference.com/w/cpp/types/integer .

No puede imprimir el byte NUL, /0

Como printf usa cadenas C en lugar de cadenas C ++, no puede imprimir el byte NUL sin trucos específicos. En ciertos casos, es posible usar %c con ''/0'' como argumento, aunque eso es claramente un hack.

Las diferencias que a nadie le importan.

Actuación

Actualización: Resulta que iostream es tan lento que generalmente es más lento que su disco duro (si redirige su programa a un archivo). Desactivar la sincronización con stdio puede ayudar, si necesita generar una gran cantidad de datos. Si el rendimiento es una preocupación real (en lugar de escribir varias líneas en STDOUT), simplemente use printf .

Todos piensan que les importa el rendimiento, pero nadie se molesta en medirlo. Mi respuesta es que I / O es un cuello de botella de todos modos, no importa si usa printf o iostream . Pienso que printf podría ser más rápido con un vistazo rápido al ensamblaje (compilado con un sonido metálico usando la opción del compilador -O3 ). Suponiendo que mi ejemplo de error, el ejemplo de printf hace menos llamadas que el ejemplo cout . Esto es int main con printf :

main: @ @main @ BB#0: push {lr} ldr r0, .LCPI0_0 ldr r2, .LCPI0_1 mov r1, #2 bl printf mov r0, #0 pop {lr} mov pc, lr .align 2 @ BB#1:

Puede observar fácilmente que dos cadenas y 2 (número) se insertan como argumentos de printf . Eso es todo; no hay nada más. Para comparación, esto es iostream compilado para ensamblar. No, no hay en línea; cada operator << llamada significa otra llamada con otro conjunto de argumentos.

main: @ @main @ BB#0: push {r4, r5, lr} ldr r4, .LCPI0_0 ldr r1, .LCPI0_1 mov r2, #6 mov r3, #0 mov r0, r4 bl _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l mov r0, r4 mov r1, #2 bl _ZNSolsEi ldr r1, .LCPI0_2 mov r2, #2 mov r3, #0 mov r4, r0 bl _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l ldr r1, .LCPI0_3 mov r0, r4 mov r2, #14 mov r3, #0 bl _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l ldr r1, .LCPI0_4 mov r0, r4 mov r2, #1 mov r3, #0 bl _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l ldr r0, [r4] sub r0, r0, #24 ldr r0, [r0] add r0, r0, r4 ldr r5, [r0, #240] cmp r5, #0 beq .LBB0_5 @ BB#1: @ %_ZSt13__check_facetISt5ctypeIcEERKT_PS3_.exit ldrb r0, [r5, #28] cmp r0, #0 beq .LBB0_3 @ BB#2: ldrb r0, [r5, #39] b .LBB0_4 .LBB0_3: mov r0, r5 bl _ZNKSt5ctypeIcE13_M_widen_initEv ldr r0, [r5] mov r1, #10 ldr r2, [r0, #24] mov r0, r5 mov lr, pc mov pc, r2 .LBB0_4: @ %_ZNKSt5ctypeIcE5widenEc.exit lsl r0, r0, #24 asr r1, r0, #24 mov r0, r4 bl _ZNSo3putEc bl _ZNSo5flushEv mov r0, #0 pop {r4, r5, lr} mov pc, lr .LBB0_5: bl _ZSt16__throw_bad_castv .align 2 @ BB#6:

Sin embargo, para ser honesto, esto no significa nada, ya que I / O es el cuello de botella de todos modos. Solo quería mostrar que iostream no es más rápido porque es "de tipo seguro". La mayoría de las implementaciones de C implementan formatos de printf usando goto computado, por lo que printf es tan rápido como puede ser, incluso sin que el compilador tenga conocimiento de printf (no es que no lo sean, algunos compiladores pueden optimizar printf en ciertos casos, cadena constante que termina con /n se suele optimizar para puts ).

Herencia

No sé por qué querría heredar ostream , pero no me importa. Es posible con FILE también.

class MyFile : public FILE {}

Tipo de seguridad

Es cierto que las listas de argumentos de longitud variable no tienen seguridad, pero eso no importa, ya que los compiladores de C populares pueden detectar problemas con la printf formato printf si habilitas las advertencias. De hecho, Clang puede hacer eso sin habilitar advertencias.

$ cat safety.c #include <stdio.h> int main(void) { printf("String: %s/n", 42); return 0; } $ clang safety.c safety.c:4:28: warning: format specifies type ''char *'' but the argument has type ''int'' [-Wformat] printf("String: %s/n", 42); ~~ ^~ %d 1 warning generated. $ gcc -Wall safety.c safety.c: In function ‘main’: safety.c:4:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=] printf("String: %s/n", 42); ^


Para mí, las diferencias reales que me harían ir por ''cout'' en lugar de ''printf'' son:

1) << operador puede ser sobrecargado para mis clases.

2) La secuencia de salida para cout se puede cambiar fácilmente a un archivo: (: copiar pegar :)

#include <iostream> #include <fstream> using namespace std; int main () { cout << "This is sent to prompt" << endl; ofstream file; file.open ("test.txt"); streambuf* sbuf = cout.rdbuf(); cout.rdbuf(file.rdbuf()); cout << "This is sent to file" << endl; cout.rdbuf(sbuf); cout << "This is also sent to prompt" << endl; return 0; }

3) Encuentro que el cout es más legible, especialmente cuando tenemos muchos parámetros.

Un problema con cout es las opciones de formato. Formatear los datos (precisión, justificación, etc.) en printf es más fácil.


Por supuesto, puedes escribir "algo" un poco mejor para mantener el mantenimiento:

#include <iostream> #include <cstdlib> using namespace std; class Something { public: Something(int x, int y, int z) : a(x), b(y), c(z) { } int a; int b; int c; friend ostream& operator<<(ostream&, const Something&); void print() const { printf("%i, %i, %i/n", a, b, c); } }; ostream& operator<<(ostream& o, const Something& s) { o << s.a << ", " << s.b << ", " << s.c; return o; } int main(void) { Something s(3, 2, 1); // Output with printf s.print(); // Simple as well, isn''t it? // Output with cout cout << s << endl; return 0; }

Y un poco de prueba extendida de cout vs. printf, agregó una prueba de ''doble'', si alguien quiere hacer más pruebas (Visual Studio 2008, versión de lanzamiento del ejecutable):

#include <stdio.h> #include <iostream> #include <ctime> class TimedSection { char const *d_name; //timespec d_start; clock_t d_start; public: TimedSection(char const *name) : d_name(name) { //clock_gettime(CLOCK_REALTIME, &d_start); d_start = clock(); } ~TimedSection() { clock_t end; //clock_gettime(CLOCK_REALTIME, &end); end = clock(); double duration = /*1e3 * (end.tv_sec - d_start.tv_sec) + 1e-6 * (end.tv_nsec - d_start.tv_nsec); */ (double) (end - d_start) / CLOCKS_PER_SEC; std::cerr << d_name << ''/t'' << std::fixed << duration * 1000.0 << " ms/n"; } }; int main() { const int iters = 1000000; char const *text = "01234567890123456789"; { TimedSection s("cout with only endl"); for (int i = 0; i < iters; ++i) std::cout << std::endl; } { TimedSection s("cout with only ''//n''"); for (int i = 0; i < iters; ++i) std::cout << ''/n''; } { TimedSection s("printf with only ''//n''"); for (int i = 0; i < iters; ++i) printf("/n"); } { TimedSection s("cout with string constant and endl"); for (int i = 0; i < iters; ++i) std::cout << "01234567890123456789" << std::endl; } { TimedSection s("cout with string constant and ''//n''"); for (int i = 0; i < iters; ++i) std::cout << "01234567890123456789/n"; } { TimedSection s("printf with string constant and ''//n''"); for (int i = 0; i < iters; ++i) printf("01234567890123456789/n"); } { TimedSection s("cout with some stuff and endl"); for (int i = 0; i < iters; ++i) std::cout << text << "01234567890123456789" << i << std::endl; } { TimedSection s("cout with some stuff and ''//n''"); for (int i = 0; i < iters; ++i) std::cout << text << "01234567890123456789" << i << ''/n''; } { TimedSection s("printf with some stuff and ''//n''"); for (int i = 0; i < iters; ++i) printf("%s01234567890123456789%i/n", text, i); } { TimedSection s("cout with formatted double (width & precision once)"); std::cout << std::fixed << std::scientific << std::right << std::showpoint; std::cout.width(8); for (int i = 0; i < iters; ++i) std::cout << text << 8.315 << i << ''/n''; } { TimedSection s("cout with formatted double (width & precision on each call)"); std::cout << std::fixed << std::scientific << std::right << std::showpoint; for (int i = 0; i < iters; ++i) { std::cout.width(8); std::cout.precision(3); std::cout << text << 8.315 << i << ''/n''; } } { TimedSection s("printf with formatted double"); for (int i = 0; i < iters; ++i) printf("%8.3f%i/n", 8.315, i); } }

El resultado es:

cout with only endl 6453.000000 ms cout with only ''/n'' 125.000000 ms printf with only ''/n'' 156.000000 ms cout with string constant and endl 6937.000000 ms cout with string constant and ''/n'' 1391.000000 ms printf with string constant and ''/n'' 3391.000000 ms cout with some stuff and endl 9672.000000 ms cout with some stuff and ''/n'' 7296.000000 ms printf with some stuff and ''/n'' 12235.000000 ms cout with formatted double (width & precision once) 7906.000000 ms cout with formatted double (width & precision on each call) 9141.000000 ms printf with formatted double 3312.000000 ms


Una es una función que imprime a la salida estándar. El otro es un objeto que proporciona varias funciones miembro y sobrecargas del operator<< que imprimen a la salida estándar. Podría enumerar muchas más diferencias, pero no estoy seguro de lo que está buscando.


Y quote :

En términos de alto nivel, las principales diferencias son la seguridad de tipo (cstdio no lo tiene), el rendimiento (la mayoría de las implementaciones de iostreams son más lentas que las de cstdio) y la extensibilidad (iostreams permite objetivos de salida personalizados y salida sin problemas de los tipos definidos por el usuario).


printfEs una función mientras que coutes una variable.


Más diferencias: "printf" devuelve un valor entero (igual al número de caracteres impresos) y "cout" no devuelve nada

Y.

cout << "y = " << 7; No es atómico.

printf("%s = %d", "y", 7); es atómico

cout realiza verificación de tipos, printf no lo hace.

No hay iostream equivalente de "% d"


No soy programador, pero he sido ingeniero de factores humanos. Creo que un lenguaje de programación debería ser fácil de aprender, entender y usar, y esto requiere que tenga una estructura lingüística simple y consistente. Aunque todos los idiomas son simbólicos y, por lo tanto, en su núcleo, arbitrarios, existen convenciones y seguirlas facilita el aprendizaje y el uso del idioma.

Hay una gran cantidad de funciones en C ++ y otros lenguajes escritos como función (parámetro), una sintaxis que se usó originalmente para las relaciones funcionales en matemáticas en la era pre-computacional. printf()sigue esta sintaxis y si los escritores de C ++ quisieran crear un método lógicamente diferente para leer y escribir archivos, simplemente podrían haber creado una función diferente utilizando una sintaxis similar.

En Python, por supuesto, podemos imprimir utilizando la object.methodsintaxis también bastante estándar , es decir, nombre de archivo variable, ya que las variables son objetos, pero en C ++ no lo son.

No me gusta la sintaxis de cout porque el operador << no sigue ninguna regla. Es un método o función, es decir, toma un parámetro y le hace algo. Sin embargo, está escrito como si fuera un operador de comparación matemático. Este es un enfoque pobre desde el punto de vista de los factores humanos.


TL; DR: Siempre realice su propia investigación, con respecto al tamaño del código de la máquina , el rendimiento , la legibilidad y el tiempo de codificación generados antes de confiar en los comentarios aleatorios en línea, incluido este.

No soy un experto. Acabo de escuchar a dos compañeros de trabajo que hablan sobre cómo deberíamos evitar el uso de C ++ en sistemas integrados debido a problemas de rendimiento. Bueno, lo suficientemente interesante, hice un punto de referencia basado en una tarea de proyecto real.

En dicha tarea, tuvimos que escribir alguna configuración en la memoria RAM. Algo como:

café =
azúcar caliente = ninguna
leche = mama
mac = AA: BB: CC: DD: EE: FF

Aquí están mis programas de referencia (Sí, sé que OP preguntó acerca de printf (), no fprintf (). Intente capturar la esencia y, por cierto, el enlace de OP apunta a fprintf () de todos modos).

Programa C:

char coffee[10], sugar[10], milk[10]; unsigned char mac[6]; /* Initialize those things here. */ FILE * f = fopen("a.txt", "wt"); fprintf(f, "coffee=%s/nsugar=%s/nmilk=%s/nmac=%02X:%02X:%02X:%02X:%02X:%02X/n", coffee, sugar, milk, mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]); fclose(f);

Programa de C ++:

//Everything else is identical except: std::ofstream f("a.txt", std::ios::out); f << "coffee=" << coffee << "/n"; f << "sugar=" << sugar << "/n"; f << "milk=" << milk << "/n"; f << "mac=" << (int)mac[0] << ":" << (int)mac[1] << ":" << (int)mac[2] << ":" << (int)mac[3] << ":" << (int)mac[4] << ":" << (int)mac[5] << endl; f.close();

Hice lo mejor que pude para pulirlos antes de enlazarlos 100,000 veces. Aquí están los resultados:

Programa C:

real 0m 8.01s user 0m 2.37s sys 0m 5.58s

Programa de C ++:

real 0m 6.07s user 0m 3.18s sys 0m 2.84s

Tamaño del archivo objeto:

C - 2,092 bytes C++ - 3,272 bytes

Conclusión: en mi plataforma muy específica , con un procesador muy específico , ejecutando una versión muy específica del kernel de Linux , para ejecutar un programa que se compila con una versión muy específica de GCC , para cumplir una tarea muy específica , diría El enfoque de C ++ es más adecuado porque se ejecuta significativamente más rápido y proporciona una mejor legibilidad. Por otro lado, C ofrece una huella pequeña, en mi opinión, significa casi nada porque el tamaño del programa no es de nuestra incumbencia.

Recuerda, YMMV.


cout<< "Hello"; printf("%s", "Hello");

Ambos se utilizan para imprimir valores. Tienen una sintaxis completamente diferente. C ++ tiene ambos, C solo tiene printf.