【问题标题】:What is the difference between %f and %lf in C?C语言中的%f和%lf有什么区别?
【发布时间】:2014-09-16 04:46:58
【问题描述】:

我在 C 书籍的 C 示例中看到这两个参数,但作者没有详细说明两者之间的区别。我知道%f 指定一个浮点数应该代替它。我尝试查找此内容,但很难找到此 w 符号。 %lf呢?

【问题讨论】:

标签: c


【解决方案1】:

简短的回答是它对printf 没有影响,并表示在scanf 中使用floatdouble

对于printffloat 类型的参数被提升为double,因此%f%lf 都用于double。对于scanf,您应该使用%ffloat%lfdouble

以下是我们中间语言律师的更多详细信息:


%f%lfprintf 系列中没有区别。 ISO C 标准(内所有引用均来自 C11),7.21.6.1 The fprintf function 部分,/7 段声明,用于l 修饰符(我的重点):

指定以下diouxX 转换说明符适用于long intunsigned long int 参数;后面的n 转换说明符适用于指向long int 参数的指针;后面的c 转换说明符适用于wint_t 参数;后面的s 转换说明符适用于指向wchar_t 参数的指针; 或对以下aAeEfFgG 转换说明符没有影响。

它不需要修改f 说明符的原因是,该说明符已经表示double,来自同一部分的/8 段,其中列出了%f 说明符:

表示浮点数的double 参数被转换为十进制表示法

这与函数原型中椭圆后面的参数受默认参数提升的影响有关,如6.5.2.2 Function calls 部分,/7 段:

函数原型声明器中的省略号符号导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。

由于printf(以及printf 类函数的整个家族)使用省略号表示法声明为int printf(const char * restrict format, ...);,因此该规则适用于此。默认参数提升在6.5.2.2 Function calls 部分,/6 段中介绍:

如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并且 类型为float 的参数提升为double。这些称为默认参数提升。


对于scanf 系列,它要求使用double 而不是float。科7.21.6.2 The fscanf function /11

指定以下diouxXn 转换说明符适用于类型指针指向long int 或@ 的参数987654390@; 以下aAeEfFgG 转换说明符适用于类型指针指向@987654399 的参数@; 或后面的 cs[ 转换说明符适用于类型指针指向 wchar_t 的参数。

这会修改该部分的/12 段落,该段落声明为%f

匹配可选带符号的浮点数、无穷大或NaN,其格式与strtod 函数的主题序列的预期格式相同。对应的参数应该是一个指向浮动的指针。

【讨论】:

    【解决方案2】:

    对于scanf%f 读入float%lf 读入double

    对于printf:在C99 和更高版本中,它们都是相同的,它们打印floatdouble。在 C89 中,%lf 会导致未定义的行为,尽管将其视为 %f 是一个常见的扩展。

    printf 中一个说明符可用于两种不同类型的原因是 默认参数提升float 类型的参数在用于调用函数并且与函数原型中的参数不匹配时被提升为 double。所以printf 在任何一种情况下都只会看到double

    【讨论】:

      【解决方案3】:

      %lf 中的宽度修饰符被 printf() 优雅地忽略了。或者,更准确地说, %f 采用双精度 - 可变参数将始终将浮点参数提升为双精度。

      【讨论】:

        【解决方案4】:

        对于使用 printf 系列函数的输出,%f 和 %lf 说明符的含义相同; l 被忽略。两者都需要一个对应的 double 类型的参数——但是 float 类型的参数被提升为 double,这就是为什么 float 类型没有单独的说明符。 (这个提升只适用于像 printf 这样的可变参数函数和没有原型声明的函数,而不是一般的函数调用。)对于 long double 类型,正确的格式说明符是 %Lf。

        对于使用 scanf 系列函数的输入,浮点格式说明符是 %f、%lf 和 %Lf。它们分别需要指向 float、double 和 long double 类型对象的指针。 (没有浮点到双精度提升,因为参数是指针。浮点值可以提升为双精度,但浮点*指针不能提升为双精度*,因为指针必须指向实际的浮点对象。 )

        但要小心使用带有数字输入的 scanf 函数。没有定义溢出检查,如果输入超出类型范围,则程序的行为未定义。为了安全起见,将输入读入字符串,然后使用 strtod 之类的东西将其转换为数值。 (请参阅文档以了解如何检测错误。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-30
          • 1970-01-01
          • 2017-01-09
          • 2021-03-24
          • 2011-07-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多