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:
- Waarom kunt u een dubbel afdrukken met% LF?
- Waarom kunt u een dubbel afdrukken met% f?
- Welke is beter en correct om te gebruiken?
Antwoord 1, Autoriteit 100%
Voor variabele argumentfuncties zoals printf
en scanf
, worden de argumenten gepromoot, bijvoorbeeld, eventuele kleinere integer-typen worden gepromoot naar int
, float
wordt gepromoot naar double
.
scanf
neemt parameters van aanwijzers, dus de promotieregel heeft geen effect. Het moet %f
gebruiken voor float*
en %lf
voor double*
.
printf
ZULLEN NOOIT EEN float
ARGUMENT, float
wordt altijd gepromoot naar double
. Het formaatspecificator is %f
. Maar C99 zegt ook %lf
is hetzelfde als %f
in printf
:
C99 §7.19.6.1 De
fprintf
FUNCTION
l
(ell) Specificeert dat een volgended
,i
,o
,u
,X
ofX
conversiespecificatie is van toepassing op eenlong int
ofunsigned long int
argument; dat een volgenden
-conversiespecificatie van toepassing is op een pointer naar eenlong int
-argument; dat een volgendec
-conversiespecificatie van toepassing is op eenwint_t
-argument; dat een volgendes
-conversiespecificatie van toepassing is op een pointer naar eenwchar_t
-argument; of heeft geen effect op een volgendeA
,A
,E
,E
,F
,F
,G
ofG
conversiespecificatie.
Antwoord 2, autoriteit 23%
Wanneer een float
wordt 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 %f
en %lf
specificaties voor printf
zijn hetzelfde; ze hebben allebei een double
waarde.
Wanneer scanf
wordt aangeroepen, worden pointers doorgegeven, geen directe waarden. Een pointer naar float
wordt 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 scanf
moet het argument voor %f
een verwijzing zijn naar float
en het argument voor %lf
moet 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’.