河内函数递归调用问题的解释

电脑杂谈  发布时间:2020-05-16 07:19:58  来源:网络整理

递归 2次调用_递归函数与递归调用_c递归调用

全部展开

递归函数与递归调用_c递归调用_递归 2次调用

13.5函数的递归调用(可选)步骤4: 走出浴室. 一周前,当我写一本关于函数的章节时,我将递归调用的内容放在了最后. 函数递归调用很重要,但对于初学者来说,它确实不适合初学者学习. 13.5.1递归和递归的危险递归调用是解决特定类型问题的好方法. 但是在现实生活中很难找到类似的比较. 有e69da5e887aae799bee5baa631333335313133广为流传的故事,但可以看出其具有“递归”的外观. “曾经有一座山. 山上有一座寺庙. 寺庙里有一位老和尚. 老和尚告诉年轻和尚一个故事: 有一座山……”. 在讲故事的过程中,故事本身是嵌套的. 这是上面故事的乐趣. 函数可以直接或间接调用自身,这称为“递归调用”. C,C ++语言不允许在函数内部定义子函数,也就是说,不能从函数的结构中嵌套子函数,但是递归调用实际上是一个嵌套的调用过程,因此C,C ++不实现递归最好的语言. 但是只要我们合理地使用它,C,C ++仍然很容易实现递归调用的语言功能. 让我们首先看一下最直接的递归调用: 是否有函数F(); void F(){F();}此功能是否与“老和尚讲故事”非常相似?在函数F()中,再次调用函数F().

递归函数与递归调用_递归 2次调用_c递归调用

这将是什么结果?当然,就像那个故事一样,它是无尽的. 因此,上面的代码是一个“致命”程序. 我不相信您将文件保存在计算机上,然后构建了一个控制台项目,填充了代码,并在主函数main()中调用了F(). 走着瞧吧? WinNT,2k,XP可能更好,98,ME很难说……我也不负责. 出于“烧自己,照亮别人”的概念,我在XP + CB6上尝试了一个. 以下是一个接一个出现的两个错误框: 这是CB6调试器的“检测”点,即将发生主要错误. 预先发出警告. 我单击确定,然后再次按F9,没有任何遗憾. 程序显示一个实际的错误框: 这是程序抛出的异常. EStackOverflow这样看待它: 字母E表示这是一个错误(堆栈)我们之前已经讨论过函数调用过程的“堆栈”,Overflow表示“溢出”. 整个StasckOverflow意味着: 堆栈溢出!您所说的“堆栈溢出”是什么意思?拿杯子倒水. 继续倒水,直到杯子装满并倒出为止,水将从杯子中溢出. 堆栈用于``推入''函数的参数或返回值. 当您无限层地调用该函数时,堆栈存储空间将不足,因此会发生“堆栈溢出”. (必须说明的是,在此示例中,void F()函数既没有返回值也没有参数. 为什么会发生堆栈溢出?实际上,在调用函数时,您需要将其推入堆栈递归 2次调用,而不仅仅是这两个,还有一些寄存器值,在术语中称为“站点保护”.

递归 2次调用_递归函数与递归调用_c递归调用

由于C,C ++在调用过程中使用一些键值将其“推入”堆栈,然后“弹出”堆栈以实现函数调用,因此C,C ++语言可以实现递归. )这是我们学习递归函数时需要学习的第一件事: 不能自动逻辑停止的递归调用将导致程序无休止地循环,并迅速导致堆栈溢出. 如何在逻辑上自动停止程序?除了使用我们努力学习的流控制语句之外,我们还必须掌握由递归调用引起的流变化. 13.5.2递归调用后的隐藏循环过程哪些过程更改是由递归引起的?前面的黑体字给出了答案: “循环”. 自调用的self当然是一个循环,如果我们前面学过的if ...语句没有对其进行补充,以控制何时可以继续调用自身以及何时必须终止,则该循环必须是无限循环. 如图所示: 递归调用也可以间接形成: 例如,A()调用B(); B()调用A();尽管更为复杂,但它仍然是一个循环过程: 在此循环中,功能之间是由系统实现的,因此要“中断”循环,我们只有一个“关键点”可以启动: 在调用将引起递归,进行条件分支判断. 功能. 红点如图所示. 你现在明白了么?合理的递归函数必须是逻辑上与此类似的函数定义: void F(){……if(……)//首先确定某个条件是否为真{F(); //然后自言自语} ...}在武术小说中,了解敌人的“关键点”几乎可以把握获胜的机会;但是,“递归调用”不是我们的敌人.

递归 2次调用_c递归调用_递归函数与递归调用

我们并不是要“摆脱”它,而是使用它. 因此,即使我们知道要点,也仍然需要解决. 更重要的是要知道: 什么时候应该中断其周期?什么时候应该继续循环?这当然与要解决的特定问题有关. 因此,这种能力取决于将来每个人的自我解决问题. 就像我们之前讨论的流控制一样,只有几章,但是每个人都将使用它们来解决程序中无数的问题. (有些学生开始关闭课本为上课做准备)该程序各个过程的最终目标是正确处理数据递归 2次调用,中间数据的更改将影响过程的方向. 在递归调用函数期间,最重要的数据更改是参数. 因此,大多数递归函数最终都依赖于参数的更改来决定是否继续. (另一个依赖关系是在函数外部更改变量). 因此,我们必须彻底了解参数在递归调用过程中的变化. 13.5.3递归调用期间的参数更改我们将通过模拟过程观察参数的更改. 这是一个递归函数: void F(int a){F(a + 1);}与上一个示例有一些重要区别,函数F()带有参数,并且在函数体中调用自身时,我们将其传递给它. 当前参数的值加1用作新参数. 您不能简单地阅读红色部分,您必须了解它. 现在,假设我们在代码中使用1作为初始参数,并首次调用F(): F(1);现在,参数为1,根据我们先前对“参数传递过程”的了解,我们知道1被“按下”了堆栈,如图所示: F()在第一次调用后立即被调用,但是参数此时为a + 1,a为原始参数值,即1,因此新参数值应为2.

在第二次调用F函数时,新的参数值也被压入堆栈: 仿真过程在下一层相同. 第三次调用F()时,参数变为3,仍将其压入堆栈,然后第四次...递归后面的循环不断重复,而参数a在循环中不断变化以上. 由于此函数仍未判断是否结束递归调用,因此last和last: 堆栈溢出. 添加逻辑判断以结束对该函数的此递归调用非常容易. 假设我们要求参数更改为10(不包括10),它将结束,然后代码如下: void F(int a){if(a <10)F(a + 1);}最后,有一个安全的递归调用示例. 但这似乎无能为力. 让我们添加一个输出代码,并将其作为我们的第一个递归实例. 13.5.4安全的递归调用函数的示例例6: 使用递归实现整数1到9的连续输出. //递归调用的函数: void F(int a){if(a <10){cout << a ; F(a + 1);}} //然后像这样调用它: F(1);完整的代码,请参阅相应的示例以进行下载. 输出为: 123456789请模拟该问题函数的调用过程. 13.5.5递归函数的返回这不是在谈论递归函数的返回值. 天气不是很冷,可以脱衣服吗?第一次穿衣服时,必须先穿上最内层,然后穿上第二层,再穿上第三层.

现在让您脱下衣服,您必须先脱掉外层,然后脱掉内层,再脱掉最内层. 递归函数调用类似于穿衣和脱衣,但内部和外部相反. 在调用开始时,它是外层和内层,而内层是内层. 等待直到最内层结束,因为条件不允许. 很好当最内层结束时,它将返回到稍外的层. 逐层退出,直到最外层结束. 如果调用折线图来表示前面的示例,则为: 本节不是关于递归函数的返回值,而是关于递归函数的返回顺序. 早些时候,我听说想要脱衣服然后逃跑或回来的学生可以回到原来的位置. 作为本节中的示例,我将仅给出示例代码,请考虑输出结果. 思考不仅是用脸颊思考(你以为你是大卫吗?). 另外,我相信许多同学都很聪明,他们可以根据自己的感受猜测结果. 精明是好事,但不要因为精明而失去您不知不觉地调试程序的动力. 该代码实际上只是以上示例中的另一行. 示例7: 递归函数的返回顺序: //递归调用函数: void F(int a){if(a <10){cout << a; F(a +1); cout << a;}} //然后像这样调用它: F(1);有关完整代码,请参见下载的示例.


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-211630-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 方千里
        方千里

        呵呵在南海说自由我们有权利自由

      • 陈潭秋
        陈潭秋

        北洋海军成军时

      热点图片
      拼命载入中...