我有一个名为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)
的函数调用之前,期间和之后将包含的内容。
答案 0 :(得分:7)
它会打印0120
(3->[2]->1)
+ +
| |
+------------+ +-------+
| |
({2}->[1]->0) ({1}->[0]->-1)
+ + +
| | |
+--------------+ +----+ |
| | +
| | (X)
+ +
({1}->[0]->-1) (0->X)
+ +
| |
+------------+ |
| |
| |
+ +
({0}->X) (X)
以上是调用树的表示。如下所示:( )
中包含{ }
的第一个数字是函数为一次调用接收的值,箭头后面的下一个数字表示减1的值,用于重拨。 [ ]
表示返回时打印。 ( )
中的最后一个数字是用于printf
之后的第二个呼叫的值。 (X)
表示无法进入if
块。在每个( )
括号的末尾,函数返回到它起源的点(跟随行)。请注意,在第一次调用返回后,将打印该值。
答案 1 :(得分:4)
好吧,每次预先计划时,都会将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的调用图,因为它会一直向下和向下调整,但每个函数的第二组调用都在'cone'下面,所以它看起来被压扁在右边。堆栈永远不会超过5深(如果第一次调用很有趣(5),比如说。)
不知道这种可视化是否有帮助,但我尽力使用ASCII。
答案 2 :(得分:3)
您的输出将为0,然后是1,然后是2,然后是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
答案 3 :(得分:-2)
应该是这样的:
开始时:有趣(3) 第一个电话:有趣(2) 在结束时:有趣(1)