解释这个递归函数(在C中)

eri*_*sse 1 c recursion

我无法理解这个反向功能是如何工作的.我已经尝试在纸上逐步解决代码所做的事情,但这对我来说没有意义.我对代码所做的最好的(尽管粗略的)解释是这样的:

http://s7.postimg.org/632xhovwr/recursion_confusion.png

#include <stdio.h>
#include <string.h>
#define MAX 1000

void reverse(char s[]);

main()
{
    char str[] = "remotes";

    printf("Before: %s\n",str);
    reverse(str);
    printf("After: %s\n",str);

    system("Pause");
    return 0;
}

void reverse(char s[])
{
    static int i = 0, n;
    char c = s[i];

    if (c != '\0') {
        ++i;
        reverse(s);
        s[n-i] = c;
        --i;
    } 
    else {
        n = i;
    }
}
Run Code Online (Sandbox Code Playgroud)

通常,当递归是代码的最后一步时,我没有使用递归函数的问题,因为你应用递归直到一些终止条件和向后级联的类型.但是当递归调用之前和之后有代码时,它会让事情变得更加混乱.

Dre*_*fer 5

您在纸面上分析是正确的-诀窍是n和i是静态的(每个堆栈帧指的是可变的同一个实例),而c在栈上分配(所以每个堆栈帧都有自己的副本).

代一些值到您的分析,以及使用c,c',c'',和c'''来表示的不同的堆栈帧的实例c:

// original function call: stack frame 0
c = str[0]
i = 1

 // stack frame 1
 c' = str[1]
 i = 2

  // stack frame 2
  c'' = str[2]
  i = 3

   // stack frame 3
   c''' = str[3]
   i = 4

    // stack frame 4
    n = 4

   // unwinding: stack frame 3
   str[0] = c'''
   i = 3

  // unwinding: stack frame 2
  str[1] = c''
  i = 2

 // unwinding: stack frame 1
 str[2] = c'
 i = 1

// unwinding: stack frame 0 (original function call)
str[3] = c
i = 0
Run Code Online (Sandbox Code Playgroud)

编辑:解决你的评论:不要放弃理解递归!一旦你有一个坚实的句柄并且可以"递归思考",就很容易编写使你看起来比你聪明的代码(一种非常有用的技能!).例如,对reverse()函数的轻微重构可以创建更小的版本:

void reverse(char s[])
{
    static int i = 0;
    char c = s[i++];
    if (c) {
        reverse(s);
        s[i++] = c;
    }
    i = c ? i : (int)c;
}
Run Code Online (Sandbox Code Playgroud)

所以真的,原作者通过比必要更冗长来帮助你:-)