在C语言中,%f和%lf之间有什么区别?

38
我在一本C语言书籍的例子中看到了这两个参数,但作者没有详细解释它们之间的区别。我知道%f表示应该放置一个float类型的值。我尝试过查找相关解释,但很难找到。那么%lf又是什么意思呢?

7
你试过查找 printffprintf,而不是查找 %f%lf 吗?printffprintf 是用于格式化输出的函数。 - ruakh
4
这个printf(和类似函数)参考资料可能会对你有所帮助。当然,还有一个scanf(和类似函数)的参考资料。 - Some programmer dude
1
在C标准中查找“fprintf函数”,它涵盖了所有内容。 - M.M
阅读printf(3)scanf(3)的文档。 - Basile Starynkevitch
4个回答

40
简短回答是:它不会影响printf,并表示在scanf中使用floatdouble
对于printffloat类型的参数被提升为double,因此%f%lf都用于double。对于scanf,您应该使用%f表示float%lf表示double
对于我们中的语言律师,以下是更详细的说明:
printf系列中,%f%lf没有区别。 ISO C标准(所有引用均来自C11),第7.21.6.1节“ fprintf函数”,段落/7指出,对于 l修饰符(我强调):
指定后面的、、、、或转换说明符适用于或参数;后面的转换说明符适用于参数的指针;后面的转换说明符适用于参数;后面的转换说明符适用于参数的指针;或者对后面的、、、、、

32

对于scanf函数,%f用于读取float类型的值,而%lf用于读取double类型的值。

对于printf函数:在C99及更高版本中,它们是相同的,并且可以打印float或者double类型的值。在C89中,%lf会导致未定义的行为,尽管将其视为%f的常见扩展。

之所以在printf函数中使用一种格式指示符来表示两种不同的数据类型,是因为默认参数提升(default argument promotions);当使用参数调用函数时,如果该参数的类型是float,则会将其提升为double类型。因此,无论哪种情况,在printf函数中都只会看到一个double类型的值。


4
对于使用printf函数族输出的情况,%f和%lf指示符意思相同; l会被忽略。这两个指示符都需要一个double类型的相应参数,但是float类型的参数会被提升为double类型,这就是为什么没有独立的float类型指示符的原因。(这种提升只适用于类似printf这样的变参函数和声明时没有原型的函数,而不适用于一般的函数调用。) 对于long double类型,正确的格式指示符是%Lf。
对于使用scanf函数族输入的情况,浮点格式指示符包括%f、%lf和%Lf。这些指示符分别需要指向float、double、long double类型对象的指针。(由于这些实参是指针,所以不存在从float到double的提升。float值可以被提升到double,但是float*指针不能被提升为double*,因为指针必须指向一个实际的float对象。)
但是注意,在使用scanf函数处理数字输入时要小心。没有定义的溢出检查,如果输入超出了程序的类型范围,则程序的行为是未定义的。为了安全起见,先将输入读入字符串,然后使用类似strtod的函数将其转换为数字值。(请查看文档以了解如何检测错误。)

3
在 printf() 函数中,%lf 中的宽度修饰符会被优雅地忽略。更准确地说,%f 接受 double 类型的参数,而 varargs 总是将 float 参数提升为 double 类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接