So - as it is in the comments: these functions printf
and scanf
has not how to know what type of argument you are passing to them from the declared type of the variable.
They just "guess" what kind of data was passed, or what they should copy to the variable (in the case of scanf), from precisely the formatting string.
So when you, in case 3, say to the printf
that will pass a float type number, it will take the corresponding bytes of the parameter stack and treat them as a double. (See below for a double and not a float). And the internal values of these bytes are very different for a float and an integer of 4 bytes.
The same way for the double, when using the scanf
you have to say if the variable you will fill is a "double" or a "float" - the second case uses the formats %f
, %e
or %g
but always fills only 4 bytes in target memory with the bytes corresponding to a float. To the scanf
work with a double
, it is necessary to use the modifier l
in format: %lf
, %le
, %lg
.
What confuses is that the compiler itself, due to the specification of the C language will always turn a float
in a double
automatically when a variable parameter function is called.
So in fact the %f
(and %e
) in the printf will always handle doubles (and use 8 bytes of argument stack), even if in your code you write that you are passing a float. (and yes, the codes are therefore different from those used by scanf
).
In C it is necessary to understand well how the different types of data are represented in memory, and there can be even an error. For example, if instead of the examples you passed, you tried to print a variable int
using the formatting %f
, your program could end with a segmentation failure - since the printf
will want to consume 8 bytes of argument where there is only 4. In dynamic languages with a higher abstraction level such as Javascript, Python, PHP and Ruby, these exact data conversion problems for your internal representation in general are handled by the language itself. Other static languages like C#, go, Java, etc... will have better mechanisms to detect this type of problem at the time of compilation. But in C, it’s just you and the CPU. :-)
The
scanf
fordouble
is not using%f
and family, but%lf
and family– Jefferson Quesado
Over two and three, there is no coercion of type, neither from floating point to integer nor the other way around, so the value will be quite chaotic, because the
printf
will interpret the past bytes as being of another type– Jefferson Quesado
And to complement what @Jeffersonquesado said a double/float has the exponent stored in the bits of higher weight (usually 8) soon and most of the values are quantified to zero because they do not generate information until these bits
– Isac