我无法理解这个反向功能是如何工作的.我已经尝试在纸上逐步解决代码所做的事情,但这对我来说没有意义.我对代码所做的最好的(尽管粗略的)解释是这样的:
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)
通常,当递归是代码的最后一步时,我没有使用递归函数的问题,因为你应用递归直到一些终止条件和向后级联的类型.但是当递归调用之前和之后有代码时,它会让事情变得更加混乱.
您在纸面上分析是正确的-诀窍是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)
所以真的,原作者通过比必要更冗长来帮助你:-)