1142_SICP学习笔记_函数以及由函数创建的进程_线性递归以及迭代

本文探讨了递归和迭代两种方法在实现阶乘函数上的差异,并通过C语言展示了这两种方法。递归虽然直观,但随着层级加深会增加解析器的负担,而迭代则更高效,尤其在资源管理上。文中还提及了线性递归和尾递归的概念,以及它们在资源消耗上的不同。通过测试,验证了C语言版本的正确性,并与Python的递归实现进行了对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    全部学习汇总:GitHub - GreyZhang/g_SICP: learn SICP and hack lisp.

    首先说,这个标题的命名来自于文本信息的翻译和调整。如果结合C语言来说,更加合适的叫法或者是子函数以及由子函数组合出来的功能函数。

    这算是这个章节的开篇词了,不过里面有几个比较有意思的东西值得思考。比如,作为一个专业的程序员其实得有一个比较形象具体的思考能力。在迈向专业的过程中,必须学会如何应对不同的场景进行相应处理的形象、具体化的思维。我们需要通过这种子功能的方式来描述一个功能的整体、全局信息以及行为。自然,很多子函数里面会有自己需要维护的状态信息。

    这是一个递归阶乘的函数实现,下面的图是使用替换法针对每一个步骤进行展开的具体描述。

    而这个,是一个迭代的实现以及展开描述。判断递归以及迭代的差异,主要的差一点其实是在于程序运行的中间状态是否利用了解析器来自动处理而不是看函数是否被自己调用。这一点,之前我在处理其他设计的时候其实是没有做一个深刻思考的。

    按照这样的理念,其实可以依葫芦画瓢设计一个C语言版本的“递归迭代”:

#include

#include

void fac(uint32_t n, uint32_t *p_counter, uint32_t *p_result)

{

    if(*p_counter > n)

    {

        /* result is stored to the memory @ p_result */

        return;

    }

    else

    {

        *p_result *= *p_counter;

        *p_counter += 1U;

        fac(n, p_counter, p_result);

    }

}

int main(void)

{

    uint32_t n = 5;

    uint32_t c = 1U;

    uint32_t r = 1U;

    fac(n, &c, &r);

    printf("result is %d\n", r);

    n = 10;

    c = 1U;

    r = 1U;

    fac(n, &c, &r);

    printf("result is %d\n", r);

    n = 12;

    c = 1U;

    r = 1U;

    fac(n, &c, &r);

    printf("result is %d\n", r);

    return 0;

}

    测试:

    上面的测试中,增加了一个python的对比。其中,python是一个完全递归的实现:

def fac(n):

    if n == 1:

        return 1

    else:

        return n * fac(n - 1)

print(fac(5))

print(fac(10))

print(fac(12))

    从测试的结果看,在一定的参数范围内,这个C的版本计算还是正确的。

    随着递归的层级增加,解析器需要追踪的信息线性膨胀增加。这种处理的过程叫做线性递归。随着递归的深度增加,越来越多的信息需要去管理维护。因此,上面两种处理思路:递归以及迭代在对比其算法的资源消耗的时候不应该仅仅关注替换模型中的处理深度,还得关注横向的扩展宽度。纵向代表的主要是时间消耗,而横向其实涉及到时间消耗的同时还多了一个存储资源的消耗。

    但是递归也不一定一定符合这样的条件,这也是为什么这里探讨的递归专门提出来是线性递归。而通过结束部分的拓展部分,其实也有资源消耗基本不变的递归方式,比如说尾递归。对我来说,这的确又是一个新的概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值