Wofür ist der richtige Formatbezeichner double
in printf? Ist es %f
oder ist es %lf
? Ich glaube, es ist %f
aber ich bin mir nicht sicher.
Codebeispiel
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
"%f"
ist das (oder zumindest ein) korrektes Format für ein Double. Dort ist kein Format für a float
denn wenn Sie versuchen, a zu bestehen float
zu printf
es wird zu befördert double
Vor printf
erhält es1. "%lf"
ist auch nach dem aktuellen Standard akzeptabel – die l
wird als wirkungslos angegeben, wenn gefolgt von der f
Konvertierungsbezeichner (unter anderem).
Beachten Sie, dass dies ein Ort ist, der printf
Formatzeichenfolgen unterscheiden sich erheblich von scanf
(und fscanf
, usw.) Formatzeichenfolgen. Für die Ausgabe übergeben Sie a Wertdie von befördert werden float
zu double
wenn es als variadischer Parameter übergeben wird. Als Eingabe übergibst du a Zeigerdie nicht beworben wird, also musst du es sagen scanf
ob du lesen willst a float
oder ein double
so für scanf
, %f
bedeutet, dass Sie a lesen möchten float
und %lf
bedeutet, dass Sie a lesen möchten double
(und für das, was es wert ist, für a long double
Sie nutzen %Lf
für entweder printf
oder scanf
).
1. C99, §6.5.2.2/6: „Wenn der Ausdruck, der die aufgerufene Funktion bezeichnet, einen Typ hat, der keinen Prototyp enthält, werden die Integer-Umstufungen für jedes Argument durchgeführt, und Argumente vom Typ Float werden zu Double befördert. Diese werden als Standardargument-Promotions bezeichnet.” In C++ ist der Wortlaut etwas anders (z. B. wird das Wort „Prototyp“ nicht verwendet), aber der Effekt ist derselbe: Alle variadischen Parameter werden standardmäßig hochgestuft, bevor sie von der Funktion empfangen werden.
Angesichts der C99 Standard (nämlich die N1256 draft), hängen die Regeln von der Art der Funktion ab: fprintf (printf, sprintf, …) oder scanf.
Hier sind relevante Teile extrahiert:
Vorwort
Diese zweite Ausgabe annulliert und ersetzt die erste Ausgabe, ISO/IEC 9899:1990, geändert und korrigiert durch ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995 und ISO/IEC 9899/COR2:1996. Zu den wichtigsten Änderungen gegenüber der vorherigen Ausgabe gehören:
%lf
Konvertierungsbezeichner erlaubt printf
7.19.6.1 Die fprintf
Funktion
7 Die Längenmodifikatoren und ihre Bedeutung sind:
l (ell) Gibt an, dass (…) keine Auswirkung auf einen folgenden Konvertierungsbezeichner a, A, e, E, f, F, g oder G hat.
L Gibt an, dass ein folgender Konvertierungsbezeichner a, A, e, E, f, F, g oder G für ein langes doppeltes Argument gilt.
Die gleichen Regeln für angegeben fprintf
bewerben für printf
, sprintf
und ähnliche Funktionen.
7.19.6.2 Die fscanf
Funktion
11 Die Längenmodifikatoren und ihre Bedeutung sind:
l (ell) Gibt an, dass (…) ein auf a, A, e, E, f, F, g oder G folgender Konvertierungsbezeichner auf ein Argument mit Typzeiger auf double angewendet wird;
L Gibt an, dass ein folgender Konvertierungsbezeichner a, A, e, E, f, F, g oder G auf ein Argument mit Typzeiger auf long double angewendet wird.
12 Die Konvertierungsbezeichner und ihre Bedeutung sind: a,e,f,g Entspricht einer optional vorzeichenbehafteten Gleitkommazahl, (…)
14 Die Konvertierungsbezeichner A, E, F, G und X sind ebenfalls gültig und verhalten sich genauso wie a, e, f, g bzw. x.
Um es kurz zu machen, z fprintf
Die folgenden Bezeichner und entsprechenden Typen sind angegeben:
%f
-> doppelt
%Lf
-> langes Doppel.
und für fscanf
es ist:
%f
-> schweben
%lf
-> doppelt
%Lf
-> langes Doppel.
Es kann sein %f
, %g
oder %e
je nachdem, wie die Zahl formatiert werden soll. Sehen hier für mehr Details. Das l
Modifikator ist in erforderlich scanf
mit double
aber nicht drin printf
.
Format %lf
ist vollkommen richtig printf
Format für double
, genau so, wie Sie es verwendet haben. An deinem Code ist nichts falsch.
Format %lf
in printf
wurde in alten (vor C99) Versionen der C-Sprache nicht unterstützt, was zu oberflächlichen “Inkonsistenzen” zwischen Formatbezeichnern für führte double
in printf
und scanf
. Diese oberflächliche Inkonsistenz wurde in C99 behoben.
Sie müssen nicht verwenden %lf
mit double
in printf
. Sie können verwenden %f
auch, wenn Sie es vorziehen (%lf
und %f
sind gleichwertig in printf
). Aber in modernem C macht es durchaus Sinn, lieber zu verwenden %f
mit float
, %lf
mit double
und %Lf
mit long double
konsequent in beiden printf
und scanf
.
%Lf
(Beachte die Hauptstadt L
) ist der Formatbezeichner zum lange Doppel.
Für schlicht doubles
entweder %e
, %E
, %f
, %g
oder %G
Wird besorgt.
Wenn Sie mit einer C89-Bibliothek feststecken,
"%lf"
ist nicht definiert; in C99- und C11-Bibliotheken ist es so definiert, dass es dasselbe ist wie"%f"
.– pmg
29. April 2012 um 0:06 Uhr
Ihre Variante ist so korrekt wie nie zuvor.
%lf
ist der richtige Formatbezeichner fürdouble
. Aber es wurde so in C99. Davor musste man verwenden%f
.– AnT steht zu Russland
7. Mai 2016 um 19:59 Uhr