鱼C论坛

 找回密码
 立即注册
查看: 2541|回复: 9

[已解决]关于递归的课后作业题

[复制链接]
发表于 2022-9-22 15:33:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在本代码中,用户输入5,得到结果为:5 4 3 2 1 0 0 0 1 2 3 4
我的问题是:在执行up_and_down函数时 先进入5 然后打印5 然后if语句执行up_and_down函数 再下面一行的打印语句根本没有被执行  那么答案中的最后几个数字0 1 2 3 4 是怎么打印出来的呢?求分析up_and_down函数的具体执行过程。
#include <stdio.h>

void up_and_down(int n);

void up_and_down(int n)
{
        printf("%d ", n);
        if (n > 0)
        {
                up_and_down(--n);
        }
        printf("%d ", n);
}

int main(void)
{
        int n;

        printf("请输入一个整数:");
        scanf("%d", &n);

        up_and_down(n);
        putchar('\n');

        return 0;
}
最佳答案
2022-9-22 16:19:36
本帖最后由 jackz007 于 2022-9-22 16:28 编辑
void up_and_down(int n)
{
        printf("%d ", n);
        if (n > 0)
        {
                up_and_down(--n);
        }
        printf("%d ", n);
}
        一共递归 6 次,每次递归,在入口要打印一个 n,在出口打印一个 n - 1(n == 0 时例外),这个没问题吧,那就看看 6 次递归的打印内容吧:
第1次:  5
第2次:       4 
第3次:            3
第4次:                 2
第5次:                      1
第6次:                           0
第6次:                           0
第5次:                      0
第4次:                 1
第3次:            2
第2次:       3
第1次:  4
         第 6 次比较特殊,因为已经到底了,所以,没有参与递归,也就没有 -- n 的过程,所以,两个口打印的都是 0 值。
         把这些数值按照从上到下的顺序写到一起,就是你所看到的打印内容了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-22 16:19:36 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-9-22 16:28 编辑
void up_and_down(int n)
{
        printf("%d ", n);
        if (n > 0)
        {
                up_and_down(--n);
        }
        printf("%d ", n);
}
        一共递归 6 次,每次递归,在入口要打印一个 n,在出口打印一个 n - 1(n == 0 时例外),这个没问题吧,那就看看 6 次递归的打印内容吧:
第1次:  5
第2次:       4 
第3次:            3
第4次:                 2
第5次:                      1
第6次:                           0
第6次:                           0
第5次:                      0
第4次:                 1
第3次:            2
第2次:       3
第1次:  4
         第 6 次比较特殊,因为已经到底了,所以,没有参与递归,也就没有 -- n 的过程,所以,两个口打印的都是 0 值。
         把这些数值按照从上到下的顺序写到一起,就是你所看到的打印内容了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-22 16:47:06 | 显示全部楼层
jackz007 发表于 2022-9-22 16:19
一共递归 6 次,每次递归,在入口要打印一个 n,在出口打印一个 n - 1(n == 0 时例外),这个没 ...

感谢指点,还是没搞懂执行为什么n-1会被打印。不是在if语句就直接重新开始该函数了吗,为什么最后一行打印n-1会被执行呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-22 16:49:00 | 显示全部楼层
折耳布偶 发表于 2022-9-22 16:47
感谢指点,还是没搞懂执行为什么n-1会被打印。不是在if语句就直接重新开始该函数了吗,为什么最后一行打 ...

      那是它在调用自己,调用完还会继续执行后面的语句,调用自己和调用另外一个函数没有什么区别。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-22 16:49:53 | 显示全部楼层
jackz007 发表于 2022-9-22 16:49
那是它在调用自己,调用完还会继续执行后面的语句,调用自己和调用另外一个函数没有什么区别。

明白了 谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-23 02:00:33 From FishC Mobile | 显示全部楼层
jackz007 发表于 2022-9-22 16:49
那是它在调用自己,调用完还会继续执行后面的语句,调用自己和调用另外一个函数没有什么区别。

调用自己和调用另外一个函数没有什么区别

谢谢,这句话太好了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-23 02:41:25 From FishC Mobile | 显示全部楼层
本帖最后由 howzyao 于 2022-9-23 03:37 编辑

先看上半部分,--n行的上半部分。
54321进去函数体,依次打印,但每次执行函数,
都未完成,
所以,都是上面的printf打的。

第6次if,导致0入参,所以,
第1个0,由上面一个print打印出,
此时,是进去了函数体,打印第1个0后,if不执行,
此时,同一时间,同一空间,完成了函数的调用。
但第0进入的那一次,打了2个0
以5432100,的状态,结束。

这时,来到右大括号。
这时的右大括号,可以理解成 完成本次调用,
这也是首次一个 函数体 的执行完毕。

也就是函数调用自己6次的最里层。这是精髓。

函数体退出,自然是一层一层地退出,
先是第6层开始退出,
此时就来到了 高级鱼油jackz007
所说的“另外一个函数开始调用自己”这个状态。

我理解的呢,就是退出函数。也就是说,
退出第6层,下面的printf打0,
这个0是0入参的 同一空间 不同时间的 产物:
本函数体终于
到右花括号
前半部分简单逻辑结束了。

后半部分,重要逻辑来了:
此时应当试想,当初5次调用函数时,
函数体执行完毕了吗?没有,那就只能接着执行,
这就是所谓的 “退出函数体”的概念,
退出第5层,下面的printf接着打1,这个1是不同时间,相同空间的产物,接着到右花括号,
结束5次调用,退到4次调用,该打几?不用说了吧?
。。。直到第n次以 n-1入参==最后1次 第5次以5-1入参打出4
万事大吉,圆满收工。

这是我自己理解的 递归 不知道是不是这个原理。
请广大鱼油审阅。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-23 03:49:59 From FishC Mobile | 显示全部楼层
本帖最后由 howzyao 于 2022-9-23 03:52 编辑

总结了一下,
实际上,递归,就是n*2+2的循环次数,且
以 n+1 个执行次数实现 递归函数体 的上半部分,
对此例:有
(n*2+2)/2=a(x)时,函数a平分变量x,且x取反向变化。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-23 03:59:53 From FishC Mobile | 显示全部楼层
若放到我们做一个动作时,比如:
左看看(其实回中没有表达)右看看
这么一个动作,可以用一个递归函数来表达:
void a(int&);
...
int direction=3;//入参
左边看时,4个动画,3210 归位。
右边看时,4个动画,0012 归位。
完美贴图 完美动作。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-9-23 15:37:00 | 显示全部楼层
howzyao 发表于 2022-9-23 03:59
若放到我们做一个动作时,比如:
左看看(其实回中没有表达)右看看
这么一个动作,可以用一个递归函数来表 ...

感谢指点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-28 03:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表