C语言--递归

news2024/9/22 5:31:15

在这里插入图片描述

曾经有一个段子:上大学时,我们的c语言老师说:学c时,如果有50%的同学死在了循环上面,那么就有90%的同学死在了递归上面。接下来,就来看看递归是怎么个事?

一.递归的介绍

递归是指一个函数直接或间接调用自身的过程。在编程中,递归通常用于解决可以被分解为相似子问题的任务。

  1. 基本原理:递归函数通过反复调用自身来解决问题,每次调用都会解决一个规模较小的子问题,直到达到递归的终止条件。

  2. 递归函数的结构

    • 基本情况(终止条件):递归函数需要定义一个或多个基本情况,这些情况下递归调用不再发生,避免无限循环。
    • 递归情况:在递归情况下,函数调用自身来解决同一问题的子问题。
  3. 递归与循环:递归和迭代循环(for、while循环)都可以实现相同的算法,但递归通常更简洁,易于理解,有时更符合问题的自然表达方式。

  4. 递归的应用:递归广泛用于数据结构==(如树、图等)的遍历和搜索==,例如深度优先搜索(DFS)和快速排序算法。

  5. 性能考虑递归可能会消耗大量的栈空间,因为每次函数调用都会在栈上分配一个新的栈帧。这在处理大规模问题时需要注意,可以通过优化算法或者尾递归优化来减少内存消耗。

  6. 递归的优缺点

    • 优点:简洁、清晰表达某些问题的解决方式。
    • 缺点:可能会因为调用层次过深导致栈溢出,性能上可能不如迭代循环。

二.什么是栈帧

栈帧(Stack Frame),也称为活动记录(Activation Record)或者帧(Frame),是在函数调用过程中在程序运行时栈上的一个特定区域,用于存储与当前函数调用相关的信息和数据。每当一个函数被调用时,系统就会为该函数在栈上分配一个新的栈帧,用于管理函数的局部变量、参数、返回地址以及其他执行上下文信息。

栈帧通常包括以下主要部分:

  1. 局部变量:函数内部声明的局部变量会被存储在栈帧中。这些变量的生命周期与函数的调用周期相关联,在函数调用结束时,这些变量的存储空间也会自动释放。

  2. 参数:调用函数时传递的参数值被存储在栈帧中,供函数体内部使用。

  3. 返回地址:函数调用完成后,程序需要返回到调用该函数的下一条指令的地址。返回地址存储在栈帧中,使得程序可以正确地返回到调用点继续执行。

  4. 其他管理信息:栈帧还可能包括调试信息、异常处理信息等,这些信息有助于程序的正确执行和调试。

栈帧的创建和销毁遵循后进先出(LIFO)原则,即最后进入栈的栈帧最先被释放。这种机制保证了函数调用的嵌套顺序正确,同时也控制了函数调用过程中的内存管理。

理解和正确使用栈帧是编写函数式程序的关键,尤其是在处理递归函数或者多层函数调用时,对栈帧的合理利用可以提高程序的效率和可靠性。

举例说明

有 5 个学生坐在一起, 问第 5 个学生多少岁?他说比第 4 个学生大 2岁,问第 4 个学生岁数,他说比第 3 个学生大 2 岁,问第 3 个学生,又说比第 2个学生大 2 岁,问第 2 个学生,说比第 1 个学生大 2 岁,最后问第 1 个学生,他说是 10 岁,请问第 5 个学生多大。
该问题如果使用非递归,代码如下:

//非递归求年龄
int Age1(int n)
{
	int tmp = 10; //第一个人年龄
	for(int i=1;i<n;i++)
	{
		tmp += 2;//后面的人比前一个多 2 岁
	}
		return tmp;
}

那么递归该如何处理呢?我们先分析一下:
如果 Age 函数是用来求年龄的,那么
Age(1)表示第一个人的年龄;
Age(2)表示第二个人的年龄;

Age(n-1)表示第 n-1 个人的年龄;
Age(n)表示第 n 个人的年龄。
上面的这些能理解,下面的程序就好理解了

//递归求年龄
int Age(int n)
{
	int tmp;//保存年龄
	if (n == 1)
		tmp = 10;
	else
		tmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个年龄多 2
	return tmp;
}

在这里插入图片描述
上图中的红色表示函数的调用过程,在这个过程中每个函数都还没有执行完成,那么每个函数占用的内存空间都不能释放,函数的调用都需要占用一定的栈空间(一个栈帧),而栈的空间是非常小的(在动态内存章节讲过栈 1M),当递归次数非常多时有可能出现栈空间不足

在这里插入图片描述

// 递归求年龄
int Age(int n)
{
	int tmp;//保存年龄
	if (n == 1)
		tmp = 10;
	else
		tmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个多 2
	return tmp;
	//return n == 1 ? 10 : Age(n - 1) + 2;//等同上面的代码
}
 //递归调用次数太多, 程序崩溃
int main()
{
	printf("%d\n", Age1(5000));//可以.利用循环求解
	//printf("%d\n",Age(5000));//崩溃,栈溢出,递归次数太多,超过栈容量
	return 0;
}

在这里插入图片描述

例2.求阶乘

利用递归求阶乘 n!
算法分析:可以利用下面公式求阶乘

在这里插入图片描述

long long Fac(int n)
{
	if (n == 0 || n == 1)
		return 1;
	return n * Fac(n - 1);
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CV09_深度学习模块之间的缝合教学(4)--调参

深度学习就像炼丹。炉子就是模型&#xff0c;火候就是那些参数&#xff0c;材料就是数据集。 1.1 参数有哪些 调参调参&#xff0c;参数到底是哪些参数&#xff1f; 1.网络相关的参数&#xff1a;&#xff08;1&#xff09;神经网络网络层 &#xff08;2&#xff09;隐藏层…

偶数位的数c++

题目描述 给你两个整数 l,r&#xff0c;求 l∼r 范围内有多少个位数为偶数的数。 输入 一行两个整数 l,r。 输出 输出位数为偶数的数的数量。 样例输入 5 15样例输出 6 提示 样例解释 10,11,12,13,14,15 位数为偶数&#xff0c;都是两位数。 数据规模与约定 对于 1…

过滤器、监听器、拦截器

目录 一、 主要内容 二、 过滤器 2.1 介绍 2.2 实现 MyFilter01 MyFilter02 MyServlet01 MyServlet02 2.3 说明 2.4 执行顺序 1. 使用 web.xml 2. 使用注解和Order 3. 使用FilterRegistrationBean 2.5字符乱码 三、监听器 3.1介绍 3.2实现 3.3在线人数统计 O…

克洛托光电再度合作福晶科技,高精度光学镜头装调仪正式交付

近日&#xff0c;苏州东方克洛托光电技术有限公司&#xff08;下称“克洛托光电”&#xff09;高精度光学镜头装调仪正式交付于福建福晶科技股份有限公司&#xff0c;研发人员在现场完成设备安装调试并介绍使用方法。据悉&#xff0c;这已是双方第二次展开合作。 前沿产品力助推…

企业知识库用不起来?试一下用HelpLook同步钉钉组织架构

提升企业管理和协同效率已成为增强竞争力的关键。企业通过知识管理&#xff0c;搭建内部知识库&#xff0c;将分散的经验和知识转化为系统化流程&#xff0c;减少重复解释&#xff0c;促进业务高效运作。这为企业提供了坚实的基础。 企业知识库面临的挑战 尽管传统知识库内容丰…

银河麒麟高级服务器操作系统V10加固操作指南

1:检查系统openssh安全配置: 2:检查是否设置口令过期前警告天数: 3:检查账户认证失败次数限制: 修改/etc/pam.d/system-auth文件中deny的参数即可 4:检查是否配置SSH方式账户认证失败次数限制:

github相关命令

如果我们要从 GitHub 上拉取一个项目到本地&#xff0c;进行修改并上传回去&#xff0c;通常需要以下步骤&#xff1a; 1. 克隆远程仓库到本地 使用 git clone 命令将 GitHub 上的项目克隆到本地&#xff1a; (网址示例如下所示&#xff09; git clone https://github.com/你的…

多旋翼无人机挂载多功能抛投器技术详解

多旋翼无人机&#xff0c;作为一种具有高效、灵活、稳定等特性的无人驾驶飞行器&#xff0c;在现代社会的多个领域得到了广泛应用。其中&#xff0c;挂载多功能抛投器技术&#xff0c;使得无人机在物资投送、救援等任务中发挥出更加重要的作用。以下将详细介绍多旋翼无人机挂载…

正则表达式怎么控制匹配的字符串更近的一个

http((?!http).)*m3u8 正则表达式怎么控制匹配的字符串更近的一个 正则如何匹配最近的字符 正则如何匹配最近的两个字符 怎么控制只要离字符串b匹配更近一点的字符串a 解释 a.b&#xff0c;它将会匹配最长的以a开始&#xff0c;以b结束的字符串 a.?b匹配最短的&#xff…

测试开发面经总结(三)

TCP三次握手 TCP 是面向连接的协议&#xff0c;所以使用 TCP 前必须先建立连接&#xff0c;而建立连接是通过三次握手来进行的。 一开始&#xff0c;客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口&#xff0c;处于 LISTEN 状态 客户端会随机初始化序号&…

微信小程序密码 显示隐藏 真机兼容问题

之前使用type来控制&#xff0c;发现不行&#xff0c;修改为password属性即可 <van-fieldright-icon"{{passwordType password? closed-eye:eye-o}}"model:value"{{ password }}"password"{{passwordType password ? true: false}}"borde…

数仓工具—Hive语法之排除特定列

排除特定列 Apache Hive是一个基于Hadoop HDFS的数据仓库框架,用于存储和分析大量数据。Apache Hive支持大多数关系数据库功能,如对大型表进行分区和根据分区列存储值。 在本文中,我们将检查从SELECT查询中排除Hive分区列的方法。 这个在我们需要表中大量列的时候,例如一…

【python】OpenCV—European Article Number

参考学习来自&#xff1a;OpenCV基础&#xff08;25&#xff09;条码和二维码扫的生成与识别 1 条形码介绍 EAN-13是欧洲物品编码&#xff08;European Article Number&#xff09;的缩写&#xff0c;是一种广泛使用的条形码标准&#xff0c;特别是在超级市场和其它零售业中。…

第二周周日学习总结

题目总结 1. 给你一个仅由数字组成的字符串 s&#xff0c;在最多交换一次 相邻 且具有相同 奇偶性 的数字后&#xff0c;返回可以得到的 字典序最小的字符串 。 如果两个数字都是奇数或都是偶数&#xff0c;则它们具有相同的奇偶性。例如&#xff0c;5 和 9、2 和 4 奇偶性…

zookeeper基础知识学习

官网&#xff1a;Apache ZooKeeper 下载地址&#xff1a;Index of /dist/zookeeper/zookeeper-3.5.7Index of /dist/zookeeperIndex of /dist/zookeeper/zookeeper-3.5.7 ZK配置参数说明&#xff1a; 1、tickTime2000&#xff1a;通讯心跳时间&#xff0c;zookeeper服务器与客…

Reinforced Causal Explainer for GNN论文笔记

论文&#xff1a;TPAMI 2023 图神经网络的强化因果解释器 论文代码地址&#xff1a;代码 目录 Abstract Introduction PRELIMINARIES Causal Attribution of a Holistic Subgraph​ individual causal effect (ICE)​ *Causal Screening of an Edge Sequence Reinforc…

Three.js 对创建的物体进行位置旋转缩放修改。

1.在场景里面添加一个物体作为示例 // 创建一个物体&#xff08;形状&#xff09;const geometry new THREE.BoxGeometry(5, 5, 5);//创建材质&#xff08;外观&#xff09;const material2 new THREE.MeshLambertMaterial({color: 0xfff, //设置材质颜色side: THREE.DoubleS…

SpringBoot + vue 管理系统

SpringBoot vue 管理系统 文章目录 SpringBoot vue 管理系统1、成品效果展示2、项目准备3、项目开发3.1、部门管理3.1.1、前端核心代码3.1.2、后端代码实现 3.2、员工管理3.2.1、前端核心代码3.2.2、后端代码实现 3.3、班级管理3.3.1、前端核心代码3.3.2、后端代码实现 3.4、…

Matlab 计算一个平面与一条直线的交点

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里使用一种很有趣的坐标:Plucker线坐标,它的定义如下所示: 这个坐标有个很有趣的性质,将直线 L L L与由其齐次坐标 V = (

STM32的定时器HAL库

目录 一&#xff0c;定时器的介绍 一&#xff0c;定时器的介绍 1. STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。 1.1 高级定时器&…