• 【递归】执行过程探究(c)


    c语言 递归的执行过程探究

    引用《c primer plus》第五版 9.3.1 递归的使用

     1 /* recur.c -- recursion illustration */
     2 #include <stdio.h>
     3 void up_and_down(int);
     4 
     5 int main(void)
     6 {
     7     up_and_down(1);
     8     return 0;
     9 }
    10 
    11 void up_and_down(int n)
    12 {
    13     printf("Level %d: n location %p
    ", n, &n); /* 1 */ 
    14     if (n < 4)
    15          up_and_down(n+1);             /* 递归处 */  
    16     printf("LEVEL %d: n location %p
    ", n, &n); /* 2 */  
    17  
    18 }

    过程:  main()调用了up_and_down(1),
    然后第一层的up_and_down(此时n为1),
    执行到了我注释的那个地方/*递归处*/即第15行
    在递归处调用了up_and_down(调用时将n+1(也就是1+1)赋给了第二层的参量n)

    由于调用后第一层要等待第二层的返回,所以第一层执行还没有完成,所以还轮不到第一层的/* 2 */ 处的打印,
    第二层的up_and_down又执行到了/*递归处*/,又调用了函数,以此类推。


    最后执行到了最深层时,n不再满足小于4的条件,所以不再递归。
    就执行了/* 2 */ 处的打印,然后函数结束了,就return返回值【此处return void;】并退出当前层的函数
    次深层检测到 被自己调用的函数的返回值 后继续执行/* 2 */ 处的打印,结束后再return void; 依次类推。
     

    输出结果为:

    LEVEL 1: n location 0x0012ff48
    LEVEL 2: n location 0x0012ff3c
    LEVEL 3: n location 0x0012ff30
    LEVEL 4: n location 0x0012ff24
    LEVEL 4: n location 0x0012ff24
    LEVEL 3: n location 0x0012ff30
    LEVEL 2: n location 0x0012ff3c
    LEVEL 1: n location 0x0012ff48





    总结:由于c语言的顺序结构,所以调用函数后要等待被调用的函数执行完成(即有返回值后)才能执行下一步,而递归恰恰是一层一层地调用自己,所以得等到最深层执行完成后,才返回值告诉次深层函数可以继续执行。次深层执行后才能返回告诉次次深层继续执行。
    【在函数没有执行完成前,不return。 导致了每一个函数都得等待被调用函数的返回才能继续,不断调用就得不断等待被调用的函数,因此必须等最深层函数开始返回后才有了一步步的函数的后续执行和返回】


    重点:调用时的LEVEL1地址和返回时的LEVEL1(LEVEL数字)是相同的
    每一级递归都使用自己的私有变量(子函数中变量的作用域和储存时期部分的知识)








    关于利用递归函数赋值的部分,引用《c primer plus》第五版 9.3.3尾递归
     1 // factor.c -- uses loops and recursion to calculate factorials
     2 #include <stdio.h>
     3 long fact(int n);
     4 long rfact(int n);
     5 int main(void)
     6 {
     7     int num;
     8 
     9     printf("This program calculates factorials.
    ");
    10     printf("Enter a value in the range 0-12 (q to quit):
    ");
    11     while (scanf("%d", &num) == 1)
    12     {
    13         if (num < 0)
    14             printf("No negative numbers, please.
    ");
    15         else if (num > 12)
    16             printf("Keep input under 13.
    ");
    17         else
    18         {
    19             printf("loop: %d factorial = %ld
    ", 
    20                     num, fact(num));
    21             printf("recursion: %d factorial = %ld
    ", 
    22                     num, rfact(num));
    23         }
    24         printf("Enter a value in the range 0-12 (q to quit):
    ");
    25     }
    26     printf("Bye.
    ");
    27   
    28     return 0;
    29 }
    30 
    31 long fact(int n)     // loop-based function
    32 {
    33     long ans;
    34 
    35     for (ans = 1; n > 1; n--)
    36         ans *= n;
    37     
    38     return ans;
    39 }
    40 
    41 long rfact(int n)    // recursive version
    42 {
    43     long ans;
    44 
    45     if (n > 0)
    46         ans= n * rfact(n-1);
    47     else
    48         ans = 1;
    49   
    50     return ans;
    51 }

    首先,此处的赋值是    将 函数返回值 赋给一个变量

    所以递归赋值这种也是一样的:
    一步步等待,直到最深层函数执行完成并返回后
    次深层才能利用返回值执行赋值操作,然后再执行完成并返回
    次次深层才能利用返回值执行赋值操作......
    依次类推


    疑问递归函数里 x=3+addall(n);
    那么x的值在递归过程中如何变化?



    =========End
    --------蓝天上的云_转载请注明出处.
  • 相关阅读:
    python---RabbitMQ(1)简单队列使用,消息依次分发(一对一),消息持久化处理
    python---ORM之SQLAlchemy(4)relationship多对多练习
    ShowcaseView-master
    HT518V311
    上方显示进度的进度条
    ArrowDrawable
    一个仿 github for windows 及 windows 8 的进度条
    高仿语音发送动画,按住闪烁,滑动跟随,删除翻转丢入垃圾桶,比较全的一个动画实例
    Ledongli
    RotatingDoughnut
  • 原文地址:https://www.cnblogs.com/yucloud/p/recursion.html
Copyright © 2020-2023  润新知