Scanf / Printf双变量C.

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

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

它从stdin变量’var’读取,然后在stdout’var’中打印两次。 我理解你是如何从stdin读取双变量的,但我的问题是:

  1. 为什么你可以用%lf打印双倍?
  2. 为什么你可以用%f打印双倍?
  3. 使用哪一种更好更正确?

对于像printfscanf这样的变量参数函数,会提升参数,例如,任何较小的整数类型都会提升为intfloat会提升为double

scanf接受指针参数,因此促销规则不起作用。 它必须使用%f表示float*%lf表示double*

printf永远不会看到float参数, float总是被提升为double 。 格式说明符是%f 。 但是C99还说%lfprintf %f相同:

C99§7.19.6.1fprintf函数

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

float传递给printf ,它会自动转换为double 。 这是默认参数提升的一部分,它适用于具有可变参数列表(包含... )的函数,主要是出于历史原因。 因此, float的“自然”说明符%f必须使用double参数。 所以printf%f%lf说明符是相同的; 他们都采取double价值。

调用scanf ,会传递指针,而不是直接值。 指向float的指针不会转换为指向double的指针(由于指针对象在更改指针类型时无法更改,因此无法工作)。 因此,对于scanf%f的参数必须是指向float的指针,而%lf的参数必须是指向double的指针。

至于我阅读手册页,scanf说’l’长度修饰符表示(在浮点的情况下)参数是double类型而不是float类型,所以你可以有’lf,le,lg’。

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

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

因此,如果您的标准支持语法,您可能需要重复检查。

总而言之,我会说你用’%lf’阅读并用’%f’打印。