为什么scanf()需要%lf";对于double,当printf()可以只使用“quot;%f";?
为什么为什么scanf()需要%lf";对于double,当printf()可以只使用“quot;%f";?,c,scanf,length-modifiers,C,Scanf,Length Modifiers,为什么scanf()在读取double时需要“%lf”中的l,printf()可以使用“%f”,而不管其参数是double还是float 示例代码: double d; scanf("%lf", &d); printf("%f", d); 因为C会将接受变量参数的函数的浮点值提升为双倍值。指针不会被提升为任何形式,因此您应该使用%lf、%lg或%le(或C99中的%la)以双倍方式读取。scanf需要知道&d所指向的数据的大小以正确填充它,而变量函数将浮点提升为双倍(不完全确定原因),
scanf()
在读取double
时需要“%lf
”中的l
,printf()
可以使用“%f
”,而不管其参数是double
还是float
示例代码:
double d;
scanf("%lf", &d);
printf("%f", d);
因为C会将接受变量参数的函数的浮点值提升为双倍值。指针不会被提升为任何形式,因此您应该使用
%lf
、%lg
或%le
(或C99中的%la
)以双倍方式读取。scanf
需要知道&d
所指向的数据的大小以正确填充它,而变量函数将浮点提升为双倍(不完全确定原因),因此,printf
总是得到一个double
在C表达式中使用浮点数或double值将导致一个值无论如何都是double,因此printf无法区分这两个值。而指向double的指针必须显式地以不同于指向float的指针的方式通知scanf,因为指针ints to才是最重要的。因为否则scanf会认为您正在传递一个指向小于双精度浮点的指针,它将返回一个不正确的值。由于С99,C中的格式说明符和浮点参数类型之间的匹配在printf
和scanf
之间是一致的
用于%f
浮动
用于%lf
double
用于%Lf
长双精度
float
的参数作为可变参数传递时,这些参数被隐式转换为类型为double
。这就是为什么在printf
格式说明符%f
和%lf
中是等价和可互换的。在printf
中,您可以“交叉使用”%lf
与float
或%f
与double
但实际上没有理由这样做。不要使用
%f
来printf
类型的double
参数。这是C89/90时代的一个普遍习惯,但这是一个坏习惯。在printf
中使用%lf
用于double
并保留%f
用于float
arguments.float在这种情况下被转换为double,因为参数是可变长度参数列表的一部分,所以在C语言中float并不总是转换为double。在C语言的前标准版本中,float
值在表达式中被自动提升为double
。在标准C中,该规则被放弃。通常,float
在表达式中不会提升为double
。它只会在作为变量参数传递时提升为double
,这就是本例中发生的情况。我不明白这里的指针是什么意思。在scanf中,我们只传递&variable(即)地址,那么pointer@deetchanya在C中,当您取"带有一元&
运算符的变量,该操作的结果是指向变量在内存中的存储位置的指针。正是该指针被传递到scanf
。这是另一篇关于这一点的文章。我想说,在printf中使用%f
是一个好习惯,因为这样您的代码总是有效的,而我们如果编译器没有与C99兼容的库,ing%lf
可能会失败。不幸的是,这种情况在现实中确实会发生。由于С99,C中的格式说明符和浮点参数类型之间的匹配在printf
和scanf
之间是一致的。请注意,这并不意味着使用相同的格式说明符意味着由[f]printf()
写入的数据可以由[f]scanf()
读取。通常,使用与printf()
相同的scanf()
格式说明符将无法成功读取数据。例如,可以由printf()
的插入的空格填充格式说明符将被scanf()中相同的%d“
格式说明符跳过
call。变量函数非常脆弱,因为它需要知道传递给它的所有参数的确切类型和大小,并且不能在编译时强制执行。如果变量的类型错误,将读取错误的值;如果变量的大小错误,后面的所有变量也将被误读。如果浮动可以通过,那么它将导致各种讨厌的和容易错过的问题。