проблема вызова стековой функции - PullRequest
4 голосов
/ 02 сентября 2011

У меня есть функция с именем fun1(), которая используется для рекурсии.Я запутался в связи с первым звонком на этот fun(--n);.Что он будет делать и как мой стек будет загружать мои функции после завершения каждой функции?

void fun(int n)
{
    if(n>0)
    {
        fun(--n);
        printf("%d",n);
        fun(--n);
    }
}

Моя основная функция выглядит следующим образом:

    int a;
    a=3;
    fun(a);

Я хочу знать порядок выполненияи что мой стек будет содержать до, во время и после вызова функции первого fun(--n).

Ответы [ 4 ]

7 голосов
/ 02 сентября 2011

Будет напечатано 0120

                                  (3->[2]->1)
                                       +   +
                                       |   |
                          +------------+   +-------+
                          |                        |
                         ({2}->[1]->0)           ({1}->[0]->-1)
                                +   +                        +
                                |   |                        |
                 +--------------+   +----+                   |
                 |                       |                   +
                 |                       |                  (X)
                 +                       +
                ({1}->[0]->-1)          (0->X)
                       +    +
                       |    |
          +------------+    |
          |                 |
          |                 |
          +                 +
         ({0}->X)          (X)

Выше приведено представление дерева вызовов. Читайте так: первое число в ( ), заключенное в { }, представляет собой значение, которое функция получает за один вызов, следующий номер, следующий за стрелкой, представляет значение, уменьшенное на единицу, и используется для повторного вызова. [ ] представляет при возврате напечатано. Последний номер в ( ) - это значение, которое используется для второго вызова после printf. (X) означает, что он не может попасть в блок if. В конце каждой ( ) фигурной скобки функция возвращается к точке, из которой она возникла (следуйте линиям). Обратите внимание, что значение возвращается после первого вызова.

4 голосов
/ 02 сентября 2011

Что ж, каждый раз, когда вы достигли цели, вы уменьшаете значение n на единицу. Вызовы функций будут опускаться до самого дна, прежде чем что-либо будет напечатано, затем будет вызван один из самых нижних параметров printfs и так далее. Возможно, вы захотите визуализировать нисходящие вызовы следующим образом:

fun(5): *               P
fun(4):  *         P    
fun(3):   *    P         *    P
fun(2):    *  P   P *  P  *  P   P
fun(1):     *P  *P   *P    *P  *P
time -->->->

, где P представляет печать и * новый вызов (вполне может быть, там есть некоторые опечатки). Если вы не делали уменьшение во второй раз, вы получаете W-образный граф вызовов, так как он продолжает идти вниз и вверх снова и вниз, но второй набор вызовов каждой функции находится на «конусе» ниже, поэтому выглядит раздавленным справа. Стек никогда не бывает глубиной более 5 (скажем, если первый вызов был забавным (5)).

Не знаю, поможет ли эта визуализация, но я приложил все усилия с ASCII.

3 голосов
/ 02 сентября 2011

Ваш вывод будет 0, затем 1, затем 2, а затем 0.

  1. Изначально вызывается с 3
  2. Больше 0, это вызывает веселье (- n), что делает его 2.
  3. Это продолжается до тех пор, пока не достигнет 0.
  4. Он продолжается до printf () и печатает 0 на консоли.

То, что вы не видите, это промежуточные звонки. Это полный вывод (перед частью n> 0):

Fun call before n > 0; n = 3
Fun call before n > 0; n = 2
Fun call before n > 0; n = 1
Fun call before n > 0; n = 0
0
Fun call before n > 0; n = -1
1
Fun call before n > 0; n = 0
2
Fun call before n > 0; n = 1
Fun call before n > 0; n = 0
0
Fun call before n > 0; n = -1
0 голосов
/ 02 сентября 2011

Должно выглядеть примерно так:

в начале: fun (3) первый вызов: fun (2) в конце: fun (1)

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