Почему scanf () нуждается в «% lf» для удвоений, когда printf () в порядке с «% f»?

Почему 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 формата printf %f и %lf эквивалентны и взаимозаменяемы. В printf вы можете «перекрестно использовать» %lf с float или %f с double .

Но на практике нет оснований. Не используйте %f для 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, поскольку то, что указывает указатель, имеет значение.

Давайте будем гением компьютера.