zoukankan      html  css  js  c++  java
  • 递归函数详解——VS调试教你理解透彻递归

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int recursion(int);
     5 
     6 int S = 0;
     7 
     8 int main(void) {
     9     recursion(10);
    10     system("pause");
    11     return 0;
    12 }
    13 
    14 int recursion(int i) {
    15     printf("i:%d   S为%d
    ",i,S);
    16     if (i > 0) {
    17         return S += recursion(i - 1);
    18         printf("返回到%d", S);
    19     }
    20     else return 1;
    21 }
    stdlib.h提供system()函数原型
    
    第4行代码是函数声明,这样就不需要把子函数定义代码写在main()前面了
    
    第6行是全局变量
    点我看详细介绍

     请跟着本教程调试,因为纯看文字不仅看不懂还头疼,动手才能理解(都怪楼主文字表达能力极差emm...)

     我们把断点打在第15行,然后就“逐语句调试”

    关于调试按钮的介绍:

    Continue 是执行到下一个断点处时才暂停,对于这里的递归函数,下一个断点还是第15行那条语句

    F10逐过程(不进入函数内部,一个函数是一个过程)

    F11逐语句(进入函数里的每一条语句)

    若要跳出函数按shift+F11

    Watch Auto 两个监视窗口都可以看变量值

    回到调试递归函数这里,在第15行打断点,然后一直点下一步(这方法也叫单步调试)

    然后我们可以发现:

    函数会执行到递归处,因为递归在return之前执行,所以函数一直调用自己执行但不返回(只有到被调用的函数执行到结尾return,也就是结束了,才能继续执行上一层函数的return),直到20行的return 1;被执行了,这样有一个函数返回了(也就是最深处被调用的函数执行到了结尾处),然后次深处的函数才能继续执行到return 也就是次深层函数自己的结尾。

    也就是函数递归调用自己,只要没有return,函数就没有执行完成(另外return void其实也算是一种return ),

    所有的函数都在等待自己调用的那一个函数执行完成,

    【仿佛一个公司,上级先做一部分事情,再分配其中一些关键任务给下级  并等待下级执行完成,下级完成后他们才能继续做这件事。上级有自己的上级和下级,下级也有自己的上级和下级,emmm...】

    关于这句return S += recursion(i - 1);

    只有recursion(i-1)执行完成后并返回了一个值X,系统才能把S的值加上返回值X再赋值给S


    PS. return是函数的结尾,因此如果return后面还有语句,那也是无效的,return后面的语句根本不会被执行


    结论:函数在没有return之前是不会结束的,递归利用这个特性,不断调用着自己,直到最后一个自己的分身return结束了,才能回到上一层继续执行,然后逐层return,最后回到最开始时那个函数
    单数字表示第n层递归函数,数字加r表示第n层函数执行结束
    
    1
        2
            3
                4 
                4r
            3r
        2r
    1r
    
    
    
     




    本文结束,以下是一些无关的事物:
    其实,我们对调试一无所知,GDB调试打印大法:为什么一般调试程序bug的时候,都用printf来调试(printf大法),cout不行吗? - Renleilei92的回答 - 知乎

    以及汇编 宏 Linux编程,这一切的一切,和C语言相关的东西,我们都一无所知,甚至Github我们都不知道怎么用,我不经会想,如果仅靠大学课堂,我们能懂什么?




    而且大学计算机教材是一如既往的烂到底,把一门工科变成纯理科,凡是知识决口不提它的用处妙处,先要求你强制学会再说。就如二叉树,
    教材里一开门就直接讲了二叉树的样子,像极了数学题,全然不告诉你它的用处妙处,而我在<C Primer Plus 中文版>书里看到的却是:
    不太记得了,概况一下就是

    现在需要从一个有顺序的列表里找到一位顾客的信息,这列表里有A到Z排序的顾客名字,对于一个排好序的列表可以用折半搜索(二分法)比顺序搜索好得多
    假如列表有127项,那么顺序搜索平均要64次比较,而折半搜索只需最多7次比较 (2的7次方是128)
    这样我们发现效率极高

    但是这样有个坏处,每次加入新内容,列表都要排序一下,如果在需要频繁改动列表的情景下,这种顺序表(无论是数组还是单链表)会很麻烦。

    另一种形式,二叉树,可能正是您所需要的。
    二叉树结合了折半搜索策略的链接结构,如图

    这本书基本上以应用为情景,带读者学习,很真实地模拟了一个需求场景,并坚持不懈地带着读者理解并学习各种新东西(最重要的是这本书内容全面完整,关键点细讲不会让你迷迷蒙蒙)
    读了这本书,我真的觉得,学习一定要有一本好书,不好的书只会让你一头雾水并丢失学习的热情

    这本适合c语言入门,另外数据结构的书还有很多,找书我一般在知乎看别人回答推荐



    附上:

    深入理解计算机系统(二):Hello World 是如何运行的 - 知乎



    --------蓝天上的云_转载请注明出处.
  • 相关阅读:
    济南学习D1T5__HEAP
    快速计算C(n,r)
    快速阶乘算法
    济南学习D2T1__折纸带
    济南学习D3T1__线性筛和阶乘质因数分解
    栈与队列:栈的链式储存结构
    线性表应用:建立一个随机数 链表获得中间结点
    栈与队列应用:二进制转十进制 八进制 十六进制(栈)
    线性表:单链表基本操作代码
    线性表应用:魔术师发牌与拉丁(Latin)方阵(循环链表)
  • 原文地址:https://www.cnblogs.com/yucloud/p/10680395.html
Copyright © 2011-2022 走看看