When you want to print a value of type float
or double
using the function printf()
, you use the specifier %f
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 function scanf()
, the specifier is used %f
to read a float
and the specifier %lf
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 the types float
and double
in scanf()
, but the same specifier in printf()
?
The C language performs an implicit conversion from
float
todouble
when a type value is passed as an argumentfloat
to a function with a variable number of arguments , as in the case of functionprintf()
. Thus, whether passing a valuefloat
or passing adouble
, the functionprintf()
receives a valuedouble
, the specifier being set%f
to print type valuesdouble
toprintf()
In the case of
scanf()
values (typefloat
ordouble
) 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 functionscanf()
must know what type of data is each of the variables where each read value is going to be saved, so as not to occupy memory areas larger than those reserved or not to save data with a incorrect format 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 forscanf()
:Using the function
printf()
with the specifier%f
can still safely use arguments of typefloat
ordouble
. Furthermore, it makes no difference to use%f
or%lf
with values of typefloat
ordouble
. In all possible combinations between them,printf()
it implicitly converts todouble
and prints it as such. But using the specifier%lf
with valuesfloat
or%f
with valuesdouble
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