Then - as it is in the comments: these functions printf
and scanf
do not have how to know what type of argument you are passing them from the declared type of the variable.
They only "guess" what type of data was passed, or what they should copy to the variable (in the case of scanf), just from the formatting string.
Then when you, in case 3, say to the printf
that will pass a number of type float, it will get the corresponding bytes from the parameter stack and treats 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 a 4-byte integer.
In the same way for double, when using scanf
you have to say if the variable you are going to 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 bytes corresponding to a float . For scanf
to work with a double
, you must use the l
modifier in the format: %lf
, %le
, %lg
.
What confuses you is that the compiler itself, because of the specification of the C language will always transform a float
in%% automatically when a variable parameter function is called.
So actually the% w / w (% w / w) in printf will always handle doubles (and use 8 bytes of the argument stack) even if you write in your code that you are passing a float. (and yes, the codes are therefore different from those used by double
).
In C you need to understand well how different types of data are represented in memory, and there can not even be an error. For example, if instead of the examples you passed, you tried to print a %f
variable using %e
formatting, your program could end up with a segmentation fault - since scanf
will want to consume 8 argument bytes where there are only 4. In dynamic languages with a higher abstraction level such as Javascript, Python, PHP, and Ruby, these exact conversion problems from the data to its internal representation are usually 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. : -)