вопрос по c ++ рекурсии и локальным переменным - PullRequest
7 голосов
/ 02 мая 2011

предположим, у меня есть эта рекурсия:

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, которые действительнытолько для этой стадии в дереве рекурсии?

Ответы [ 5 ]

9 голосов
/ 02 мая 2011

Будет ли область действия 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

4 голосов
/ 02 мая 2011

Каждый вызов получает свою собственную копию переменных.Присвоение копии в одном вызове функции не влияет на версии в любом другом вызове функции.Вот почему рекурсия должна связываться между «этапами», передавая аргументы и возвращая значение.

2 голосов
/ 02 мая 2011

да, x и y являются переменными стека и, таким образом, независимы между каждым вызовом. Новые, основанные на стеке x и y будут создаваться для каждого вызова doSomething.

Если вы хотите, чтобы они были одинаковыми переменными в каждом вызове, вы должны объявить их static

0 голосов
/ 02 мая 2011

Вы передаете значение 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 ;
}

Обратите внимание на & после двойного, это говорит компилятору, что функция принимает значение двойного по своему адресу, который вызывается достаточно соответствующим образом, передавая по адресу. Здесь в дочернем элементе каждого 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 ;
}
0 голосов
/ 02 мая 2011

Каждый раз, когда вызывается функция, создаются новые локальные переменные x и y, которые не связаны с любым другим вызовом функции. Это то, что отличает локальные переменные от глобальных переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...