void reverseSentence()
{
char c;
scanf("%c", &c);
if(c != '\n')
{
reverseSentence();
printf("%c", c);
}
}
我在这里不明白的是,如果一次又一次调用递归函数,则控件何时进入打印功能并打印调用堆栈?
答案 0 :(得分:2)
当函数调用自身时,printf会一直处于保留状态,直到被调用函数完成为止。
输入“ Hi \ n”后,它将如下所示:
scanf -> H
reverseSentence()
scanf -> i
reverseSentence()
scanf -> \n
return
printf -> i
return
printf -> H
return
逐步调试器可以帮助您理解。
答案 1 :(得分:2)
要了解此代码,让我们首先看一下不可逆版本:
void reverseSentence() {
char c;
scanf("%c", &c);
if (c != '\n')
{
printf("%c",c);
reverseSentence();
}
}
它从stdin读取一个字符,如果该字符不是换行符,则将其写回。然后,它不是通过显式循环,而是通过递归隐式循环以读取和打印下一个字符:
local> echo "The elephants are coming!" | ./a.out
The elephants are coming!local>
该函数在每次递归中读取并打印一个字符。现在,如果我们像原来那样颠倒这两行的顺序:
reverseSentence();
printf("%c",c);
发生同样的事情,除了现在我们要在处理当前字符之前处理下一个字符:
local> echo "The elephants are coming!" | ./a.out
!gnimoc era stnahpele ehTlocal>
在每次递归中仍然读取和写入一个字符,但是利用了以下事实:首先重复发生,然后处理当前项以相反的顺序处理数据。先处理当前项目,然后再重新处理,然后按向前的顺序处理数据。