C中的递归函数(打印#的piramid)

jvidinwx  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(87)

我正在跟随著名的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循环。它为什么会这样?
非常感谢您的帮助!

nmpmafwu

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)在栈顶,我们弹出它并继续以同样的方式处理其他调用,
  • ...
  • (n-1)#被打印,我们从堆栈中弹出它,
  • 打印了n #,我们的堆栈现在是空的。
knsnq2tg

knsnq2tg2#

为了便于理解,我们举一个小数字的例子:

#include <stdio.h>

void piramid (int n);

int
main (void)
{
  piramid (2);
}

void
piramid (int n)
{
  if (n == 0)
    {
      return;
    }
  piramid (n - 1);

  for (int i = 0; i < n; i++)
    {
      printf ("#");
    }
  printf ("\n");
}

字符串
它的作用:

  • 主调用piramid(2)
  • piramid(2)调用piramid(1),但是piramid(2)没有像你说的那样完成
  • piramid(1)调用piramid(0)
  • piramid(0)不执行任何操作,因为它立即返回
  • piramid(1)饰面和印花#
  • piramid(2)饰面和印花##

如果n更大,它将遵循这个,但步骤更多
希望它可以帮助和抱歉,如果我的答案不是很大,因为这是我第一次尝试回答stackoverflow(如果你有建议,我应该如何回答,不要犹豫,告诉我)

wdebmtf2

wdebmtf23#

混淆是由于不知道执行上下文和调用堆栈。我们应该了解所讨论的编程语言的内存模型,这对于理解函数调用是如何工作的至关重要。
递归调用按调用它们的顺序添加到调用堆栈,第一个递归调用位于堆栈底部,最近的递归调用位于堆栈顶部。递归调用记住它们离开执行的位置(执行上下文),并以(n-1)作为参数调用自己,直到n<=0,在这种情况下,堆栈被退回,最新的递归调用从它离开的地方继续执行,堆栈中的后续调用顺序执行,第一个递归调用最后执行。所有的函数调用都在一个执行线程中执行。

相关问题