我有一个问题来自我的大三学生,我无法解决它。以下是他在Code::Blocks官方网站下载的Code :: Blocks IDE中使用的代码。
这是一个hello world控制台项目,他刚刚使用头文件math.h
并使用pow()
函数进行了一些修改。
#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()
存在问题。
答案 0 :(得分: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 :(得分:1)
如您所述,pow
会返回一个双精度数。但是,printf
并不知道在堆栈中传递给它的类型,如果你传递double
预期int
,那么它只需要第一个sizeof(int)
来自堆栈的字节并将它们解释为int
。
例如,在我的机器上(g86(GCC)4.4.7 20120313(Red Hat 4.4.7-4)x86_64),该程序打印Hello world! -1954378952
。
如果您希望使用int
将结果视为%d
,则应明确将其转换为:
printf("Hello world! %d\n", (int)pow(2,2));
答案 2 :(得分:1)
printf("Hello world! %d\n",pow(2,2));
“这段代码的输出应该是Hello world!4对吧?”
没有。由于这是未定义的行为,任何事情都可能发生。当@Mureinik发布了在这种错误情况下可能发生的情况时,你可能会理解为什么你看到了0.但最后,C不必以这种方式执行。
...如果任何参数不是相应转换规范的正确类型,则行为未定义.C11§7.21.6.19
转换为(int)
也是一个问题。
1)int
范围远小于double
,而对于pow(2,100)
,则失败。
2)转换为int
截断double
结果的小数部分,并且未定义pow()
的精确度。如果pow()
类似于7.99999999999999
并打印7
而不是希望8.000000
,则会产生令人惊讶的结果。
如果代码需要整数幂函数,请考虑unsigned long long int pow或https://stackoverflow.com/a/213897/2410359或搜索。
答案 3 :(得分:0)
pow(2,2)
将始终返回双倍。
在printf()
%d和%i中,两者都用于打印int。如果使用%d或%i作为double,则会产生问题。
为了显示双重使用%f或%lf,它将为您提供正确答案
printf("Hello world! %f\n",pow(2,2));
或
printf("Hello world! %lf\n",pow(2,2));