C语言 Scanf/Printf 双变量 C

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19952200/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:57:31  来源:igfitidea点击:

Scanf/Printf double variable C

cdoubleprintfstdoutstdin

提问by Dragos Rizescu

Let's say I have this following bit of code in C:

假设我在 C 中有以下代码:

double var;
scanf("%lf", &var);
printf("%lf", var);
printf("%f", var);

It reads from stdin variable 'var' and then prints twice in stdout 'var'. I understand that's how you read a double variable from stdin, but my questions are:

它从标准输入变量“var”中读取,然后在标准输出“var”中打印两次。我知道这就是您从标准输入读取双变量的方式,但我的问题是:

  1. Why can you print a double with %lf?
  2. Why can you print a double with %f?
  3. Which one is better and correct to use?
  1. 为什么可以用 %lf 打印双精度值?
  2. 为什么可以用 %f 打印双精度值?
  3. 哪一种更好且正确使用?

回答by Yu Hao

For variable argument functions like printfand scanf, the arguments are promoted, for example, any smaller integer types are promoted to int, floatis promoted to double.

对于像printf和这样的可变参数函数scanf,参数被提升,例如,任何较小的整数类型被提升为intfloat被提升为double

scanftakes parameters of pointers, so the promotion rule takes no effect. It must use %ffor float*and %lffor double*.

scanf接受指针的参数,所以提升规则不起作用。它必须使用%fforfloat*%lffor double*

printfwill never see a floatargument, floatis always promoted to double. The format specifier is %f. But C99 also says %lfis the same as %fin printf:

printf永远不会看到一个float论点,float总是被提升为double。格式说明符是%f. 但是C99也说%lf是一样%fprintf

C99 §7.19.6.1 The fprintffunction

l(ell) Specifies that a following d, i, o, u, x, or Xconversion specifier applies to a long intor unsigned long intargument; that a following nconversion specifier applies to a pointer to a long intargument; that a following cconversion specifier applies to a wint_targument; that a following sconversion specifier applies to a pointer to a wchar_targument; or has no effect on a following a, A, e, E, f, F, g, or Gconversion specifier.

C99 §7.19.6.1fprintf函数

l(ell) 指定后面的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转换说明符没有影响。

回答by Eric Postpischil

When a floatis passed to printf, it is automatically converted to a double. This is part of the default argument promotions, which apply to functions that have a variable parameter list (containing ...), largely for historical reasons. Therefore, the “natural” specifier for a float, %f, must work with a doubleargument. So the %fand %lfspecifiers for printfare the same; they both take a doublevalue.

当 afloat传递给 时printf,它会自动转换为 a double。这是默认参数 Promotions 的一部分,它适用于具有可变参数列表(包含...)的函数,这主要是出于历史原因。因此,“自然”说明符的float%f必须有一个工作double的说法。所以for%f%lf说明符printf是一样的;它们都double取值。

When scanfis called, pointers are passed, not direct values. A pointer to floatis not converted to a pointer to double(this could not work since the pointed-to object cannot change when you change the pointer type). So, for scanf, the argument for %fmust be a pointer to float, and the argument for %lfmust be a pointer to double.

scanf被调用时,指针传递,而不是直接的价值。指向的指针float不会转换为指向的指针double(这是行不通的,因为当您更改指针类型时,指向的对象无法更改)。因此,对于 , forscanf的参数%f必须是指向 的指针float,而 for 的参数%lf必须是指向 的指针double

回答by Artem Shinkarov

As far as I read manual pages, scanf says that 'l' length modifier indicates (in case of floating points) that the argument is of type double rather than of type float, so you can have 'lf, le, lg'.

就我阅读的手册页而言,scanf 表示 'l' 长度修饰符表示(在浮点的情况下)参数是 double 类型而不是 float 类型,因此您可以使用 'lf, le, lg'。

As for printing, officially, the manual says that 'l' applies only to integer types. So it might be not supported on some systems or by some standards. For instance, I get the following error message when compiling with gcc -Wall -Wextra -pedantic

至于打印,官方手册说“l”仅适用于整数类型。因此,某些系统或某些标准可能不支持它。例如,我在编译时收到以下错误消息gcc -Wall -Wextra -pedantic

a.c:6:1: warning: ISO C90 does not support the ‘%lf' gnu_printf format [-Wformat=]

So you may want to doublecheck if your standard supports the syntax.

因此,您可能需要仔细检查您的标准是否支持该语法。

To conclude, I would say that you read with '%lf' and you print with '%f'.

总而言之,我会说您使用“%lf”阅读并使用“%f”打印。