¿Por qué scanf()necesita el l" %lf" cuando lee un double, cuándo printf()puede usar " %f" independientemente de si su argumento es a doubleo a float?
Código de ejemplo:
double d;
scanf("%lf", &d);
printf("%f", d);
c
scanf
length-modifiers
raldi
fuente
fuente

&operador unario , el resultado de esa operación es un puntero a la ubicación de almacenamiento de la variable en la memoria. Es ese puntero al que se pasascanf.Respuestas:
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,%lgo%le(o%laen C99) para leer en dobles.fuente
Desde С99, la coincidencia entre los especificadores de formato y los tipos de argumento de coma flotante en C es consistente entre
printfyscanf. Es%fparafloat%lfparadouble%Lfparalong doubleSucede que cuando los argumentos de tipo
floatse pasan como parámetros variables, dichos argumentos se convierten implícitamente en tipodouble. Esta es la razón por la cual enprintflos especificadores de formato%fy%lfson equivalentes e intercambiables. Enprintfusted puede "uso cruzado"%lfconfloato%fcondouble.Pero no hay razón para hacerlo en la práctica. No utilice
%faprintfargumentos de tipodouble. Es un hábito generalizado nacido en C89/90 veces, pero es un mal hábito. Uso%lfenprintfparadoubley mantenga%freservada parafloatlos argumentos.fuente
%fen printf es un buen hábito porque su código siempre funciona, mientras que usarlo%lfpuede fallar si el compilador no tiene una biblioteca compatible con C99. Lamentablemente, esa situación sucede en la realidad.printfyscanf. Tenga en cuenta que esto no implica que el uso del mismo especificador de formato signifique que los datos escritos por a[f]printf()puedan ser leídos[f]scanf(). En general, el uso de la misma para el especificador de formatoscanf()que se utilizó porprintf()lo que no lea correctamente los datos. Por ejemplo, el relleno del espacio que puede ser insertado por unprinf()'s"%d"especificador de formato se omitirá por el mismo"%d"especificador de formato en unascanf()llamada.scanfnecesita saber el tamaño de los datos a los que apunta&dpara llenarlos correctamente, mientras que las funciones variadas promueven flotantes a dobles (no del todo seguro por qué), porprintflo que siempre se obtiene undouble.fuente
Porque, de lo contrario, scanf pensará que está pasando un puntero a un flotante que tiene un tamaño menor que el doble, y devolverá un valor incorrecto.
fuente
El uso de un valor flotante o doble en una expresión en C dará como resultado un valor que sea 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 a diferencia de un puntero para flotar, porque lo que apunta el puntero es lo que importa.
fuente
floatvalores se promocionaban automáticamentedoubleen expresiones. Esa regla se abandonó en el estándar C. Generalmente,floatno se promuevedoubleen expresiones. Solo se promuevedoublecuando se pasa como un argumento variado, que es lo que sucede en este caso.