假设我有这个递归:
void doSomething(double j)
{
double x;
double y;
x = j -1;
y = j -2 ;
doSomething(x+y);
x = j + 31;
y = j + 12 ;
}
我知道这个递归无限执行,但只是忽略了
我的问题是关于变量x和y在递归树中的范围... x和y的范围是否仅对递归树中特定阶段的函数有效?或者当我再次调用doSomething()时,当递归树中的子doSomething()重新声明x和y时,它是否会重置父项的x和y变量,或者它是否创建了一个全新的x和y变量,它们是有效的仅在递归树中的那个阶段?
答案 0 :(得分:9)
x和y的范围是否仅对递归树中特定阶段的函数有效?
是
当我再次调用doSomething(),并且递归树中的子doSomething()重新声明x和y时,它会重置父项的x和y变量
没有
是否只创建了一个全新的x和y变量,这些变量只对递归树中的那个阶段有效?
是
编辑1: 这个例子应该会有所帮助。
#include <iostream>
void foo( int temp )
{
int num = temp;
if( temp == 0)
return;
foo(temp-1) ;
std::cout << &num << "\t" << num << "\n" ;
}
int main()
{
foo(5) ;
return 0;
}
<强>输出:强>
0xbfa4e2d0 1
0xbfa4e300 2
0xbfa4e330 3
0xbfa4e360 4
0xbfa4e390 5
请注意num
的地址不同,每次调用都有自己的num
值。
Ideone
答案 1 :(得分:4)
每次调用都有自己的变量副本。在一个函数调用中分配给副本对任何其他函数调用中的版本没有影响。这就是为什么递归必须通过传递参数和返回值来在“阶段”之间进行通信。
答案 2 :(得分:2)
是的,x和y是堆栈变量,因此在每次调用之间是独立的。每次调用doSomething
时都会创建一个基于堆栈的全新x和y。
如果您希望它们在每个调用中都是相同的变量,则应声明它们static
答案 3 :(得分:0)
每次调用函数时,都会创建新的局部变量x
和y
,这与函数的任何其他调用无关。这就是本地变量与全局变量不同的原因。
答案 4 :(得分:0)
您将x + y按值传递到函数doSomething()中。这意味着在函数堆栈上,doSomething()可以访问一个局部变量j,其值从堆栈下面的函数设置为x + y计算的值(即调用它们的函数)。由于此变量与父函数中的变量完全分开,因此修改其值不会影响堆栈下面的变量。
但是,如果您希望j与父函数中的变量完全相同,那么您可以执行以下操作:
void doSomething( double& j )
{
double x = j - 1;
double y = j - 2;
double willChange = x + y;
doSomething( willChange );
x = j + 31;
y = j + 12 ;
}
注意&amp;在double之后,这告诉编译器该函数通过其地址接受double的值,该地址被称为足够通过地址传递。在每个doSomething()的子节点中,j是堆栈下面函数中变量willChange的别名。
如果你想特别修改x和y,那么可能会做类似
的事情void doSomething( double& x, double& y )
{
double j = x + y
double x = j - 1;
double y = j - 2;
doSomething( x, y );
x = j + 31;
y = j + 12 ;
}