ScanF / PrintF Dubbele variabele C

Laten we zeggen dat ik dit volgende bit van code in C:

heb

double var;
scanf("%lf", &var);
printf("%lf", var);
printf("%f", var);

Het leest van Stdin-variabele ‘Var’ en drukt vervolgens twee keer af in Stdout ‘Var’.
Ik begrijp dat dat is hoe je een dubbele variabele van Stdin leest, maar mijn vragen zijn:

  1. Waarom kunt u een dubbel afdrukken met% LF?
  2. Waarom kunt u een dubbel afdrukken met% f?
  3. Welke is beter en correct om te gebruiken?

Antwoord 1, Autoriteit 100%

Voor variabele argumentfuncties zoals printfen scanf, worden de argumenten gepromoot, bijvoorbeeld, eventuele kleinere integer-typen worden gepromoot naar int, floatwordt gepromoot naar double.

scanfneemt parameters van aanwijzers, dus de promotieregel heeft geen effect. Het moet %fgebruiken voor float*en %lfvoor double*.

printfZULLEN NOOIT EEN floatARGUMENT, floatwordt altijd gepromoot naar double. Het formaatspecificator is %f. Maar C99 zegt ook %lfis hetzelfde als %fin printf:

C99 §7.19.6.1 De fprintfFUNCTION

l(ell) Specificeert dat een volgende d, i, o, u, Xof Xconversiespecificatie is van toepassing op een long intof unsigned long intargument; dat een volgende n-conversiespecificatie van toepassing is op een pointer naar een long int-argument; dat een volgende c-conversiespecificatie van toepassing is op een wint_t-argument; dat een volgende s-conversiespecificatie van toepassing is op een pointer naar een wchar_t-argument; of heeft geen effect op een volgende A, A, E, E, F, F, Gof Gconversiespecificatie.


Antwoord 2, autoriteit 23%

Wanneer een floatwordt doorgegeven aan printf, wordt deze automatisch geconverteerd naar een double. Dit maakt deel uit van de standaard argumentpromoties, die van toepassing zijn op functies die een variabele parameterlijst hebben (met ...), grotendeels om historische redenen. Daarom moet de “natuurlijke” specificatie voor een float, %f, werken met een double-argument. Dus de %fen %lfspecificaties voor printfzijn hetzelfde; ze hebben allebei een doublewaarde.

Wanneer scanfwordt aangeroepen, worden pointers doorgegeven, geen directe waarden. Een pointer naar floatwordt niet geconverteerd naar een pointer naar double(dit kan niet werken omdat het point-to-object niet kan veranderen wanneer u het pointertype wijzigt). Dus voor scanfmoet het argument voor %feen verwijzing zijn naar floaten het argument voor %lfmoet een verwijzing zijn naar double.


Antwoord 3, autoriteit 11%

Voor zover ik man-pagina’s lees, zegt scanf dat de lengte-modifier ‘l’ aangeeft (in het geval van zwevende punten) dat het argument van het type double is in plaats van van het type float, dus je kunt ‘lf, le, lg hebben ‘.

Wat betreft afdrukken, officieel zegt de handleiding dat ‘l’ alleen van toepassing is op integer-types. Het wordt dus mogelijk niet ondersteund op sommige systemen of door sommige standaarden. Ik krijg bijvoorbeeld de volgende foutmelding bij het compileren met gcc -Wall -Wextra -pedantic

a.c:6:1: warning: ISO C90 does not support the ‘%lf’ gnu_printf format [-Wformat=]

Dus misschien wil je nog een keer controleren of je standaard de syntaxis ondersteunt.

Tot slot zou ik willen zeggen dat u leest met ‘%lf’ en u afdrukt met ‘%f’.

Other episodes