C语言中使用scanf函数无法存储double类型的值

3

所发生的情况是我请求用户输入,然后使用scanf将其存储到变量中。

但是当我尝试检索该值时,它只是0.000000。我确定我只是犯了愚蠢的错误,但是您能提供的任何帮助都将不胜感激。

printf("Enter the radius of your circle/sphere: ");
scanf("%f", &radius);

printf("\n%f", radius);

示例:

请输入你的圆/球体半径:10

0.0000000

感谢您的时间!


8
你是否尝试过使用 %lf(如果你的变量 radius 是一个 double 类型的话,因为你没有展示你的声明)? - AntonH
1
还应该检查scanf的返回值。 - Ed Heal
2
如果我把这些内容放在答案里而不是评论里,我的声誉会更好:D - AntonH
你是如何声明半径的? - Jekyll
谢谢!Radius是一个双精度浮点数。我不知道我应该使用lf来表示双精度浮点数。非常感谢你的帮助! - UnlovedPanda
可能是scanf和double类型的问题的重复。 - phuclv
2个回答

5
正如@Chris McGrath所回答的那样,您必须使用%lf格式说明符来表示双精度类型。然而,这并不能解释为什么%f格式说明符在printf中也能正常工作。 %lf代表长浮点型,即double。当float类型的值被传递给可变参数函数(接受可变数量参数的函数,如printfscanf),它们会被隐式提升为double类型。
float val;
printf("%f", val);   /* printf receives val cast to double, the same
                        as printf("%f", (double) val) */
printf("%lf", val);  /* printf also receives val cast to double, the
                        same as printf("%lf", (double) val) */

既然 printf("%lf", ...)printf("%f", ...) 都接收一个 double,所以这两者完全等价。

另一方面,所有传递给 scanf 的参数都是指针。 scanf("%f", ...) 希望接收一个 float *,而 scanf("%lf", ...) 则希望接收一个 double *

float floatval;
double dblval;
scanf("%f", &floatval); /* stores a float value to address received */
scanf("%lf", &dblval);  /* stores a double value to address received */

两个指针指向不同类型,因此一个不能升级到另一个。如果它们被 scanf 相同对待,那么最终会将相同的值存储到分配给不同大小类型的地址中,这是行不通的。
这就是为什么在使用 double 值时,scanf 严格要求使用 %lf 指示符的原因。

"long float" 不是 "double" 的同义词,它是语法错误。浮点类型有 "float"、"double" 和 "long double"。 - Keith Thompson
1
我不再这样做了! - Keith Thompson
@barakmanos 那个问题的答案基本上和我第一部分回答的相同,我在那里解释了为什么 printf%f%lf 是相同的。这个答案更进一步解释了为什么它们在 scanf不同,因为 scanf 并不直接接收变长浮点数值,而是指向它们的指针。指针不会(也不能)遵循默认提升规则,所以 %lf%f 必须执行不同的操作,以存储不同类型的值。 [另一个答案](https://dev59.com/hXVC5IYBdhLWcg3wsTbv#210591)表述了同样的观点,但没有解释原因。 - user4815162342
@user4815162342:哦!!!!scanf需要指针,当然了!!!抱歉,我应该意识到这一点(或者更仔细地阅读你的答案)...谢谢,给了你十英镑 :) - barak manos
附加说明:C89没有printf(“%lf”,...),尽管许多编译器将其作为扩展实现。 直到C99才正式添加。 C89指定%ffloatdouble的格式说明符。 - M.M
显示剩余3条评论

0
正如AntonH所说,如果半径被声明为double类型,那么你必须使用%lf格式说明符:
scanf("%lf", &radius);

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