Я хочу знать для себя, что происходит позади и почему он печатает nan
, когда я использую его с %f
, или длинное число, когда я использую его с %lf
.
Некоторые причины.
Во-первых, printf
не знает типы дополнительных аргументов, которые вы ему фактически передаете. Он полагается на строку формата, чтобы сообщить ему количество и типы дополнительных аргументов, которые нужно ожидать. Если вы передадите size_t
в качестве дополнительного аргумента, но скажете printf
ожидать float
, то printf
будет интерпретировать битовую комбинацию дополнительного аргумента как float
, а не size_t
. Целочисленные типы и типы с плавающей запятой имеют совершенно разные представления, поэтому вы получите значения, которых не ожидаете (включая NaN).
Во-вторых, разные типы имеют разные размеры. Если вы передадите 16-битное short
в качестве аргумента, но скажете printf
ожидать 64-битного double
с %f
, то printf
будет искать дополнительные байты сразу после этого аргумента. Не гарантируется, что size_t
и double
имеют одинаковые размеры, поэтому printf
может либо игнорировать часть фактического значения, либо использовать байты из памяти, которые не являются частью значения.
Наконец, это зависит от того, как передаются аргументы. В некоторых архитектурах для передачи аргументов (по крайней мере, для первых нескольких аргументов) используются регистры, а не стек, и разные регистры используются для чисел с плавающей запятой и целых чисел, поэтому, если вы передаете целое число и сообщаете ему ожидать двойное значение с %f
, printf
может посмотрите не в том месте и напечатайте что-то совершенно случайное.
printf
не умный. Он зависит от того, используете ли вы правильный спецификатор преобразования для типа аргумента, который вы хотите передать.
23.10.2019