Warum scanf()
braucht es das l
in " %lf
" beim Lesen von a double
, wann printf()
kann " %f
" verwendet werden, unabhängig davon, ob sein Argument a double
oder a ist float
?
Beispielcode:
double d;
scanf("%lf", &d);
printf("%f", d);
c
scanf
length-modifiers
Raldi
quelle
quelle
&
Operator die Adresse einer Variablen "nehmen" , ist das Ergebnis dieser Operation ein Zeiger auf den Speicherort der Variablen im Speicher. Es ist dieser Zeiger, an den übergeben wirdscanf
.Antworten:
Weil C Floats für Funktionen, die variable Argumente annehmen, auf Double hochfährt. Zeiger sind nicht auf etwas gefördert, so sollten Sie verwenden
%lf
,%lg
oder%le
(oder%la
in C99) im Doppel zu lesen.quelle
Seit С99 ist die Übereinstimmung zwischen Formatbezeichnern und Gleitkomma-Argumenttypen in C zwischen
printf
und konsistentscanf
. Es ist%f
zumfloat
%lf
zumdouble
%Lf
zumlong double
Es kommt einfach so vor, dass
float
solche Argumente implizit in Typ konvertiert werden , wenn Argumente vom Typ als variable Parameter übergeben werdendouble
. Dies ist der Grund, warum inprintf
Formatbezeichnern%f
und%lf
gleichwertig und austauschbar sind. In könnenprintf
Sie%lf
mitfloat
oder%f
mit "Cross-Use"double
.Aber es gibt keinen Grund, dies tatsächlich in der Praxis zu tun. Verwenden Sie nicht
%f
aufprintf
Argumente des Typsdouble
. Es ist eine weit verbreitete Angewohnheit, die in C89 / 90-mal geboren wurde, aber es ist eine schlechte Angewohnheit. Verwenden Sie%lf
inprintf
fürdouble
und behalten Sie%f
sichfloat
Argumente vor.quelle
%f
in printf eine gute Angewohnheit ist, da dann Ihr Code immer funktioniert, während die Verwendung%lf
möglicherweise fehlschlägt, wenn der Compiler keine C99-kompatible Bibliothek hat. Leider passiert diese Situation in der Realität.printf
und konsistentscanf
. Beachten Sie, dass dies nicht bedeutet, dass die Verwendung desselben Formatbezeichners bedeutet, dass die von a geschriebenen Daten von[f]printf()
gelesen werden können[f]scanf()
. Im Allgemeinen werden die Daten nicht erfolgreich gelesenscanf()
, wenn derselbe Formatbezeichner verwendetprintf()
wird , der von verwendet wurde. Zum Beispiel , die Raumpolsterung durch einen eingeschoben werden kann ‚s - Format - Spezifizierer werden von denselben übersprungen werden Formatbezeich in einem Anruf.prinf()
"%d"
"%d"
scanf()
scanf
muss die Größe der Daten kennen, auf die verwiesen wird&d
, um sie richtig zu füllen, wohingegen verschiedene Funktionen Floats auf Doppelwerte bringen (nicht ganz sicher warum), so dassprintf
immer ein erhalten wirddouble
.quelle
Andernfalls wird scanf glauben, dass Sie einen Zeiger auf einen Float übergeben, der kleiner als ein Double ist, und einen falschen Wert zurückgeben.
quelle
Die Verwendung eines Gleitkomma- oder Doppelwerts in einem C-Ausdruck führt ohnehin zu einem Doppelwert, sodass printf den Unterschied nicht erkennen kann. Während ein Zeiger auf ein Double explizit an scanf signalisiert werden muss, im Gegensatz zu einem Zeiger auf float, ist es wichtig, worauf der Zeiger zeigt.
quelle
float
automatischdouble
in Ausdrücken heraufgestuft. Diese Regel wurde in Standard C aufgegeben. Wird im Allgemeinenfloat
nichtdouble
in Ausdrücken befördert. Es wird nur befördert,double
wenn es als variadisches Argument übergeben wird, was in diesem Fall der Fall ist.