下面是一个示例C程序,它提供程序后的输出
#include<stdio.h>
void newfunc(int n);
int main(void)
{
newfunc(2);
return 0;
}
void newfunc(int n)
{
printf("\n%d",n);
if(n<50)
{
newfunc(2*n);
printf("\n%d",n);
}
}
产生输出
2
4
8
16
32
64
32
16
8
4
2
但根据代码,似乎在第13行的函数调用之后,未调用下一个printf
。输出似乎不自然。我在互联网上搜索了一些关于堆栈的东西。有人能详细说明为什么会这样吗?
答案 0 :(得分:3)
这是一个基本的递归调用。
首先,请注意,对于n
小于50的值,您的函数将打印n
两次,而对于n
的其他值,它将只打印一次。这与你的输出一致,所以这里唯一要弄清楚的是订单......
第二次注意n*2
的输出介于<{1}}(n
)的第一行和第二行之间,因为你制作了两个n < 50
之间的递归调用。那么,也同意你的输出。
这是预期的。
您在互联网上找到的关于堆栈的部分是指调用堆栈。为了从函数返回,程序必须跟踪调用函数时的位置。该信息被写入称为“调用堆栈”或“执行堆栈”的特殊存储器部分的“末尾”;并且它从堆栈中取出(意味着当函数返回时'end'被移动)。呼叫参数也记录在堆栈中。
这种堆叠对于递归至关重要。
因此,当你调用printf
程序记录它在第5行时,然后跳转到第8行的newfunc(2)
的开头。堆栈看起来(在概念上)如:
newfunc
当它到达第13行时,它再次调用新函数,使堆栈
line 5, n=2
这会持续几次,直到堆栈看起来像
line 5, n=2; line 13, n=4
当if失败并且line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32; line 13, n=64
返回弹出堆栈并在第13行之后继续执行(因为这是我们从堆栈中得到的)制作堆栈
newfunc
当我们运行line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32
并弹出堆栈时我们返回到第13行(我们弹出时得到的内容,右边&gt;)以便堆栈
printf
等等,它解除了整个调用堆栈。
最后几个细节:堆栈在概念上“增长”,因此我们经常将其写为
line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16;
并且堆栈内容的确切格式取决于芯片的体系结构以及OS程序员做出的一些决定。
答案 1 :(得分:0)
实际发生的是,当您在第13行调用该函数时,该函数之后的代码无法执行,因此它们存储在称为堆栈的内存中的特殊位置,并且它们从底部填充,因此更新的代码填充在堆栈的顶部。因此,在第一个函数调用时,printf("\n%d",2)
被添加到底部和printf("\n%d",4);
的堆栈中,即 2 * n = 2 * 2 = 4 被添加到上一个堆栈的顶部以及递归执行停止时。执行从顶部开始的堆栈程序,产生上述复杂类型的输出,这对于简单分析是不可预测的。
答案 2 :(得分:0)
让我们把它当作小值说10
1st call from main ////returned from newfunc(2)
newfunc(2)
//inside newfunc(2)
print 2
2<10 (correct)
newfunc(4) --> on stack print 2 //returned from newfunc(4)
-------------------------------
//inside newfunc(4)
print 4
4<10
newfunc(8) --> on stack print 4 //returned from newfunc(8)
---------------------------------
//inside newfunc(8)
print 8
8<10
newfunc(16) --> on stack print 8 //returned from newfunc(16)
---------------------------
//inside newfunc(16)
print 16
16<10 failed
所以它会return
到它之前的函数,无论哪个函数都调用它,所以它将继续-->
符号,这个符号在这个例子中是堆栈的顶部,print
用于显示屏幕上显示result
功能序列从上到下......我试图在图表中显示。希望你明白。
此处-->
语句将从下到上执行,因此结果将为
2
4
8
16
8
4
2