Почему scanf()
нуждается в l
в "%lf
" при чтении double
, когда printf()
может использовать "%f
" независимо от того, является ли его аргумент double
или float
?
Пример кода:
double d;
scanf("%lf", &d);
printf("%f", d);
Почему scanf()
нуждается в l
в "%lf
" при чтении double
, когда printf()
может использовать "%f
" независимо от того, является ли его аргумент double
или float
?
Пример кода:
double d;
scanf("%lf", &d);
printf("%f", d);
Потому что C будет поддерживать float в double для функций, которые принимают переменные аргументы. Указатели не продвигаются ни на что, поэтому вы должны использовать %lf
, %lg
или %le
(или %la
в C99) для чтения в двухлокальных номерах.
С С99 соответствие между спецификаторами формата и типами аргументов с плавающей запятой в C согласовано между printf
и scanf
.
%f
для float
%lf
для double
%lf
для long double
Так получилось, что когда аргументы типа float
передаются как переменные параметры, такие аргументы неявно преобразуются в тип double
. Именно поэтому спецификаторы формата printf
%f
и %lf
эквивалентны и взаимозаменяемы. В printf
вы можете "перекрестно использовать" %lf
с помощью float
или %f
с помощью double
.
Но нет оснований на самом деле делать это на практике. Не используйте аргументы %f
to printf
типа double
. Это широко распространенная привычка, появившаяся в C89/90 раз, но это плохая привычка. Используйте %lf
в printf
для double
и сохраните %f
для аргументов float
.
scanf
должен знать размер данных, на которые указывает &d
, чтобы заполнить его должным образом, тогда как вариативные функции поддерживают float в double (не совсем уверен, почему), поэтому printf
всегда получает double
.
Потому что иначе scanf подумает, что вы передаете указатель на float, размер которого меньше, чем двойной, и он вернет неправильное значение.
Использование значения float или double в выражении C приведет к тому, что значение равно double, поэтому printf не может отличить эту разницу. В то время как указатель на double должен быть явно передан scanf в отличие от указателя на float, поскольку то, что указывает указатель, имеет значение.