utiliza son salida que programacion pedir para leer las funciones entrada datos cuáles caracteres c++ c floating-point printf cout

son - pedir datos en c++



¿Por qué esta salida de la misma expresión de printf difiere de cout? (9)

A la función C se le está pasando un número entero, pero usted le está diciendo (con %f ) que espere un número de punto flotante de doble precisión, por lo que falla. La función C ++ sabe que se está pasando un entero, por lo que funciona correctamente.

Estoy usando Visual C ++ 2012 y compilando desde la línea de comandos los siguientes archivos:

#include <stdio.h> int main() { printf("%.5f", 18/4+18%4); return 0; }

Enlace con MSVCRT.LIB en lugar de LIBCMT para evitar el error de tiempo de ejecución R6002.
El valor que se genera es 0.00000 para este programa.

Sin embargo, si realizo exactamente lo mismo en C ++

#include <iostream> using namespace std; int main() { cout << 18/4+18%4 << endl; return 0; }

Ahora, imprime 6, como debería.

¿Cual es la diferencia? ¿Tiene que ver con los propios lenguajes (C vs C ++) o los métodos de salida (cout vs printf), o es solo una peculiaridad con MSVC?


En C porque especifica explícitamente el punto flotante ("% f") en su especificador de formato de printf, por lo que está esperando un argumento de punto flotante. Pero le estás dando un argumento "int", de ahí el problema.

Dependiendo de lo que estés tratando de hacer, puedes:

1) Convertir su expresión (de lo contrario entero ) para flotar

y / o

2) Usar setprecision en su flujo de cout, tal como usaría "% .5f" en C:

#include <iostream> using namespace std; int main() { float x = 18/4+18%4; std::cout << std::setprecision(5) << x << endl; return 0; }

3) Si desea un entero, use printf ("%d", 18/4+18%4);


En el ejemplo de C, esta expresión 18/4+18%4 se evaluará como un int, ya que todos los operandos son constantes de enteros, pero está especificando que es doble para printf y, por lo tanto, se procesará incorrectamente. Por otro lado, si hubiera usado una constante flotante en la parte de la división de la expresión, por ejemplo, 18.0/4+18%4 la expresión completa se habría evaluado a un doble . Alternativamente, también podría haber usado "%d" en el especificador de formato.

Este también es un comportamiento indefinido para especificar incorrectamente el formato de printf y también demuestra por qué es importante construir con advertencias, usando gcc -Wall . Recibirá la siguiente advertencia ( gcc -Wall en live ):

warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’

En C ++ std::cout ''s operator<< tiene una sobrecarga para int y, por lo tanto, se llamará en este caso. Podemos ver esta sobrecarga y muchos otros son requeridos por el borrador de la norma C ++ , en la sección 27.7.3.1 Plantilla de clase basic_ostream encontramos la siguiente declaración del operador:

basic_ostream<charT,traits>& operator<<(int n);

Para completar, volviendo al comportamiento indefinido, el borrador del estándar C99 en la sección 7.19.6.1 La función fprintf a la que se refiere la sección de printf se refiere al párrafo 9 de la cadena de formato, dice:

Si una especificación de conversión no es válida, el comportamiento no está definido. [...]


Haz que uno de tus números sea un valor de punto flotante:

#include <stdio.h> int main() { printf("%.0f", 18/4.0+18%4); return 0; }


La expresión 18/4+18%4 evalúa como un int , y está solicitando un flotante. Siempre debe compilar con las advertencias habilitadas, y prestarles atención (dicen que una advertencia es un error que espera que suceda , y tienen razón).

Esto es lo que mi compilador (GCC 4.8.1) me dice (e incluso sin imponer -Wall ):

warning: format ‘%.5f’ expects type ‘double’, but argument 2 has type ‘int’

Por otro lado, la operación std::cout<< puede deducir el tipo de su expresión y transmitirla correctamente a su pantalla.


La expresion

18 / 4 + 18 % 4

Evalúa a un int .

Pero la cadena de formato printf "% .5f" espera un doble.

Con c ++ y ostreams, el idioma puede determinar el tipo de salida automáticamente.

Solo cambia tu código C a lo siguiente:

#include <stdio.h> int main() { printf("%d", 18 / 4 + 18 % 4); return 0; }


Otros han señalado correctamente la falta de coincidencia de int / double en su declaración printf (). Solo quiero comentar sobre su declaración, "Vinculación con MSVCRT.LIB en lugar de LIBCMT para evitar el error de tiempo de ejecución R6002". Un programa tan simple como este no debería gravar indebidamente el entorno de ejecución, por lo que un error de tiempo de ejecución como este debería ser un indicador de comportamiento indefinido en su código.

Un rápido Google de "MSVCRT R6002" dice:

C Error en tiempo de ejecución R6002 soporte de punto flotante no cargado

La biblioteca de punto flotante necesaria no estaba vinculada. Para solucionarlo comprobando las siguientes causas posibles

  1. El programa se compiló o se vinculó con una opción, como / FPi87, que requiere un coprocesador, pero el programa se ejecutó en una máquina que no tenía un coprocesador instalado.
  2. Una cadena de formato para una función printf_s o scanf_s contenía una especificación de formato de punto flotante y el programa no contenía valores ni variables de punto flotante.
  3. El compilador minimiza el tamaño de un programa al cargar el soporte de punto flotante solo cuando es necesario. El compilador no puede detectar especificaciones de formato de punto flotante en cadenas de formato, por lo que no carga las rutinas de punto flotante necesarias.
  4. Utilice un argumento de punto flotante para corresponder a la especificación de formato de punto flotante, o realice una asignación de punto flotante en otra parte del programa. Esto hace que se cargue el soporte de punto flotante.
  5. En un programa de lenguaje mixto, se especificó una biblioteca C antes de una biblioteca FORTRAN cuando se vinculó el programa. Vuelva a vincular y especifique la biblioteca C en último lugar.

La lección aquí, por supuesto, es que debe prestar mucha atención a las advertencias y errores del compilador y del tiempo de ejecución. En caso de duda, siempre asuma que el problema está en su código, no en el compilador.


Si quieres el mismo comportamiento (y respuesta) es mejor que codifiques

printf("%d/n", 18/4 + 18%4);

para obtener una respuesta int en lugar de un punto flotante. Obtendrá el mismo resultado que << operador seleccionado es

ostream& std::operator<<(ostream&, const int);

De lo contrario, puede utilizar explícitamente

printf("%.5f/n", (double)(18/4 + 18%4));

para obtener 6.00000 resultado.


Una posible alternativa es encasillar los literales (o la expresión en sí):

#include <stdio.h> int main(void) { printf("%.5f", (float)18/4+18%4); return 0; }