Code::Blocks IDE中pow函数无法正常工作

3

我收到了我的下属的一个问题,但是我无法解决。以下是他从Code::Blocks官方网站下载的IDE中使用的代码。

这是一个hello world控制台项目,他只是稍微修改了一下,使用了头文件math.hpow()函数。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    printf("Hello world! %d\n",pow(2,2));
    return 0;
}

这段代码的输出应该是Hello world! 4,对吧?但是,实际上总是Hello world! 0,除非使用printf("Hello world! %f\n", pow(2,2));,这样语法上没问题,也是正确的做法。但接下来就变成了另一回事。
Pow函数应该返回一个值为4的double类型。那么到底发生了什么呢?printf()不起作用了,或者pow()存在某些问题。

2
返回值是 double,因此您必须将其转换为 (int) - Rizier123
2
如果您正在使用GCC,请添加“-Wall”,您将会被告知%d格式与double值之间的不匹配。 - Jonathan Leffler
4个回答

2
pow() 函数的返回值是 double,您可以在此处查看:

http://www.tutorialspoint.com/c_standard_library/c_function_pow.htm

因此,您需要将返回值强制转换为 int,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    printf("Hello world! %d\n",(int)pow(2,2));
    return 0;
}

否则,如您所见,输出为0!
另一个示例以证明此事,您可以尝试以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    printf("Hello world! %d\n",4.000000);
    return 0;
}

正如您所看到的,输出结果也为0,因为它是一个双精度值!


1
正如你所提到的,pow返回一个双精度浮点数。然而,printf并不知道在堆栈中传递给它的类型,如果你将一个double传递给需要int的参数位置,它将简单地从堆栈中取出前sizeof(int)字节并把它们解释为一个int。例如,在我的机器上(gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-4)上的x86_64),这个程序打印了Hello world!-1954378952
如果你想使用%d将结果视为int,你应该明确将其强制转换为int
printf("Hello world! %d\n", (int)pow(2,2));

1

printf("Hello world! %d\n",pow(2,2));
这段代码的输出应该是“Hello world! 4”,对吗?

不是的。由于这是未定义的行为,任何事情都有可能发生。正如@Mureinik在这种错误情况下所发表的内容,您可能会对为什么看到0有一个可能的理解。但最终,C语言不一定会以这种方式执行。

...如果任何参数不是相应转换说明符的正确类型,则行为是未定义的。 C11 §7.21.6.1 9

将其强制转换为(int)也是有问题的。

1)int范围要小得多,无法处理pow(2,100)

2)将double强制转换为int会截断结果的小数部分,pow()的精度未定义。当pow()的输入为类似于7.99999999999999时,输出结果可能出乎意料地是7而非期望的8.000000

如果代码需要整数幂函数,请考虑使用unsigned long long int pow或者https://dev59.com/IXVC5IYBdhLWcg3wsTVi#213897,或者搜索相关资料。


0

pow(2,2)总是返回一个double。

printf()中,%d和%i都用于打印int。如果您使用%d或%i来打印double,它会创建问题。为了显示double,请使用%f或%lf,这将给您正确的答案。

    printf("Hello world! %f\n",pow(2,2));

或者

    printf("Hello world! %lf\n",pow(2,2));

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