我无法理解为什么会发生这种情况: 使用以下代码;
#include <stdio.h>
int main()
{
double x=123;
printf("x is %f. Enter a new value for x.\n", x);
scanf("%f", &x);
printf("x is %f\n", x);
return 0;
}
当您输入45678作为x的新值时,将打印“x为123.000017”。 我知道在扫描时使用%lf时这是固定的,但为什么在使用%f?
时会发生这种情况答案 0 :(得分:3)
我知道在扫描时使用%lf时这是固定的,但为什么在使用%f时会发生这种情况?
printf
和scanf
函数参数之间的区别在于您将值传递给printf
,但是传递给scanf
指针(即值的地址)。根据C规则,当函数采用可变数量的参数时,所有参数都经历default promotions。
其中一项促销活动是float
转换为double
,与short
转换为int
的方式相同。这就是为什么您可以将%f
或%lf
与printf
一起使用:编译器将这两种类型的值转换为double
,因此访问它们是安全的。
但是,指针没有这样的规则(并且有充分的理由:尝试将double
写入float
的空间将是未定义的行为。这就是为什么在将参数传递给%f
函数族时必须区分%lf
和scanf
的原因。
答案 1 :(得分:1)
scanf("%f", &x);
应该是
scanf("%lf", &x);
printf
和scanf
之间的浮点转换说明符存在错误对称。
另请注意,lf
转换说明符等同于f
中的printf
转换说明符(因为c99,之前未定义)。
我知道在扫描时使用%lf时这是固定的,但为什么在使用%f时会发生这种情况?
f
中的 scanf
转换说明符需要一个指向float
的类型指针的参数。通过将类型指针的参数传递给double
,您可以调用未定义的行为。