2014-02-16 4 views
1

Я вызывающая функции по ссылке и вызывающей функцией значения обучения, и я столкнулся проблема в обнаружении, почему она возвращается мне 6561.Почему этот код возвращает мне 6561?

В моей основной функции я назвал функцию f(p,p), где р инициализируется до 5 перед вызовом.

И я определил функции п как:

int f(int &x, int c) 
{ 
    c = c - 1; 
    if (c == 0) 
     return 1; 
    x = x + 1; 
    return f(x,c)*x; 
} 

Почему этот код возврата 6561?

+0

Я думаю, что последняя строка вашей функции вызывает неопределенное/зависящее от компилятора поведение, поскольку переменная x как множитель может быть либо x до того, как функция была вызвана, либо после того, как в зависимости от порядка компилятор оценивает коэффициенты f (x , c) и x in. –

+0

@JamesMcLeod Извините, я не понимаю, что вы только что сказали ... пожалуйста, уточните ... thanx –

+1

Хорошо, давайте попробуем что-то еще - в первый раз вызывается функция f, что значение множителя x? Это 6? Это 10? Это зависит от того, как компилятор обрабатывает линию. Стандарт не говорит, как справиться с этим. –

ответ

3

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

Позвольте мне повторить код:

int f(int &x, int c) 
{ 
    c = c - 1; 
    if (c == 0) 
     return 1; 
    x = x + 1; 
    return f(x,c)*x; 
} 

по-видимому, есть еще одна функция где которая содержит код, как это:

int p = 5; 
result = f(p, p); 

Первое, что нужно отметить тот факт, что он называет себя рекурсивно , Параметр c используется в качестве счетчика для ограничения количества рекурсивных вызовов. Он уменьшается в первой строке f(), и когда он уменьшается до 0, рекурсия останавливается (только что возвращая 1).

С p инициализировано до 5, рекурсия прекращается после 5 вызовов.

В 4-й строке f() параметр x увеличивается.

И, наконец, в последней строке выполняется рекурсивный вызов, передающий ссылку x и декрементированный c.

По-видимому, функция возвращает 6561 в результате 9 * 9 * 9 * 9 (что эквивалентно 9 * 9 * 9 * 9 * 1). Это намек на то, что здесь происходит.

Позволяет следить за данными через рекурсию:

# 0: запись: х = 5, С = 5, как раз перед последней строкой: х = 6, х = 4
# 1: запись: х = 6, c = 4, непосредственно перед последней строкой: x = 7, x = 3
# 2: запись: x = 7, c = 3, непосредственно перед последней строкой: x = 8, x = 2
# 3: запись: x = 8, c = 2, непосредственно перед последней строкой: x = 9, x = 1
# 4: запись: x = 9, c = 1, непосредственно перед строкой 3: x = 9, x = 0 (возвращается в строке 3, возврат 1;)

С return 1 дальнейших рекурсивных вызовов не производится.Теперь мы возвращаемся назад через рекурсии:

# 3: x = 9 => return 1 * 9; (оценивается в 9)
# 2: x = 9 => return 9 * 9; (составляет до 81)
# 1: x = 9 => return 81 * 9; (оценивается в 729)
# 0: x = 9 => return 729 * 9; (до 6561)

Теперь почему x = 9 во всех четырех рекурсивных уровнях? Потому что он передается как ссылка, а не значение. Это означает, что x - это в основном одна и та же переменная в памяти для всех рекурсивных вызовов f() (фактически все x являются псевдонимами для p). Не только x = 9 перед возвратом с первого уровня рекурсии, p будет равен 9 после возврата f().

Хотя вы передаете p для обоих параметров, x одинаково на всех уровнях рекурсии, а x не является (передается по значению). Это должно объяснить разницу.

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

Смежные вопросы