对不起,如果我做错了,我对C真的很陌生,以前没有使用过堆栈溢出。我试图用手跟踪此简单的递归函数,但从编译的代码中得到了不同的答案。
我的思考过程是
打印2 | n = 2-1 = 1 | 1> = 0 |倒数计时(1)
打印1 | n = 1-1 = 0 | 0> = 0 |倒数计时(0)
打印0 | n = 0-1 = -1 | -1不是> = 0 |
打印-1 |结束
void countdown(int n)
{
printf ("n = %d\t", n);
n--;
if (n >= 0)
{
countdown(n);
}
printf ("n = %d\t", n);
}
int main ( )
{
countdown(2);
return 0;
}
我希望得到:n = 2 n = 1 n = 0 n = -1
但是编译后的代码给了我:n = 2 n = 1 n = 0 n = -1 n = 0 n = 1
我不确定-1之后的0和1来自何处
答案 0 :(得分:1)
您的代码执行以下操作(省略if):
#innodb_force_recovery = 1
对于n = 2:
countdown(n):
print(n)
countdown(n-1)
print(n-1)
答案 1 :(得分:0)
您的代码没有问题。只需删除第二个printf
代码即可。
void countdown(int n)
{
printf("n = %d\t", n);
n--;
if (n >= 0)
countdown(n);
}
int main()
{
countdown(2);
return 0;
}
结果是:
n = 2 n = 1 n = 0
这是我在2nd printf
捕获时的调用堆栈。
StudyCpp.exe!countdown(int n) line 16 C++ // It is 2nd printf of countdown(0). Now, n is -1.
StudyCpp.exe!countdown(int n) line 14 C++ // It called countdown(0)
StudyCpp.exe!countdown(int n) line 14 C++ // It called countdown(1)
StudyCpp.exe!main() line 21 C++ // It called countdown(2)
如果再进行一次调试,则可以看到如下所示的调用堆栈:
StudyCpp.exe!countdown(int n) line 16 C++ // It is 2nd printf of countdown(1) after executed countdown(0).
StudyCpp.exe!countdown(int n) line 14 C++ // It called countdown(1)
StudyCpp.exe!main() line 21 C++ // It called countdown(2)
而且,如果再进行一次调试,则可以看到如下所示的调用堆栈:
StudyCpp.exe!countdown(int n) line 16 C++ // It is 2nd printf of countdown(2) after executed countdown(1).
StudyCpp.exe!main() line 21 C++ // It called countdown(2)
最后,程序将退出。
答案 2 :(得分:0)
这里您递归地调用countdown(),被称为三次。
实际上,每个递归调用都会将countdown()推入堆栈。
SF1(Bottom of stack) ---> SF2 ---> SF3 (Top of stack).
现在将执行顶部的框架。
从函数返回期间,将弹出特定的堆栈框架。
现在,堆栈帧指针指向SF2,然后指向SF1。
考虑程序,以下是流程。
推送操作:
SF1将首先被压入堆栈
n = 2 printed.
Again n updated to 1
SF2已推送:
n = 1 got printed.
Again n updated to 0
SF3已推送:
n = 0 got printed.
Again n updated to -1.
But n <= 0, So if check fails.
弹出操作:
现在,SF3首先从堆栈中弹出。
n = -1 printed
然后SF2弹出
prints n = 0.
最后SF1
n = 1 printed