printf中double的正确格式说明符是什么?是%f还是%f ?我相信是%f,但我不确定。
代码示例
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
printf中double的正确格式说明符是什么?是%f还是%f ?我相信是%f,但我不确定。
代码示例
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
“%f”是(或至少一个)double的正确格式。浮点数没有格式,因为如果你试图将一个浮点数传递给printf,它会在printf接收到它1之前升格为double。在当前标准下,“%lf”也是可以接受的——如果后面跟着f转换说明符(以及其他),则l被指定为无效。
Note that this is one place that printf format strings differ substantially from scanf (and fscanf, etc.) format strings. For output, you're passing a value, which will be promoted from float to double when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf whether you want to read a float or a double, so for scanf, %f means you want to read a float and %lf means you want to read a double (and, for what it's worth, for a long double, you use %Lf for either printf or scanf).
1. C99,§6.5.2.2/6:“如果表示被调用函数的表达式的类型不包括原型,则对每个实参执行整数提升,类型为float的实参将提升为double。这些被称为默认参数提升。”在c++中,措辞有些不同(例如,它不使用“prototype”这个词),但效果是一样的:所有可变参数在被函数接收之前都会进行默认的提升。
对于C99标准(即N1256草案),规则取决于 函数类型:fprintf (printf, sprintf,…)或scanf。
以下是相关部分摘录:
Foreword This second edition cancels and replaces the first edition, ISO/IEC 9899:1990, as amended and corrected by ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995, and ISO/IEC 9899/COR2:1996. Major changes from the previous edition include: %lf conversion specifier allowed in printf 7.19.6.1 The fprintf function 7 The length modifiers and their meanings are: l (ell) Specifies that (...) has no effect on a following a, A, e, E, f, F, g, or G conversion specifier. L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to a long double argument.
为fprintf指定的相同规则也适用于printf、sprintf和类似的函数。
7.19.6.2 The fscanf function 11 The length modifiers and their meanings are: l (ell) Specifies that (...) that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to double; L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to long double. 12 The conversion specifiers and their meanings are: a,e,f,g Matches an optionally signed floating-point number, (...) 14 The conversion specifiers A, E, F, G, and X are also valid and behave the same as, respectively, a, e, f, g, and x.
长话短说,对于fprintf,指定了以下说明符和相应的类型:
%f -> double %Lf ->长双。
对于fscanf,它是:
%f ->浮点数 %lf -> double %Lf ->长双。
Format %lf是double的一个完全正确的printf格式,与您使用的完全相同。你的代码没有问题。
旧版本(c99之前)的C语言不支持printf中的Format %lf,这在printf中的double格式说明符和scanf中造成了表面上的“不一致”。这种表面上的不一致在C99中得到了修复。
你不需要在printf中使用%lf和double。如果您愿意,也可以使用%f (%lf和%f在printf中是等价的)。但在现代C语言中,更喜欢使用%f与float, %lf与double, %lf与long double,在printf和scanf中始终一致是完全有意义的。