leer - scanf int
¿Por qué scanf() necesita "% lf" para dobles, cuando printf() está bien con solo "% f"? (5)
¿Por qué es que scanf()
necesita el l
en " %lf
" cuando lee un double
, cuando printf()
puede usar " %f
" independientemente de si su argumento es double
o float
?
Código de ejemplo:
double d;
scanf("%lf", &d);
printf("%f", d);
Desde 1999, la coincidencia entre los especificadores de formato y los tipos de argumento de coma flotante en C es coherente entre printf
y scanf
. Es
-
%f
parafloat
-
%lf
para eldouble
-
%Lf
porlong double
Sucede que cuando los argumentos de tipo float
se pasan como parámetros variadic, dichos argumentos se convierten implícitamente a type double
. Esta es la razón por la cual en los especificadores de formato printf
%f
y %lf
son equivalentes e intercambiables. En printf
puede "usar de forma cruzada" %lf
con float
o %f
con double
.
Pero no hay razón para hacerlo en la práctica. No use %f
para printf
argumentos de tipo double
. Es un hábito generalizado que nació en C89 / 90 veces, pero es un mal hábito. Use %lf
en printf
para double
y mantenga %f
reservado para argumentos float
.
El uso de un flotador o un valor doble en una expresión C dará como resultado un valor que es doble de todos modos, por lo que printf no puede notar la diferencia. Mientras que un puntero a un doble tiene que ser señalado explícitamente para scanf como distinto de un puntero para flotar, porque lo que el puntero apunta es lo que importa.
Porque C promoverá flotantes a dobles para funciones que toman argumentos variables. Los punteros no se promocionan a nada, por lo que debe usar %lf
, %lg
o %le
(o %la
en C99) para leer en dobles.
Porque de lo contrario, scanf pensará que está pasando un puntero a un flotador que es un tamaño más pequeño que un doble, y devolverá un valor incorrecto.
scanf
necesita saber el tamaño de los datos señalados por &d
para llenarlo correctamente, mientras que las funciones variadas promueven los flotantes a los dobles (no del todo seguro por qué), por lo que printf
siempre obtiene un double
.