Question:
When you want to print a value of type float
or double
using the printf()
function, you use the %f
specifier for both data types. For example:
double d = 3.5;
float f = 4.5;
printf("Valores: %f %f", f, d);
Whereas in the case of the scanf()
, the %f
specifier is used to read a float
and the %lf
specifier is used to read a double
:
double d;
float f;
printf("Introduce un float y un double: ");
scanf("%f %lf", &f, &d);
Why are there different specifiers for float
and double
types in scanf()
, but the same specifier in printf()
?
Answer:
The C language performs an implicit conversion from float
to double
when a float
type value is passed as an argument to a function with a variable number of arguments , as in the case of the printf()
function. Therefore, whether passing a float
value or passing a double
, the printf()
function receives a double
value, the %f
specifier being set to print double
values in printf()
In the case of scanf()
, values ( float
or double
type) are not passed as arguments, but rather pointers are passed with the memory addresses where to store the read values. Pointers are not implicitly converted by C, in addition to the fact that the scanf()
must know what type of data is each of the variables where each read value is going to be stored, so as not to occupy larger memory areas than those reserved or not to save incorrectly formatted data to the corresponding variable. Therefore, a specific specifier is necessary for each variable with its corresponding data type.
Since the C99 standard, a specific specifier is established for each floating point data type, both for printf()
and scanf()
:
%f
forfloat
%lf
fordouble
%Lf
forlong double
By using the printf()
function with the %f
specifier, you can still safely use arguments of type float
or double
. Furthermore, it makes no difference to use %f
or %lf
with values of type float
or double
. In all possible combinations between them, printf()
implicitly converts to double
and prints it as such. But using the specifier %lf
with float
values or %f
with double
values is considered bad practice and should be avoided, even if it doesn't initially cause problems.
To write this solution, much of the information from the English SO entry has been used: https://stackoverflow.com/questions/210590/why-does-scanf-need-lf-for-doubles-when-printf -is-okay-with-just-f