我正在跟随著名的CS50课程。
在一堂课上,老师展示了一个程序,该程序可以打印出一个高度为用户输入的金字塔:
#include <cs50.h>
#include <stdio.h>
void pyramid(int n);
int main (void)
{
int height = get_int("height:");
pyramid(height);
return 0;
}
void pyramid(int n)
{
if (n==0)
{
return;
}
pyramid(n-1);
for (int i=0; i<n;i++)
{
printf("#");
}
printf("\n");
}
字符串
请问谁能给我解释一下,递归函数金字塔是做什么的?我调试它,我看到给定的输入正在检查它是否等于0,然后它调用自己,直到n==0并返回。之后,调试器进入循环并执行n次。
在一个线性路径之后,它不应该进入for循环。它为什么会这样?
非常感谢您的帮助!
3条答案
按热度按时间nmpmafwu1#
在设置了
height
的某个值之后,调用函数piramid
。如果height
的值是0
,则函数结束。否则,它会使用减少的参数height
调用自己,这允许您打印金字塔的每一层。正如您在void piramid(int n)
的主体中看到的,它首先调用自己,然后打印n
“块”。假设我们正在使用
height = n
,并尝试分析发生了什么(每个点是另一个步骤):piramid(n)
调用:piramid(n-1)
调用:piramid(n-2)
调用:piramid(1)
调用:piramid(0)
-不返回任何内容,这是piramid
的最后一次递归调用,所以我们开始返回:在我们的例子中,这意味着我们按照从上到下的顺序打印哈希:#
被打印出来,因为piramid(1)
在堆栈的顶部,在我们打印它之后,我们弹出它,所以piramid(2)
成为顶部的第一个元素##
被打印出来,piramid(2)
在栈顶,我们弹出它并继续以同样的方式处理其他调用,#
被打印,我们从堆栈中弹出它,#
,我们的堆栈现在是空的。knsnq2tg2#
为了便于理解,我们举一个小数字的例子:
字符串
它的作用:
如果n更大,它将遵循这个,但步骤更多
希望它可以帮助和抱歉,如果我的答案不是很大,因为这是我第一次尝试回答stackoverflow(如果你有建议,我应该如何回答,不要犹豫,告诉我)
wdebmtf23#
混淆是由于不知道执行上下文和调用堆栈。我们应该了解所讨论的编程语言的内存模型,这对于理解函数调用是如何工作的至关重要。
递归调用按调用它们的顺序添加到调用堆栈,第一个递归调用位于堆栈底部,最近的递归调用位于堆栈顶部。递归调用记住它们离开执行的位置(执行上下文),并以(n-1)作为参数调用自己,直到n<=0,在这种情况下,堆栈被退回,最新的递归调用从它离开的地方继续执行,堆栈中的后续调用顺序执行,第一个递归调用最后执行。所有的函数调用都在一个执行线程中执行。