函数递归(C语言)(详细过程!)

函数递归

  • 一. 递归是什么
    • 1.1 递归的思想
    • 1.2 递归的限制条件
  • 二. 递归举例
    • 2.1 求n的阶乘
    • 2.2 按顺序打印一个整数的每一位
  • 三. 递归与迭代
    • 3.1 求第n个斐波那契数

一. 递归是什么

递归是学习C语言很重要的一个知识,递归就是函数自己调用自己,是一种解决问题的方法,下面就使用一个简单的代码帮助大家理解:下面展示一些 内联代码片


#include <stdio.h>
int main()
{
printf("hehe\n");
main()  //出现了main函数自己调用自己
return 0

在这里插入图片描述
上图展示的代码就是一个简单的调用函数的例子,不断的调用main函数也就是要不断输出hehe,形成了一个循环,这就是一个简单的函数递归。

1.1 递归的思想

把一个大型问题转换成一个与原问题相似但是规模较小的子问题来解决,直到到子问题不能再被拆分,递归就结束了。递归中的递就是递推的意思,归就是回归的意思,下面会有详细的解释。

1.2 递归的限制条件

递归在书写的时候,有两个必要条件:
. 递归存在限制条件,当满足这个限制条件的时候,递归便不再继续
. 每次递归之后越来越接近这个限制条件

二. 递归举例

2.1 求n的阶乘

为了让大家更好理解递归是怎么回事,我们可以举几个例子,下面为大家展示第一个例子求n的阶乘的代码: 内联代码片

int Fact(int n)
{
	if (n == 0)
		return 1;
	else if (n > 0)
		return n * Fact(n - 1);//相当于是多次调用这个函数,形成一个循环,不断地累乘
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int r = Fact(n);
	printf("%d", r);
	return 0;
}

上述代码就给大家演示了一遍比较基本的函数递归,我们可以看到如果n大于0的话,就会返回n*Fact(n-1),所以就相当于不断的调用Fact函数,如果大家还是不太理解,下面我们用一张图帮助大家进一步理解:在这里插入图片描述

2.2 按顺序打印一个整数的每一位

这是为大家展示的第二个例子,按顺序打印一个整数的每一位。首先我们看到这个题目,我们不难想到用%的方法,假如现在给一个数字1234,要如何打印出1 2 3 4 这四个数字呢?首先就是很容易想到1234%10=4,这时候我们就得到了4,然后1234/10=123(默认取整),然后再用123%10=3,这时候我们就得到了3…按照这个思路我们的代码就能实现,后面我还会再加上图片解释,方便大家进一步理解: 内联代码片

void get(int n)
{
	if (n > 9)
	{
		get(n / 10);
	}

	printf("%d ", n % 10);
}


int main()
{
	int n = 0;
	scanf("%d", &n);
	get(n);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

三. 递归与迭代

(1)递归是⼀种很好的编程技巧,但是和很多技巧⼀样,也是可能被误⽤的,就像举例1⼀样,看到推导的公式,很容易就被写成递归的形式,为大家解释一下,我们的第一个例子求n的阶乘,我们用递归的方法很容易算出来,但是我们可以自己操作一下,如果数值小的话,计算结果是很快出来,但是如果我们的数值偏大,假如我们输入50,那么计算结果就会很慢,原因就是 Fact函数是可以产生正确的结果,但是在递归函数调用的过程中涉及⼀些运行时的开销。

  • 在C语言中每⼀次函数调用,都需要为本次函数调用在内存的栈区,申请⼀块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧
  • 函数不返回,函数对应的栈帧空间就⼀直占用,所以如果函数调用中存在递归调用的话,每⼀次递归函数调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。所以如果采用函数递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stackoverflow)的问题。

(2)所以如果不想使用递归,就得想其他的办法,通常就是迭代的方式(通常就是循环的方式)比如我们举的第一个例子计算n的阶乘,也是可以产⽣1~n的数字累计乘在⼀起的。
在这里插入图片描述

上述代码是能够完成任务,并且效率是比递归的方式更好的。事实上,我们看到的许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更加清晰,但是这些问题的迭代实现往往比递归实现效率更高。但是当⼀个问题非常复杂,难以使用迭代的方式实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。所以我们不能说是递归更便捷还是迭代更便捷,我们更多的要去思考问题本身。

3.1 求第n个斐波那契数

我们也能举出更加极端的例⼦,就像计算第n个斐波那契数,是不适合使⽤递归求解的,但是斐波那契数 (1 1 2 3 5 8 13…前两个数相加) 的问题通过是使⽤递归的形式描述的,如下:在这里插入图片描述
当我们n输⼊为50的时候,需要很长时间才能算出结果,这个计算所花费的时间,是我们很难接受的,这也说明递归的写法是非常低效的,那是为什么呢?其实递归程序会不断的展开,在展开的过程中,我们很容易就能发现,在递归的过程中会有重复计算,而且递归层次越深,冗余计算就会越多。在这里插入图片描述
就像上面的图片上展示的,计算一个数值,就要将它拆分成另外两个数,以此类推,会循环很多很多次,也造成了巨大的计算量,所以在有些时候我们不妨试试另一种方法,例如迭代的方法,其实循环也算是迭代的一种,下图计算将递归的方法转换成迭代的方式去实现这个代码,效率就要高出很多了。有时候,递归虽好,但是也会引⼊⼀些问题,所以我们⼀定不要迷恋递归,适可而止就好。在这里插入图片描述

以上就是关于递归的一些初级的理解,在后期我也会为大家继续写更多关于递归的知识,以及一些深入的了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/703882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

与浪涌保护器相关的8/20μs和10/350μs波形

8/20μs和10/350μ是到底是什么&#xff1f; 浪涌保护器中有个极为重要的参数&#xff0c;8/20μs或10/350μs。浪涌保护器的作用主要是保护电子设备免受电源浪涌或瞬态电压影响的重要装置。主要应对雷击&#xff0c;包括直击雷和感应雷。由于直击雷和感应雷的能量不一样&…

RabbitMQ实践——在Ubuntu上安装并启用管理后台

大纲 环境安装启动管理后台 RabbitMQ是一款功能强大、灵活可靠的消息代理软件&#xff0c;为分布式系统中的通信问题提供了优秀的解决方案。无论是在大规模数据处理、实时分析还是微服务架构中&#xff0c;RabbitMQ都能发挥出色的性能&#xff0c;帮助开发者构建高效、稳定的系…

《Windows API每日一练》3.3 更好效果的滚动条

本节讲述滚动条的复杂使用方法&#xff0c;以便达到更好的效果。Windows操作系统提供了两套机制&#xff0c;一套机制是使用默认的对象属性进行简单的操作&#xff0c;并提供简单便捷的API接口函数。另一套机制是用户可以自定义对象属性&#xff0c;实现自己想要的效果。本节我…

【ARM Cache 及 MMU 系列文章 6.1 -- Cache maintenance 指令及相关寄存器有哪些?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Cache Maintenance registers and instructionsDCZID_EL0DCZID_EL0寄存器字段解释 DCZ 使用场景Cache maintenance 范围选择 Cache maintenance 指令集 Cache Maintenance registers a…

公司活动想找媒体报道宣传怎样邀请媒体?

在当今信息爆炸的时代,对于正处于成长阶段的中小企业而言,有效且成本控制得当的宣传策略是推动品牌发展、扩大市场影响力的关键。尤其是在预算有限的情况下,如何让“好钢用在刀刃上”,实现宣传效果的最大化,成为众多企业共同面临的挑战。在此背景下,智慧软文发布系统网站作为一…

IDEA 高效插件工具

文章目录 LombokMaven Helper 依赖冲突any-rule(正则表达式插件)快速生成javadocGsonFormat (Aits) 将json解析成类Diagrams使用 类图SequenceDiagram时序图GenerateAllSetter&#xff08;AltEnter&#xff09;大小写转写String ManipulationGitToolBox 代码提交人activate-pow…

机器学习笔记 - 用于3D数据分类、分割的Point Net简述

一、简述 在本文中,我们将了解Point Net,目前,处理图像数据的方法有很多。从传统的计算机视觉方法到使用卷积神经网络到Transformer方法,几乎任何 2D 图像应用都会有某种现有的方法。然而,当涉及到 3D 数据时,现成的工具和方法并不那么丰富。3D 空间中一个工具就是Point …

springboot的WebFlux 和Servlet

Spring Boot 中的 Servlet 定义&#xff1a; 在 Spring Boot 中&#xff0c;Servlet 应用程序通常基于 Spring MVC&#xff0c;它是一个基于 Servlet API 的 Web 框架。Spring MVC 提供了模型-视图-控制器&#xff08;MVC&#xff09;架构&#xff0c;用于构建 Web 应用程序。…

颠覆与创新:探寻Facebook未来的发展路径

Facebook&#xff0c;这个曾经引领社交网络革命的巨头&#xff0c;在如今竞争激烈的科技市场中&#xff0c;正面临着前所未有的挑战和机遇。如何在不断变化的数字世界中保持竞争力&#xff0c;成为业界领先者&#xff0c;这是摆在Facebook面前的重要课题。本文将探寻Facebook未…

STM32项目分享:车牌号识别系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.…

【Mac】增加 safari 体验的插件笔记

Safari 本身的功能不全面&#xff0c;探索积累了一点插件笔记&#xff0c;提升使用体验&#xff1b;但后面因为插件或会影响运行速度&#xff0c;就全部都禁止了。做个笔记记录一下。 Cascadea 相当于 stylus&#xff0c;可以自定义页面。测试过几个&#xff0c;只有几个可行。…

Linux so文件无法找到及某条命令找不到的解决办法

前言 在一些定制软件中可能会自带so文件。或者自带一些二进制命令。 这时会如果运行某个程序会发生 **.so 文件无法找到的错误。 以及 * 某条命令无法找到的错误。 比如像是下面这样 解决办法&#xff1a; so文件无法找到 通过往 LD_LIBRARY_PATH 变量中追加路径来告诉程序…

数组还可以这样用!常用但不为人知的应用场景

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

Linux:多线程的操作

多线程操作 进程与线程线程的创建 create_pthread创建线程池给线程传入对象的指针 线程等待 pthread_join退出线程 pthread_exit线程等待参数 retval 与 线程退出参数 retval 线程中断 pthread_cancel获取线程编号 pthread_self线程分离 pthread_detach 进程与线程 进程是资源…

为CAP面板天添加简单的认证功能 C#|.net

做过后端的比较熟悉&#xff0c;CAP面板有个界面&#xff0c;可以通过域名加cap访问&#xff1a; 但是这个面板直接通过url就可以访问了。 Hangfire Dashboard有自己的面板&#xff0c;可以使用用户名和密码做简单的认证。 LogDashboard也有自己的面板&#xff0c;可以使用用…

Apache HttpClient总览

一、重大版本 Apache HttpClient 4.x 系列 • HttpClient 4.0&#xff08;发布于2008年左右&#xff09;&#xff1a;这是一个重要的里程碑&#xff0c;标志着HttpClient从Jakarta Commons项目转移到Apache HttpComponents项目。4.0版进行了大量的重构&#xff0c;引入了新…

谷歌利用人工智能来推动搜索,显示出其组织信息的方式存在问题

谷歌利用人工智能来推动搜索&#xff0c;显示出其组织信息的方式存在问题 从相关文件到新闻报道、商业、音乐和社会互动&#xff0c;世界上的大部分信息现在都在网上。谷歌成立于1998年&#xff0c;其使命是“组织世界上的信息&#xff0c;使其普遍可用和有用”&#xff0c;它…

STM32理论 —— μCOS-Ⅲ(2/2):时间管理、消息队列、信号量、任务内嵌信号量/队列

文章目录 9. 时间管理9.1 OSTimeDly()9.2 OSTimeDlyHMSM()9.3 OSTimeDlyResume()9.4 延时函数实验 10. 消息队列10.1 创建消息队列函数OSQCreate()10.2 发送消息到消息队列函数(写入队列)OSQPost()10.3 获取消息队列中的消息函数(读出队列)OSQPend()10.4 消息队列操作实验 11. …

深度学习500问——Chapter11:迁移学习(2)

文章目录 11.2 迁移学习的基本思路有哪些 11.2.1 基于样本迁移 11.2.2 基于特征迁移 11.2.3 基于模型迁移 11.2.4 基于关系迁移 11.2 迁移学习的基本思路有哪些 迁移学习的基本方法可以分为四种。这四种基本方法分别是&#xff1a;基于样本的迁移&#xff0c;基于模型的迁移&a…

【高阶数据结构】红黑树详解

目录 前言一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树的插入情况1&#xff1a;cur为红&#xff0c;parent为红&#xff0c;grandfather为黑&#xff0c;uncle为红情况2&#xff1a; cur为红&#xff0c;parent为红&#xff0c;grandfather为黑&#xff0c…