"%f" is the (or at least one) correct format for a double. There is no format for a
float, because if you attempt to pass a
printf, it’ll be promoted to
printf receives it1.
"%lf" is also acceptable under the current standard — the
l is specified as having no effect if followed by the
f conversion specifier (among others).
Note that this is one place that
printf format strings differ substantially from
fscanf, etc.) format strings. For output, you’re passing a value, which will be promoted from
double when passed as a variadic parameter. For input you’re passing a pointer, which is not promoted, so you have to tell
scanf whether you want to read a
float or a
double, so for
%f means you want to read a
%lf means you want to read a
double (and, for what it’s worth, for a
long double, you use
%Lf for either
1. C99, §126.96.36.199/6: “If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.” In C++ the wording is somewhat different (e.g., it doesn’t use the word “prototype”) but the effect is the same: all the variadic parameters undergo default promotions before they’re received by the function.