Правильный спецификатор формата для двойного в printf
-
27-09-2019 - |
Вопрос
Какой правильный спецификатор формата для double
в printf? Это %f
или это %lf
? Я верю, что это %f
, но я не уверен.
Образец кода
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
Решение
"%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: «Если выражение, которое обозначает вызываемую функцию, имеет тип, который не включает в себя прототип, целочисленные акции выполняются на каждом аргументе, а аргументы, которые имеют тип плавающей способности к двойным. Они называются аргументом по умолчанию. В 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 Модификаторы длины и их значения:
летание (ELL) Указывает, что (...) не влияет на следующий спецификатор преобразования A, A, E, E, F, F, F, F, F, G или G.
Летание Указывает, что следующий спецификатор преобразования A, E, E, E, F, F, G или G применяется к длинному двойному аргументу.
Те же правила, указанные для fprintf
подать заявку printf
, sprintf
и подобные функции.
7.19.6.2
fscanf
функция11 Модификаторы длины и их значения:
летание (ELL) Указывает, что (...), что следующее спецификатор преобразования A, A, E, E, F, F, F, G или G применяется к аргументу с указателем типа для двойного;
Летание Указывает, что следующий спецификатор преобразования A, E, E, E, F, F, G или G применяется к аргументу с указателем типа длинным двойным.
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
не был поддержан в старых (Pre-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