¿Por qué scanf() necesita “%lf” para dobles, cuando printf() está bien con solo “%f”?

5 minutos de lectura

avatar de usuario
raldi

Por qué es eso scanf() necesita el l en “%lf“al leer un doublecuando printf() puedo usar “%findependientemente de si su argumento es un double o un float?

Código de ejemplo:

double d;
scanf("%lf", &d);
printf("%f", d);

  • No entiendo lo que quieres decir con PUNTERO aquí. En scanf solo pasamos &variable (es decir)dirección, entonces, ¿dónde está el puntero?

    usuario1461834

    17 de junio de 2012 a las 13:04

  • @deetchanya En C, cuando “tomas la dirección de” una variable con el unario & operador, el resultado de esa operación es un puntero a la ubicación de almacenamiento de la variable en la memoria. Es ese puntero que se pasa a scanf.

    – zwol

    27 de junio de 2013 a las 23:03


  • esta es otra publicación sobre este stackoverflow.com/questions/9291348/…

    – vimalpt

    22 de septiembre de 2014 a las 10:03


avatar de usuario
MSN

Porque C promoverá flotantes a dobles para funciones que toman argumentos variables. Los punteros no se promocionan a nada, por lo que debería usar %lf, %lg o %le (o %la en C99) para leer en dobles.

avatar de usuario
Hormiga

Desde С99, la coincidencia entre los especificadores de formato y los tipos de argumentos de punto flotante en C es consistente entre printf y scanf. Está

  • %f por float
  • %lf por double
  • %Lf por long double

Sucede que cuando los argumentos de tipo float se pasan como parámetros variádicos, dichos argumentos se convierten implícitamente al tipo double. Esta es la razón por la que en printf especificadores de formato %f y %lf son equivalentes e intercambiables. En printf puede “uso cruzado” %lf con float o %f con double.

Pero no hay razón para hacerlo en la práctica. no usar %f para printf argumentos de tipo double. Es una costumbre muy extendida que nace en tiempos del C89/90, pero es una mala costumbre. Usar %lf en printf por double y mantener %f reservado para float argumentos

  • Yo diría que usando %f en printf es un buen hábito porque entonces su código siempre funciona, mientras que usar %lf puede fallar si el compilador no tiene una biblioteca compatible con C99. Desafortunadamente esa situación sucede en la realidad.

    –MM

    22 de mayo de 2016 a las 4:39

  • Desde С99, la coincidencia entre los especificadores de formato y los tipos de argumentos de punto flotante en C es consistente entre printf y scanf. Tenga en cuenta que esto no implica que usar el mismo especificador de formato signifique que los datos escritos por un [f]printf() puede ser leído por [f]scanf(). En general, usando el mismo especificador de formato para scanf() que fue usado por printf() será no leer con éxito los datos. Por ejemplo, el espacio de relleno que puede ser insertado por un prinf()‘s "%d" el especificador de formato será omitido por ese mismo "%d" especificador de formato en un scanf() llamar.

    –Andrew Henle

    14/07/2018 a las 18:02

avatar de usuario
tanquetalus

scanf necesita saber el tamaño de los datos señalados por &d para llenarlo correctamente, mientras que las funciones variádicas promueven flotantes a dobles (no estoy completamente seguro de por qué), por lo que printf siempre está recibiendo un double.

  • Una función variádica es muy frágil, porque necesita saber el tipo y tamaño exactos de todos los parámetros que se le pasan, y no puede imponer esto en tiempo de compilación. Si una variable es del tipo incorrecto, se leerá el valor incorrecto; si tiene el tamaño incorrecto, todas las variables posteriores también se leerán mal. Si se pudieran pasar dos tamaños diferentes de flotador, esto causaría todo tipo de problemas desagradables y fáciles de pasar por alto.

    – mwfearnley

    5 de noviembre de 2016 a las 12:54

Porque de lo contrario, scanf pensará que está pasando un puntero a un flotador que tiene un tamaño más pequeño que un doble, y devolverá un valor incorrecto.

El uso de un valor flotante o doble en una expresión C dará como resultado un valor doble de todos modos, por lo que printf no puede notar la diferencia. Mientras que un puntero a un doble debe señalarse explícitamente para scanf a diferencia de un puntero para flotar, porque lo que el puntero apunta es lo que importa.

  • float se convierte en un doble en este caso debido a que los argumentos son parte de una lista de argumentos de longitud variable, los flotantes no siempre se convierten en dobles en C.

    – Roberto Gamble

    16 de octubre de 2008 a las 23:19

  • En versiones pre-estándar de lenguaje C float los valores se promovieron automáticamente a double en expresiones. Esa regla fue abandonada en el estándar C. Generalmente, float no es ascendido a double en expresiones. Solo se promociona a double cuando se pasa como un argumento variádico, que es lo que sucede en este caso.

    – Ant

    29/01/2015 a las 19:00


  • float se convierte en un doble en este caso debido a que los argumentos son parte de una lista de argumentos de longitud variable, los flotantes no siempre se convierten en dobles en C.

    – Roberto Gamble

    16 de octubre de 2008 a las 23:19

  • En versiones pre-estándar de lenguaje C float los valores se promovieron automáticamente a double en expresiones. Esa regla fue abandonada en el estándar C. Generalmente, float no es ascendido a double en expresiones. Solo se promociona a double cuando se pasa como un argumento variádico, que es lo que sucede en este caso.

    – Ant

    29/01/2015 a las 19:00


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad