Правильный спецификатор формата для double в printf

Какой правильный формат формата для double в принтф? Это %f либо это %lf? Я верю что это %f, но я не уверен.

Пример кода

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

6 ответов

Решение

"%f" (или хотя бы один) правильный формат для двойного числа. Там нет формата для float, потому что если вы попытаетесь передатьfloat в printf, он будет повышен до double до printfполучает это 1."%lf"также приемлемо в соответствии с действующим стандартом -lуказано, что не имеет никакого эффекта, если после f спецификатор конверсии (среди прочих).

Обратите внимание, что это одно место, котороеprintfстроки формата существенно отличаются отscanf(а также fscanf и т. д.) форматирование строк. Для вывода вы передаете значение, которое будет повышаться с floatвdoubleкогда передается в качестве параметра с переменным значением. Для ввода вы передаете указатель, который не продвигается, поэтому вы должны сказать scanfхотите ли вы прочитатьfloatили double, Таким образом, для scanf, %fозначает, что вы хотите прочитать floatа также %lf означает, что вы хотите прочитать double (и, для чего это стоит, для long double, ты используешь %Lf для любого printfили же scanf).


1. C99, §6.5.2.2 / 6: "Если выражение, обозначающее вызываемую функцию, имеет тип, который не включает в себя прототип, целочисленные преобразования выполняются для каждого аргумента, а аргументы, имеющие тип float, повышаются до двойного. Это называется продвижением аргументов по умолчанию."В C++ формулировка несколько иная (например, она не использует слово "прототип"), но эффект тот же: все переменные параметры проходят промоакции по умолчанию, прежде чем они будут получены функцией.

Учитывая стандарт C99 (а именно, черновик N1256), правила зависят от вида функции: fprintf (printf, sprintf, ...) или scanf.

Вот соответствующие извлеченные части:

предисловие

Настоящее второе издание отменяет и заменяет первое издание, ISO/IEC 9899:1990, с поправками и исправлениями, приведенными в ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 и ISO/IEC 9899/COR2:1996. Основные изменения по сравнению с предыдущим изданием:

  • %lf спецификатор преобразования разрешен в printf

7.19.6.1 fprintf функция

7 Модификаторы длины и их значения:

l (ell) Указывает, что (...) не влияет на следующий спецификатор преобразования a, A, e, E, f, F, g или G.

L Указывает, что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к длинному двойному аргументу.

Те же правила, указанные для fprintf подать заявку на printf, sprintf и аналогичные функции.

7.19.6.2 fscanf функция

11 Модификаторы длины и их значения:

l (ell) Указывает, что (...) что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к аргументу с указателем типа double;

L Указывает, что следующий аргумент преобразования a, A, e, E, f, F, g или G применяется к аргументу с указателем типа на long double.

12 Спецификаторы преобразования и их значения: a,e,f,g Соответствует необязательному знаку с плавающей запятой, (...)

14 Спецификаторы преобразования A, E, F, G и X также действительны и ведут себя так же, как, соответственно, a, e, f, g и x.

Короче говоря, для fprintf указываются следующие спецификаторы и соответствующие типы:

  • %f -> двойной
  • %Lf -> длинный двойной.

и для fscanf это:

  • %f -> плавать
  • %lf -> двойной
  • %Lf -> длинный двойной.

Может быть %f, %g или же %e в зависимости от того, как вы хотите, чтобы число было отформатировано. Смотрите здесь для более подробной информации. l модификатор требуется в scanf с double, но не в printf,

Правильный printf формат для double является %lfТочно так же, как вы использовали это. В вашем коде нет ничего плохого.

Формат %lf в printf не поддерживалось в старых (до C99) версиях языка C, что создавало поверхностную "несогласованность" между спецификаторами формата для double в printf а также scanf, Это поверхностное несоответствие было исправлено в C99.

Так что в современном С имеет смысл отдать предпочтение %f с float, %lf с double а также %Lf с long double последовательно в обоих printf а также scanf,

%Lf (обратите внимание на столицу L) является спецификатором формата для длинных пар.

Для равнины doubles, или %e, %E, %f, %g или же %G Сделаю.

Для двойного вы можете просто использовать %lf или вы можете использовать любой из следующих в соответствии с вашими предпочтениями

%e или же %E для значений в экспоненциальном формате

%g или же %G для нормального или экспоненциального обозначения, в зависимости от того, что больше подходит для его величины.

Узнайте больше здесь Список всех спецификаторов формата в C

Другие вопросы по тегам