Recursion 斐波那契递归:返回地址?

Recursion 斐波那契递归:返回地址?,recursion,stack,fibonacci,Recursion,Stack,Fibonacci,通常,当对函数进行递归调用时,堆栈中的返回地址指向函数调用后的下一条指令。但是在斐波那契码中,返回地址指向哪里?i、 e.“+”运算符后的下一行或剩余代码行 int Fibonacci(int x) { if (x == 0) return 0; // Stopping conditions if (x == 1) return 1; return Fibonacci(x - 1)/*cond1*/ + Fibonacci(x - 2);/*cond2*/ }

通常,当对函数进行递归调用时,堆栈中的返回地址指向函数调用后的下一条指令。但是在斐波那契码中,返回地址指向哪里?i、 e.“+”运算符后的下一行或剩余代码行

 int Fibonacci(int x) { 
   if (x == 0) return 0;  // Stopping conditions 
   if (x == 1) return 1; 
   return Fibonacci(x - 1)/*cond1*/ + Fibonacci(x - 2);/*cond2*/ 
 }
就我对递归的理解而言,cond1会一直执行,直到返回0或1值(即递归树最左边的分支上的深度优先),然后只执行cond2,依此类推。是这样吗?当控件执行斐波那契(x-1)时,返回地址将保存为堆栈中的什么(即EBP)


是的,你对递归的理解是正确的。它将像DFS一样工作

关于返回地址:回想一下,一行代码不是一条指令。事实上,一行代码可以产生很多指令

在这种情况下,编译器将生成类似以下内容的代码:

a = call Fibonacci(x-1)
b = call Fibonacci(x-2)
c = add a, b
return c
因此,
Fibonacci(x-1)
的返回地址是下一条指令的地址——在本例中,是调用
Fibonacci(x-2)
的指令。但是,请注意,大多数语言并不能保证操作数的求值顺序,您所知道的是,
+
的两个操作数在执行加法之前都已完全求值。实际上,您可以改为:

a = call Fibonacci(x-2)
b = call Fibonacci(x-1)
c = add a, b
return c

关键是,其中一个递归调用的返回地址将是第二次调用指令的地址,第二次调用的返回地址将是一条
ADD
指令。

是的,你是对的。这种DFS的类型也被称为预排序,首先访问根,然后遍历左子树,然后遍历右子树。因此,基本上,如果我有3个这样的递归调用的总和,那么第一个的返回地址将指向第二个,第二个到第三个和第三个到那一点为止所获得的结果的相加?@Dubby Yes。但是请记住,当您查看代码时,第一、第二和第三不一定是相同的。出于优化的原因,编译器可以按照它认为方便的任何顺序计算操作数。谢谢@Filipe Gonçalves
a = call Fibonacci(x-2)
b = call Fibonacci(x-1)
c = add a, b
return c