我被告知在while循环中实现函数而不是递归函数。到目前为止,我总是得到错误的答案。任何关于我犯错误的指标都将受到赞赏。 我正在尝试计算2 ^ 12,但到目前为止,每当我运行程序时它给了我4.原始问题然后我创建这个线程已经解决了。但我有一个与前一个问题有关的新问题,但需要采用不同的方法
#include <stdio.h>
double powerloop(double x, int y, double help)
{
while(y!=0)
{
if((y%2)==0)
{
x=x*x;
y=y/2;
}
if((y%2)==1)
{
help=help*x;
x=x*x;
y=(y-1)/2;
}
if(y==1)
{
x=x*help;
}
return x;
}
}
int main(void){
printf("Using powerloop to calculate 2^12: %f \n", powerloop(2, 12, 1));
return 0;
}
答案 0 :(得分:5)
两个问题:
1。以下测试错误:
if(y & 2 == 0)
你想要
if((y % 2) == 0)
模数%运算符与&#34;按位和&#34;不完全相同用2。
2. 初始线
double num=power(x, y/2);
导致堆栈溢出。在Visual C ++中,它也给了我一个明确的警告:&#34; C4717:&#39; power&#39;:递归所有控制路径&#34;
递归总是绝对需要一个停止的结束条件。
你在power()中做的第一件事就是再次调用power(),再次,再次调用....再次:
double power(double x, int y) {
double num=power(x, y/2); // <- call myself again forever
// other code
}
由于没有与该呼叫相关联的停止条件,您将永远调用power() - 或者直到总是有限的调用堆栈最终耗尽。
请记住,每次调用power()的返回地址至少都存储在堆栈中。将您的实现与正确的算法进行比较。你会发现第一个电话不在那里,而是更像是这样:
double power(double x, int y)
{
if(x==0) {
return 0; // stops recursion
}
if(y==0) {
return 1; // stops recursion
}
if( (y % 2) == 0) {
num=num*num;
y=y/2;
return num; // stops recursion
}
num=x*power(x, y-1); // another recursive call
y=y-1;
return num;
}
答案 1 :(得分:3)
你的无限递归
double power(double x, int y) {
double num=power(x, y/2);
/* .... */
}
power()将无条件地自行调用。我没有检查算法本身,但你需要检查一下......
答案 2 :(得分:1)
毫无疑问,你正在遭遇堆栈溢出。
行:
double power(double x, int y)
{
double num=power(x, y/2);
结果power
呼叫power
呼叫power
呼叫power
......没有机会再回来。
每次调用函数时,返回地址都会被压入堆栈。你继续这样做,没有return
来从堆栈中弹出地址,你最终会耗尽空间并获得段错误。
这个递归算法中的终止条件是缺少的,即执行 not 导致递归路径的代码路径。
答案 3 :(得分:1)
假设你称之为权力(3.0,10)。
你的功能首先要做的是调用电源(3.0,5)。
呼叫的第一件事是呼叫电源(3.0,2)。
呼叫的第一件事就是呼叫电源(3.0,1)。
调用的第一件事就是调用电源(3.0,0)。
调用的第一件事就是调用电源(3.0,0)。
调用的第一件事就是调用电源(3.0,0)。
调用的第一件事就是调用电源(3.0,0)。
调用的第一件事就是调用电源(3.0,0)。
调用的第一件事就是调用电源(3.0,0)。
...
几百万次呼叫后,您会收到“分段错误”。
答案 4 :(得分:1)
您的return x
应该在最后if
声明的范围内。