floats
автоматически повышаются до doubles
, когда передаются как ...
параметры (аналогично тому, как chars
и short ints
повышаются до ints
). Когда printf()
просматривает спецификатор формата (%d
или %f
или что-то еще), он захватывает и интерпретирует необработанные данные, которые он получил, в соответствии со спецификатором формата (как int
или double
или что-то еще), а затем печатает его.
printf("%d\n",x)
неправильно, потому что вы передаете double
на printf()
, но лгите ему, что это будет int
. printf()
заставляет вас платить за ложь. Он берет 4 байта (скорее всего, но не обязательно 4 байта) из своих параметров, который имеет размер int
, он захватывает те байты, откуда вы ранее положили 8 байтов (опять же, скорее всего, но не обязательно 8) байт) из double
4.0, из которых эти 4 байта оказываются всеми нулями, а затем он интерпретирует их как целое число и печатает его. Действительно, степени 2 в формате двойной точности IEEE-754 обычно имеют 52 нулевых бита или более 6 8-битных байтов, равных нулю.
Эти слова «скорее всего, но не обязательно» означают, что стандарт C не требует фиксированного размера и диапазона для типов, и они могут варьироваться от компилятора к компилятору, от ОС к ОС. В наши дни наиболее распространены 4-байтовые ints
и 8-байтовые doubles
(если мы рассмотрим, например, платформу x86).