为什么在读取scanf()l需要“ %lf”中的double,而printf()可以使用“ %f”而不管其参数是double还是float

示例代码:
>
double d;
scanf("%lf", &d);
printf("%f", d);


评论

我不明白您所说的POINTER是什么意思。在scanf中,我们仅传递&variable(即)地址,因此指针在哪里

@deetchanya在C中,当您使用一元&运算符“获取”变量的地址时,该操作的结果是指向变量在内存中的存储位置的指针。指针被传递给scanf。

这是关于此stackoverflow.com/questions/9291348/…的另一篇文章。

#1 楼

因为C会将带有可变参数的函数的浮点数提升为双精度。指针没有提升为任何内容,因此您应该使用%lf%lg%le(或C99中的%la)来读取双精度型。

#2 楼

由于С99,C中格式说明符和浮点参数类型之间的匹配在printfscanf之间是一致的。




%f for float


%lf for double


%Lf for long double


正好发生这样的情况,当将float类型的参数作为可变参数传递时,此类参数被隐式转换为double类型。这就是为什么在printf格式中,说明符%f%lf是等效且可互换的原因。在printf中,您可以将%lffloat交叉使用,或者将%fdouble交叉使用。

但是没有理由在实践中实际使用它。不要使用%fprintf类型的参数。这是一个普遍的习惯,可追溯到C89 / 90年代,但这是一个坏习惯。将double中的%lf用于printf,并保留double用于%f参数。

评论


我会说在printf中使用%f是一个好习惯,因为这样您的代码就可以正常工作,而如果编译器没有C99兼容库,则使用%lf可能会失败。不幸的是,这种情况确实发生在现实中。

– M.M
16年5月22日在4:39

由于С99,C中的格式说明符和浮点参数类型之间的匹配在printf和scanf之间是一致的。注意,这并不意味着使用相同的格式说明符意味着[f] printf()写入的数据可以被[f] scanf()读取。通常,对printf()使用与scanf()相同的格式说明符将不会成功读取数据。例如,prinf()的“%d”格式说明符可以插入的空格填充将由scanf()调用中的同一“%d”格式说明符跳过。

–安德鲁·亨利(Andrew Henle)
18年7月14日在18:02

#3 楼

scanf需要知道&d指向的数据大小才能正确填充,而可变参数函数会将浮点数加倍(不确定原因),因此printf总是得到double

评论


可变参数函数非常脆弱,因为它需要能够知道传递给它的所有参数的确切类型和大小,并且不能在编译时强制执行。如果变量的类型错误,将读取错误的值。如果大小错误,则之后的所有变量也会被误读。如果可以通过两种不同大小的浮标,则将引起各种令人讨厌且容易遗漏的问题。

–mwfearnley
16年11月5日,12:54

#4 楼

因为否则scanf会认为您正在传递一个指向小于双精度数大小的float的指针,并且它将返回错误的值。

#5 楼

在C表达式中使用float或double值将导致值始终是double,因此printf无法分辨出差异。而指向double的指针必须显式地向scanf发出信号,以不同于float指针,因为该指针所指向的是重要的。

评论


在这种情况下,由于参数是可变长度参数列表的一部分,因此float会转换为double,但float并不总是在C中转换为double。

– Robert Gamble
08-10-16在23:19

在C语言的标准版中,浮点值会自动提升为表达式的两倍。该规则在标准C中被放弃。通常,float不会被提升为表达式中的double值。当作为可变参数传递时,它只会被提升为两倍,这就是这种情况。

– AnT
2015年1月29日19:00