Почему это , что scanf()
нуждается l
в « %lf
» при чтении double
, когда printf()
можно использовать « %f
» независимо от того, является ли ее аргумент double
или float
?
Пример кода:
double d;
scanf("%lf", &d);
printf("%f", d);
c
scanf
length-modifiers
Raldi
источник
источник
&
оператором, результатом этой операции является указатель на место хранения переменной в памяти. Это тот указатель, который передаетсяscanf
.Ответы:
Потому что C будет продвигать числа с плавающей запятой для функций, которые принимают переменные аргументы. Указатели ни на что не повышаются, поэтому вы должны использовать
%lf
,%lg
или%le
(или%la
в C99), чтобы читать в двойных.источник
Начиная с С99 соответствие между спецификаторами формата и типами аргументов с плавающей запятой в C согласовано между
printf
иscanf
. это%f
дляfloat
%lf
дляdouble
%Lf
дляlong double
Так уж получилось, что когда аргументы типа
float
передаются как переменные параметры, такие аргументы неявно преобразуются в типdouble
. Это причина, почему вprintf
спецификаторах формата%f
и%lf
эквивалентны и взаимозаменяемы. Вprintf
вы можете "перекрестное использование"%lf
сfloat
или%f
сdouble
.Но на самом деле нет причин делать это на практике. Не используйте
%f
дляprintf
аргументов типаdouble
. Это широко распространенная привычка, рожденная еще в C89 / 90 раз, но это плохая привычка. Используйте%lf
вprintf
fordouble
и оставьте%f
зарезервированные дляfloat
аргументов.источник
%f
в printf - хорошая привычка, потому что тогда ваш код всегда работает, тогда как использование%lf
может завершиться неудачей, если у компилятора нет библиотеки, совместимой с C99. К сожалению, такая ситуация действительно происходит.printf
иscanf
. Обратите внимание, что это не означает, что использование одного и того же спецификатора формата означает, что данные, записанные с помощью a,[f]printf()
могут быть прочитаны[f]scanf()
. Как правило, использование того же спецификатора формата,scanf()
который использовался дляprintf()
, не приведет к успешному чтению данных. Так , например, пространство обивка , которая может быть вставлена с помощьюprinf()
«S"%d"
спецификатора формата будет пропущена к тому же"%d"
спецификатору формата вscanf()
вызове.scanf
Чтобы&d
правильно заполнить данные, необходимо знать размер данных, на которые они указывают , тогда как функции с переменными числами повышают число с плавающей точкой до двойных (не совсем понятно, почему), поэтомуprintf
всегда получаем adouble
.источник
Потому что в противном случае scanf будет думать, что вы передаете указатель на число с плавающей точкой, размер которого меньше, чем double, и он вернет неправильное значение.
источник
Использование значения с плавающей запятой или двойного значения в выражении C в любом случае приведет к двойному значению, поэтому printf не сможет определить разницу. Принимая во внимание, что указатель на двойник должен быть явно передан в scanf в отличие от указателя на число с плавающей точкой, потому что именно то, на что указывает указатель, имеет значение.
источник
float
значения автоматически переводилисьdouble
в выражения. Это правило было отменено в стандарте C. Как правило,float
не применяетсяdouble
в выражениях. Это только повышается,double
когда передается в качестве аргумента с переменным значением, что и происходит в этом случае.