разница между% fl и% lf в C

0

В настоящее время я изучаю тип данных языка C и пытаюсь напечатать двойную переменную, которую компилятор предложил мне использовать fl после того, как я наберу «%», и я получил 1 число в конце точной десятичной строки. Сравните с% lf, всего будет напечатано шесть знаков после запятой.

double num=12322;
printf("%lf",num);// result is 12322.000000
printf("%fl",num);// result is 12322.0000001 

Я искал много мест, но в основном часто спрашивают о разнице между% f и% lf. Может ли моя ситуация такая же?

Новый участник
nomeiker is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
7
  • Вы уверены, что лишнее 1в конце действительно есть 1? Или это могло быть l? 24 октября в 16:18
  • 4
    %flза %fним следует буквальный l (нижний регистр L), поэтому вывод будет 12322.000000l, а не12322.0000001
    phuclv
    24 октября в 16:18
  • 1
    компилятор предложил мне использовать fl. Вы уверены? Это предположение звучит очень странно, и я не могу представить, почему компилятор сделал это. 24 октября в 16:55
  • @SteveSummit это выглядит так: ibb.co/w6SytmG 24 октября в 16:59
  • Что это за IDE? 24 октября в 17:40
3

В этом призыве printf

printf("%lf",num);// result is 12322.000000

модификатор длины lв спецификаторе преобразования %lfне действует.

Из стандарта C (7.21.6.1 Функция fprintf)

7 The length modifiers and their meanings are:

l (ell) Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument; that a following n conversion specifier applies to a pointer to a long int argument; that a following c conversion specifier applies to a wint_t argument; that a following s conversion specifier applies to a pointer to a wchar_t argument; or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

В этом призыве printf

printf("%fl",num);// result is 12322.0000001 

где в комментарии должна быть написана буква 'l'вместо числа, 1как вы думаете

// result is 12322.000000l
                        ^^^

строка формата "%fl"означает, что после вывода объекта типа double из-за спецификации преобразования %fбудет выведена буква 'l'.

Обратите внимание, что со спецификатором преобразования fможет использоваться еще одна буква 'l'- заглавная буква 'L'. В этом случае спецификация преобразования %Lfслужит для вывода объектов типа long double.

2

Я думаю, у вас действительно есть опечатка в вашем выводе ...

double num=12322;
printf("%lf",num);// result is 12322.000000
printf("%fl",num);// result is 12322.0000001

на самом деле

double num=12322;
printf("%lf",num);// result is 12322.000000
printf("%fl",num);// result is 12322.000000l

В стандарте C говорится, что при передаче в вариативную функцию они floatпреобразуются в a double, поэтому %lfи %fявляются эквивалентными; %flто же самое %f... с lпосле него.

5
  • это не целое число ... но все равно ищите спецификацию. 24 октября в 16:22
  • да, я проверил еще раз, и это буква «l», но каким-то образом IDE порекомендовала мне «fl», так что это точно? 24 октября в 16:28
  • @nomeiker: Не могли бы вы процитировать все сообщение, предоставленное IDE? 24 октября в 16:34
  • Я делаю это снова ... Сначала я набираю "% lf", а он не совпадает. Затем , когда наведен на него указатель мыши, появляется этот "fl" и еще кое-что ibb.co/w6SytmG 24 октября в 16:49
  • 2
    @nomeiker: Эта всплывающая подсказка вообще не кажется полезной. Я рекомендую вам просто игнорировать это. 24 октября в 17:38
0

Есть два правильных способа печати значения типа double:

printf("%f", num);

или

printf("%lf", num);

Эти два имеют точно такой же эффект. В этом случае "l"модификатор фактически игнорируется.

Причина, по которой они имеют такой же эффект, в том, что они printfособенные. printfпринимает переменное количество аргументов, и для таких функций C всегда применяет продвижение аргументов по умолчанию . Это означает , что все тип целого числа , меньшие , чем intповышаются до intи floatповышаются до double. Итак, если вы напишете

float f = 1.5;
printf("%f\n", f);

затем fповышается до doubleперед передачей. Так что внутри printfвсегда есть файл double. Так %fчто никогда не увидишь float, всегда а double. Так %fнаписано, чтобы ожидать a double, поэтому он работает как для, так float и для double . Так что вам не нужен lмодификатор, чтобы указать, какой именно. Но это немного сбивает с толку, поэтому в стандарте говорится, что вы можете поместить lтуда, если хотите, но вам не нужно, и он ничего не делает.

(Между прочим, все это очень отличается от того, scanfоткуда %fи %lfсовершенно разные, и должно быть явно сопоставлено с аргументами типа по float *сравнению с double *.)

Я понятия не имею, почему ваша среда IDE жаловалась (поставьте красную линию под) %lf, и я понятия не имею, что это означало, когда вы предлагали, как вы сказали,

fl, lg, l, f,
elf, Alf, ls, sf,
if, la, lo, of

Некоторые из них выглядят нестандартными, специфичными для системы расширениями, но некоторые (особенно fl) - ерунда. Итак, в итоге, похоже, что предложение вашей IDE было запутанным, ненужным и, вполне возможно, неправильным.