关于Code:: Blocks中不能输出double类型数据问题总结说明

最新在练习C Primer Plus中的编程题,其中有一个题如下:

编写一个程序,提示用户输入一个double类型的数,并打印该数的立方值。自己设计一个函数计算并打印立方值。main()函数要把用户输入的值传递给该函数。

看了这题目应该是个很简单的,于是自己编写了程序,如下:

#include 
#include 
int main(void)
{
 void fun(double m);
 double a;
 scanf("%lf",&a);
 fun(a);
 return 0;
}

void fun(double m)
{
 printf("%.2lf",m*m*m);

}

相信大家看了这代码后,也会觉得没有啥问题,但是我编译,运行后,输入一个数,输出结果却是不对的。我就纳闷了,明明编写没有问题,输出结果怎么会是错误的,开始以为是编译器设置是不是有问题了,我重新选择了C99,或C11或C90等,试了试还是错误的,后来网上查了之后,发现也有好多人遇到类似的问题,最终得到了答案是:

printf中,%f通杀单精度和双精度
在scanf中,%f和%lf才有区别

官方给出的解释为;

在C89中明确说明
printf("%lf", (doube)d);
的结果是未定义的。
An optional h specifying that a following d, i, o, u, x, or X conversion specifier applies to a short int or unsigned short int argument (the argument will have been promoted according to the integral promotions, and its value shall be converted to short int or unsigned short int before printing); an optional h specifying that a following n conversion specifier applies to a pointer to a short int argument; an optional l (ell) specifying that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument; an optional l specifying that a following n conversion specifier applies to a pointer to a long int argument; or an optional L specifying that a following e, E, f, g, or G conversion specifier applies to a long double argument. If an h, l, or L appears with any other conversion specifier, the behavior is undefined. 

C99中则说
printf("%lf", (doube)d);
相当于
printf("%f", (doube)d);

l (ell) Specifies that a following d, i, o, u, x, or X conversion specifier applies to a
long int or unsigned long int argument; that a following n conversion specifier applies to a pointer to a long int argument; that a following c conversion specifier applies to a wint_t argument; that a following s conversion specifier applies to a pointer to a wchar_t argument; or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

其他给出的解释:

printf 的 %f 标识符的确既可以输出浮点数又可以输出双精度数。根据  ``缺省参数扩展" 规则, 不论范围内有没有原形都会在在类似 printf 的可变长度参数列表中采用, 浮点型的变量或扩展为双精度型, 因此 printf()  只会看到双精度数。
scanf,它接受指针,这里没有类似的类型提升。(通过指针)向float存储和向double存储大不一样,因此,scanf区别%f和%lf.

终于明白是怎么回事后,我于是按照要求重新修改了代码,编译运行后,输入一个数,输出的结果是对了,代码如下:

#include 
#include 
int main(void)
{
 void fun(double m);
 double a;
 scanf("%lf",&a);
 fun(a);
 return 0;
}

void fun(double m)
{
 printf("%.2f",m*m*m);

}

总结:看似简单的编程练习题,里面却包含这么多的知识点,对C语言又有进一步的了解。

 

 

你可能感兴趣的:(问题总结,C笔记,个人笔记)