【C语言课堂】 函数递归

news/2024/11/16 9:47:00/

欢迎来到 Claffic 的博客 💞💞💞

前言:

时隔多日,来还欠大家的 C 语言学习啦,上期讲了函数,其实函数中应该包括函数递归的,这里单独拿出来讲解的原因是函数递归属于重难知识,值得拿出来单独讲讲。


目录

❤️1. 何为递归

🧡2. 递归的两个必要条件

💚3. 递归和迭代(循环) 

💜4. 一个练习


1. 何为递归

屏幕前的大佬们:

这个有趣的表情包就有点递归的意思:

可以看到抱腿系数不断攀升,抱腿下还有抱腿...(huyanluanyu)。

还有《盗梦空间》中的经典场面:

两面镜子相对,镜子里面的情景是相同的,无限循环的。典型的 “德罗斯特效应”。

这也与递归类似,逐渐深入,深入,深入... ...

通过上面两个引子,相信你已经大概了解递归是什么样子的,下面 递归的概念:

程序调用自身的编程技巧称为递归 recursion)。 

说的通俗点,就是函数里用了函数本身。

int Strlen(const char*str) 
{if(*str == '\0')return 0;elsereturn 1 + Strlen(str+1);
}

这是用递归的方法模拟了 strlen 函数,这个函数调用了函数自身。

递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归的主要思考方式在于:把大事化小

2. 递归的两个必要条件

递归大不可一直进行下去,否则就会像《盗梦空间》里的镜子那样碎掉,所以递归要有停止的条件,给递归一个限制。

于是就有了递归的第一个必要条件: 存在限制条件。

        以上面的模拟 strlen 函数为例, *str == '\0'  就是限制条件,当达到这个条件时函数就会返回。

有了限制条件就可么?其实不是,如果递归一直停留在一个位置或者向非限制条件的方向进行,那么限制条件存在的意义不大。

所以还要有一个必要条件:每次递归后要接近这个限制条件。

        同样以模拟 strlen 函数为例, Strlen(str+1) 的意思就是每进行一次递归,指向单个字符的指针不断加一,越来越接近 '\0'

🧑🏻‍💻总结:

递归的两个必要条件: 

• 存在限制条件,当满足这个限制条件的时候,递归便不再继续;
• 每次递归调用之后越来越接近这个限制条件。

3. 递归和迭代(循环) 

不知道大家在学习递归的时候有没有考虑几个问题:

• 递归和循环是不是有些相似?

• 何时选择递归,何时选择循环?

是的,大多数情况下 递归存在重复运算,与循环相似

这里总结下递归和迭代(循环)的优缺点:

• 递归代码简洁,思路较简单,有时甚至是所想即所得;

• 但递归多次调用函数本身,而每次调用函数都会有时间和空间消耗,都会在内存栈中分配空间,效率较低,容易导致栈溢出。

所以我对递归的理解是: 方便了自己,麻烦了电脑

• 迭代(循环)对程序员来说可能思路复杂,但不会对电脑造成大的压力,不会出现栈溢出的情况,且效率较高。

迭代(循环)的理解是: 方便了电脑,麻烦了自己。

一个建议: 优先选择迭代(循环),实在没思路选择递归。

4. 一个练习

求第n个斐波那契函数(不考虑溢出)。

 1、1、2、3、5、8、13、21、34、… 

著名的生兔子数列,这个数列从第三项开始,每一项都等于前两项之和。

用递归,所想即所得:

int fib(int n) 
{if (n <= 2)         return 1;elsereturn fib(n - 1) + fib(n - 2);
}

 但,假如要求 fib(10) :

虽然只求第10个斐波那契数,但是要进行 1000 多次函数调用!

可见是非常危险的。

这种情况下,选择循环比较好:

int fib(int n)
{if (n <= 2)return 1;int fibn = 0;int fibone = 1;int fibtwo = 1;int i = 1;for (i = 1; i < n - 1; i++){fibn = fibone + fibtwo;fibone = fibtwo;fibtwo = fibn;}return fibn;
}

总结:

递归虽好,但不要贪杯哦 ~


http://www.ppmy.cn/news/19684.html

相关文章

8. 好客租房-WebSocket与即时通讯系统[项目必需]

本章节主要是学习WebSocket, 目标快速入门, 能够回答以下问题:WebSocket和HTTP的区别.WebSocket使用的是全双工通讯协议, 与其他类似协议有啥区别?WebSocket中的常用注解有哪些&#xff1f;通过本章节的学习, 应该可以回答上来这几个问题.8.1 WebSocket概念快速理解WebSocket …

【Linux】目录权限和默认权限

上期介绍了Linux的文件权限&#xff0c;这期我们仔细来说说Linux环境下目录权限和默认权限一、目录权限1.1 进入目录所需的权限我们在进入目录时需要什么样的权限呢&#xff1f;是r、w还是x呢&#xff1f;下面我们一起来验证一下&#xff1a;&#x1f4cb;如下我门拥有全部目录…

2-SAT

前置核心知识&#xff1a;强连通分量&#xff08;tarjan算法&#xff09; 1&#xff0c;定义 给定n个集合&#xff08;每个集合都是有2个元素&#xff09;&#xff0c;再给出m个关系式&#xff08;形式大致是aVb1),求是否能够从每个集合选一个元素&#xff0c;并且元素满足上…

Citadel——Dusk网络的Zero-Knowledge KYC解决方案

1. 引言 近期&#xff0c;Dusk网络宣布其已支持名为Citadel的Zero-Knowledge KYC解决方案&#xff0c;使得用户和机构可控制其权限以及个人信息分享。该架构可用于all claim-based KYC requests&#xff0c;并让用户完全控制他们共享的信息以及与谁共享信息&#xff0c;同时完…

【CSDN的2022与2023】普普通通的三年,从懵懂、焦虑到坚定、奋进,破除焦虑努力成为更好的自己

大家好&#xff0c;我是黄小黄&#xff01;一名普通的软件工程在读学生。最近终于闲下来了一丢丢&#xff01;借着休息之余&#xff0c;来写一篇年度总结散散心~与其说是年度总结&#xff0c;不如说是给大学生活与莽莽撞撞的自己一个交代叭&#xff01; 这些都是小标题~碎碎念1…

InstanceNorm LayerNorm

InstanceNorm && LayerNorm author: SUFEHeisenberg date: 2023/01/26 先说结论: 将Transformer类比于RNN&#xff1a;一个token就是一层layer&#xff0c;对一整句不如token有意义原生Bert代码或huggingface中用的都是InstanceNorm instead of LayerNorm&#xff…

厚积薄发打卡Day115:Debug设计模式<简单工厂、工厂方法、抽象工厂>

厚积薄发打卡Day115&#xff1a;Debug设计模式<简单工厂、工厂方法、抽象工厂> 简单工厂 定义 由一个工厂对象决定创建出哪一种产品类的实例&#xff08;严格意义并不是设计模式&#xff0c;更是一种风格&#xff09; 类型&#xff1a;创建型&#xff0c;但不属于GOF…

RISC-V Instruction Formats

原始内容如下&#xff1a; RISC-V Instruction Formats The RISC-V Instruction Set Manual Volume I: User-Level ISA lists 15 instruction formats where some of the formats have multiple variants. For the ‘.insn’ pseudo directive the assembler recognizes some o…