C语言 C 中的 %f 和 %lf 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25860850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between %f and %lf in C?
提问by committedandroider
I saw these two parameters in a C example in a C book but the author didn't elaborate what the difference between the two are. I know that %fspecifies that a float should take its place. I tried looking this up but had a hard time trying to find this w symbols. What about %lf?
我在C书的C例子中看到了这两个参数,但是作者没有详细说明这两者的区别是什么。我知道这%f指定了一个浮点数应该取代它的位置。我试着查找这个,但很难找到这个 w 符号。怎么样%lf?
采纳答案by paxdiablo
The short answer is that it has no impact on printf, and denotes use of floator doublein scanf.
简短的回答是它对 没有影响printf,并且表示使用float或doublein scanf。
For printf, arguments of type floatare promoted to doubleso both %fand %lfare used for double. For scanf, you should use %ffor floatand %lffor double.
对于printf,类型的参数float被提升为doubleso%f和%lf用于double。For scanf,你应该使用%fforfloat和%lffor double。
More detail for the language lawyers among us below:
我们中间的语言律师的更多细节如下:
There is no difference between %fand %lfin the printffamily. The ISO C standard (all references within are from C11), section 7.21.6.1 The fprintf function, paragraph /7states, for the lmodifier (my emphasis):
有什么区别%f和%lf在printf家庭。ISO C 标准(其中的所有参考资料均来自 C11),部分7.21.6.1 The fprintf function,段落/7状态,用于l修饰符(我的重点):
Specifies that a following
d,i,o,u,x, orXconversion specifier applies to along intorunsigned long intargument; that a followingnconversion specifier applies to a pointer to along intargument; that a followingcconversion specifier applies to awint_targument; that a followingsconversion specifier applies to a pointer to awchar_targument; or has no effect on a followinga,A,e,E,f,F,g, orGconversion specifier.
指定后面的
d,i,o,u,x, orX转换说明符应用于long intorunsigned long int参数;以下n转换说明符适用于指向long int参数的指针;以下c转换说明符适用于wint_t参数;以下s转换说明符适用于指向wchar_t参数的指针;or 对后面的a,A,e,E,f,F,g, 或G转换说明符没有影响。
The reason it doesn't need to modify the fspecifier is because that specifier alreadydenotes a double, from paragraph /8of that same section where it lists the type for the %fspecifier:
它不需要修改说明f符的原因是因为该说明符已经表示 a double,来自/8同一部分的段落,其中列出了%f说明符的类型:
A
doubleargument representing a floating-point number is converted to decimal notation
甲
double表示浮点数参数被转换为十进制表示法
That has to do with the fact that arguments following the ellipse in the function prototype are subject to default argument promotions as per section 6.5.2.2 Function calls, paragraph /7:
这与函数原型中椭圆后面的参数受到默认参数提升有关,按照部分6.5.2.2 Function calls,段落/7:
The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.
函数原型声明符中的省略号表示在最后一个声明的参数之后停止参数类型转换。默认参数提升是在尾随参数上执行的。
Since printf(and the entire familyof printf-like functions) is declared as int printf(const char * restrict format, ...);with the ellipsis notation, that rule applies here. The default argument promotions are covered in section 6.5.2.2 Function calls, paragraph /6:
由于printf(以及整个系列的printf-like 函数)是int printf(const char * restrict format, ...);用省略号表示法声明的,因此该规则适用于此处。部分6.5.2.2 Function calls、段落中介绍了默认参数提升/6:
If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type
floatare promoted todouble. These are called the default argument promotions.
如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并将具有类型的参数
float提升为double。这些被称为默认参数提升。
For the scanffamily, it mandates the use of a doublerather than a float. Section 7.21.6.2 The fscanf function /11:
对于scanf家庭,它要求使用 adouble而不是 a float。部分7.21.6.2 The fscanf function /11:
Specifies that a following
d,i,o,u,x,X, ornconversion specifier applies to an argument with type pointer tolong intorunsigned long int; that a followinga,A,e,E,f,F,g, orGconversion specifier applies to an argument with type pointer todouble;or that a followingc,s, or[conversion specifier applies to an argument with type pointer towchar_t.
指定后面的
d,i,o,u,x,X, orn转换说明符适用于类型指针指向long intor的参数unsigned long int;后面的a,A,e,E,f,F,g, 或G转换说明符适用于类型指针为 的参数double;或者后面的c、s或[转换说明符适用于类型指针为 的参数wchar_t。
This modifies the /12paragraph of that section that states, for %f:
这修改了/12该部分的段落,对于%f:
Matches an optionally signed floating-point number, infinity, or
NaN, whose format is the same as expected for the subject sequence of thestrtodfunction. The corresponding argument shall be a pointer to floating.
匹配一个可选的有符号浮点数、无穷大或
NaN,其格式与strtod函数主题序列的预期格式相同。相应的参数应该是一个指向浮动的指针。
回答by M.M
For scanf, %freads into a float, and %lfreads into a double.
对于scanf,%f读入 a float,然后%lf读入 a double。
For printf: In C99 and later, they both are identical, and they print either a floator a double. In C89, %lfcaused undefined behaviour although it was a common extension to treat it as %f.
对于printf:在 C99 及更高版本中,它们都是相同的,并且它们打印 afloat或 a double。在 C89 中,%lf导致未定义的行为,尽管将其视为%f.
The reason that one specifier can be used for two different types in printfis because of the default argument promotions; arguments of type floatare promoted to doublewhen used to call a function and not matching a parameter in a function prototype. So printfjust sees a doublein either case.
一个说明符可以用于两种不同类型的printf原因是因为默认参数提升;当用于调用函数并且与函数原型中的参数不匹配时,类型参数float被提升为double。所以在任何一种情况下printf都只看到 a double。
回答by Vineeth Krishna K
%fis a format specifier in C that denotes floatingpoint or fractional numbers.
%f是 C 中的格式说明符,表示floating点数或小数。
Syntax:
句法:
scanf("%f", variable);
The memory allocated for floatis 4 bytes.
The range of values is from 1.17549 x 10^(‐38) to 3.40282 x 10^(38).
The precision of digits is 6 decimal digits.
分配的内存为float4 个字节。值的范围是从 1.17549 x 10^(‐38) 到 3.40282 x 10^(38)。数字的精度为 6 位十进制数字。
%lf is a format specifier specifying doublewhich is the double precision of floating-point numbers.
%lf 是一个格式说明符,指定double哪个是浮点数的双精度。
Syntax:
句法:
scanf("%lf", variable)
The memory allocated for doubleis 8 bytes.
The range of values is from 2.22507 x 10^(‐308) to 1.79769 x 10^(308).
The precision of digits is 15 decimal digits.
分配的内存为double8 个字节。值的范围是从 2.22507 x 10^(‐308) 到 1.79769 x 10^(308)。数字的精度为 15 位十进制数字。
For variadic functions like printfeither %for %lfcan be used because for such functions floatis directly promoted to double.
可变参数的功能,如printf任一%f或%lf可以使用,因为用于这样的功能float被直接提升到double。
But for reading data i.e. for scanf, format specifier %findicates floatpoint no. and %lfindicates doublefloat point no.. scanfand other similar functions require pointersto objects of type floatand doublerespectively. This is because there is no promotion from floatto doublesince arguments for such functions is a pointeri.e. a floatvalue can be promoted to double, but a float pointercan't be promoted to a double pointerbecause the pointerhas to point to the address of actual floatobject.
但是对于读取数据即 for scanf,格式说明符%f表示float点号。and%lf表示double浮点数..scanf和其他类似的函数分别需要pointers类型float和对象double。这是因为没有从floatto提升,double因为这些函数的参数是 a ,pointer即一个float值可以提升为double,但 afloat pointer不能提升为 adouble pointer因为pointer必须指向实际float对象的地址。
In case for scanfand other related functions, %fused in place of %lfand the input is beyond the above specified range then it may lead to error.
万一 forscanf等相关功能,%f代替使用,%lf输入超出上述规定范围,可能会导致错误。
回答by BadZen
The width modifier in %lf is gracefully ignored by printf(). Or, to be more accurate, %f takes a double - varargs will always promote float arguments to double.
printf() 优雅地忽略了 %lf 中的宽度修饰符。或者,更准确地说, %f 采用双精度 - varargs 将始终将浮点参数提升为双精度。
回答by Deepesh Dragoneel
For output using the printf family of functions, the %f and %lf specifiers mean the same thing; the l is ignored. Both require a corresponding argument of type double — but an argument of type float is promoted to double, which is why there's no separate specifier for type float. (This promotion applies only to variadic functions like printf and to functions declared without a prototype, not to function calls in general.) For type long double, the correct format specifier is %Lf.
对于使用 printf 系列函数的输出,%f 和 %lf 说明符的含义相同;l 被忽略。两者都需要一个相应的 double 类型的参数——但是一个 float 类型的参数被提升为 double,这就是为什么没有单独的 float 类型说明符的原因。(此提升仅适用于 printf 等可变参数函数和没有原型声明的函数,不适用于一般的函数调用。)对于 long double 类型,正确的格式说明符是 %Lf。
For input using the scanf family of functions, the floating-point format specifiers are %f, %lf, and %Lf. These require pointers to objects of type float, double, and long double, respectively. (There's no float-to-double promotion because the arguments are pointers. A float value can be promoted to double, but a float* pointer can't be promoted to a double* because the pointer has to point to an actual float object.)
对于使用 scanf 系列函数的输入,浮点格式说明符是 %f、%lf 和 %Lf。它们分别需要指向 float、double 和 long double 类型的对象的指针。(没有 float-to-double 提升,因为参数是指针。浮点值可以提升为 double,但 float* 指针不能提升为 double*,因为指针必须指向实际的 float 对象。 )
But be careful using the scanf functions with numeric input. There is no defined overflow checking, and if the input is outside the range of the type your program's behavior is undefined. For safety, read input into a string and then use something like strtod to convert it to a numeric value. (See the documentation to find out how to detect errors.)
但是要小心使用带有数字输入的 scanf 函数。没有定义的溢出检查,如果输入超出类型的范围,则程序的行为是未定义的。为了安全起见,将输入读入一个字符串,然后使用类似 strtod 的东西将其转换为数值。(请参阅文档以了解如何检测错误。)

