C语言——函数递归与迭代

 各位CSDN的uu们大家好呀,今天将会给大家带来关于C语言的函数递归的知识,这一块知识理解起来稍微会比较难,需要多花点时间。

话不多说,让我们开始今天的内容吧!

目录

1.函数递归

1.1 什么是递归?

1.2 递归的两个必要条件

1.3 递归实例练习

2.函数的迭代

2.1 什么是迭代

2.2 递归与迭代实例

2.2.1 求第n个斐波那契数

2.2.2 实现n的阶乘

3.总结


1.函数递归

1.1 什么是递归?

递归是程序调用自身的一种编程技巧,也是在程序设计语言中被广泛应用的一种算法,一个过程或函数在其定义或说明中有直接或间接调用自身的方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,这样一来,只需少量的程序就可以描述出解题过程所需要的多次重复计算,大大减少程序的代码量。

递归的思考方式:把大化小

1.2 递归的两个必要条件

·在使用递归时一定要设定限制条件,当满足这个限制条件时,递归就不再继续;

·每次递归调用之后越来越接近这个限制条件。

1.3 递归实例练习

1.接收一个无符号整型值,按顺序打印它的每一位

如:输入1234 打印1 2 3 4

代码实现如下:

#include<stdio.h>void print(int n)
{if (n > 9){print(n/10);}printf("%d ", n % 10);
}int main()
{int num = 0;scanf("%d", &num);print(num);return 0;
}

我们来看一下输入1234后的运行结果:

 

 可以看到,运行结果符合我们的需求。现在让我们一起来阅读这段代码,看看函数的递归体现在哪里:

我们在main函数中用scanf对定义的num变量进行输入赋值,并调用print函数,将num的值传给print,完成了main函数的编写,我们回到main函数前面(函数先声明(定义)后使用),开始print函数的实现;

这里print函数的实现通过画图给大家讲解(很重要!!!):

2.函数的迭代

2.1 什么是迭代

迭代是函数利用自身已有的变量来推算需要的新变量,和递归直接调用自身存在一定差异,二者在某些情况下是可以相互转换的,同种情况下,这两种方法优先考虑迭代,因为递归很容易造成栈溢出,下面就通过两个实例来感受一下迭代与递归的差异。

2.2 递归与迭代实例

2.2.1 求第n个斐波那契数

斐波那契数列是一个特殊的数列,从第三项开始,每一项都是前两项之和,

1,1,2,3,5,8,......,(n-2),(n-1),(n-2)+(n-1)

现在我们用递归的方法实现一下:

#include<stdio.h>
//递归实现求第n个斐波那契数
int fib(int n)
{if (n <= 2)return 1;elsereturn fib(n - 2) + fib(n - 1);
}int main()
{int n = 0;scanf("%d", &n);printf("%d", fib(n));return 0;
}

但事实上,用递归求第n个斐波那契数会出现很多重复的计算,我们可以通过画图来看一下:

假设我们要求第50个斐波那契数: 

那么就要调用fib函数求第49个和第48个,求第49个和第48个又要再调用fib函数求第48、47、46个,其中第47个还调用了两次,越往下存在的重复计算越多,这样即浪费内存空间,又可能造成栈溢出。

为了让大家更清晰地感受到求第n个斐波那契数需要调用fib函数的次数,我们在原先代码基础上改进一下:

#include<stdio.h>
int count = 0;
int fib(int n)
{
//这里计算的是第三个斐波那契数被重复计算多少次if (n == 3)count++;if (n <= 2)return 1;elsereturn fib(n - 2) + fib(n - 1);
}int main()
{int n = 0;scanf("%d", &n);/*printf("%d\n", fib(n));*/printf("%d", count);return 0;
}

我们来求一下第40个斐波那契数,运行一下看看count的值是多少:

 可以看到,count的值高达39088169,也就是说第三个斐波那契数被重复计算了39088169次。

为了避免这种不必要的大量重复计算,我们采用了非递归的形式改进代码,也就是迭代,代码实现如下:

#include<stdio.h>int fib(int n)
{int result;int pre_result;int next_older_result;result = pre_result = 1;while (n > 2){n--;next_older_result = pre_result;pre_result = result;result = pre_result + next_older_result;}return result;
}int main()
{int n = 0;scanf("%d", &n);int ret = fib(n);printf("%d", ret);return 0;
}

可以看到,在fib函数里,程序通过while循环不断使用两个已知变量求第三个需要的变量,这样的方式要比直接调用函数自身(即递归)减少很多重复计算。

2.2.2 实现n的阶乘

#include<stdio.h>//递归实现
int factorial(int n)
{if (n <= 1)return 1;elsereturn n * factorial(n - 1);
}//迭代实现
int  factorial(int n)
{int result = 1;while (n > 1){result *= n;n--;}return result;
}int main()
{int n = 0;scanf("%d", &n);printf("%d", factorial(n));return 0;
}

实现n的阶乘和求第n个斐波那契数也是同样的道理,uu们可以自行探究一下,用递归求n的阶乘,会造成多少重复计算。

3.总结

我们要知道,系统分配给程序的空间是有限的,如果出现了死循环或者是死递归,就可能导致系统一直不停地开辟栈空间,最终耗尽栈空间,造成栈溢出的现象。

许多问题以递归的形式来解释,会让问题变得更清晰易懂,但这些问题的迭代实现往往要比递归实现效率更高,但同样的,迭代实现的代码理解起来没有递归那么容易。

在能用迭代的情况下,尽量不用递归,除非该问题的迭代实现非常复杂,那么此时递归实现的简洁性就足以弥补它运行时所产生的一系列问题。

这篇文章就到这里啦,关于递归与迭代的知识,还需要uu们多去找题练习,递归虽好,但不要经常用哦。

如果你觉得这篇文章对你有帮助的话,麻烦动动小手为我点个赞哦,你的喜欢就是我创作的动力!

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

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

相关文章

藏品馆管理系统

藏品馆管理系统 项目简介 这是一个基于 PHP 开发的藏品馆管理系统&#xff0c;实现了藏品管理、用户管理等功能。 藏品馆管理系统 系统架构 开发语言&#xff1a;PHP数据库&#xff1a;MySQL前端框架&#xff1a;BootstrapJavaScript 库&#xff1a;jQuery 目录结构 book/…

centos停服 迁移centos7.3系统到新搭建的openEuler

背景 最近在做的事&#xff0c;简单来讲&#xff0c;就是一套系统差不多有10多台虚拟机&#xff0c;都是centos系统&#xff0c;版本主要是7.3、7.6、7.9&#xff0c;现在centos停止维护了&#xff0c;转为了centos stream&#xff0c;而centos stream的定位是&#xff1a;Red …

什么是 IDE?集成开发环境的功能与优势

原文&#xff1a;什么是 IDE&#xff1f;集成开发环境的功能与优势 | w3cschool笔记 &#xff08;注意&#xff1a;此为科普文章&#xff0c;请勿标记为付费文章&#xff01;且此文章并非我原创&#xff0c;不要标记为付费&#xff01;&#xff09; IDE 是什么&#xff1f; …

jenkins批量复制Job项目的shell脚本实现

背景 现在需要将“测试” 目录中的所有job全部复制到 一个新目录中 test2。可以结合jenkins提供的apilinux shell 进行实现。 测试目录的实际文件夹名称是 test。 脚本运行效果如下&#xff1a; [qdevsom5f-dev-hhyl shekk]$ ./copy_jenkins_job.sh 创建文件夹 test2 获取源…

VisualSVN过期后的解决方法

作为一款不错的源代码管理软件&#xff0c;svn还是有很多公司使用的。在vs中使用svn&#xff0c;大家一般用的都是VisualSVN插件。在30天试用期过后&#xff0c;它就不能被免费使用了。下面给大家讲如何免费延长过期时间&#xff08;自定义天数&#xff0c;可以设定一个很大的值…

硬件工程师笔记——电子器件汇总大全

目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能&#xff08;将电能转化为热能&#xff09; 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 &#xff08;…

[图论]Kruskal

Kruskal 本质&#xff1a;贪心&#xff0c;对边进行操作。存储结构&#xff1a;边集数组。适用对象&#xff1a;可为负权图&#xff0c;可求最大生成树。核心思想&#xff1a;最短的边一定在最小生成树(MST)上&#xff0c;对最短的边进行贪心。算法流程&#xff1a;对全体边集…

vulnhub five86系列靶机合集

five86 ~ VulnHubhttps://www.vulnhub.com/series/five86,272/ five86-1渗透过程 信息收集 # 主机发现 nmap 192.168.56.0/24 -Pn ​ # 靶机全面扫描 nmap 192.168.56.131 -A -T4 目录扫描 dirsearch -u http://192.168.56.131/ /robots.txt提示/ona。 /ona二层目录扫描。 …

如何高效利用呼叫中心系统和AI语音机器人

要更好地使用呼叫中心系统和语音机器人&#xff0c;需要结合两者的优势&#xff0c;实现自动化、智能化、高效率的客户服务与业务运营。以下是优化策略和具体实践方法&#xff1a; 一、呼叫中心系统优化 1. 智能路由与IVR优化 智能ACD&#xff08;自动呼叫分配&#xff09; …

Nacos安装及数据持久化

1.Nacos安装及数据持久化 1.1下载nacos 下载地址&#xff1a;https://nacos.io/download/nacos-server/ 不用安装&#xff0c;直接解压缩即可。 1.2配置文件增加jdk环境和修改单机启动standalone 找到bin目录下的startup.cmd文件&#xff0c;添加以下语句(jdk路径根据自己…

【牛客练习赛137 C】题解

比赛链接 C. 变化的数组(Easy Version) 题目大意 一个长度为 n n n 的非负数组 a a a&#xff0c;要求执行 k k k 次操作&#xff0c;每次操作如下&#xff1a; 有 1 2 \frac{1}{2} 21​ 的概率令 a i ← a i ( a i ⊗ m ) x , ∀ i ∈ [ 1 , n ] a_i \leftarrow a_…

Redis适用场景

Redis适用场景 一、加速缓存二、会话管理三、排行榜和计数器四、消息队列五、实时分析六、分布式锁七、地理位置数据八、限流九、数据共享十、签到 一、加速缓存 Redis最常见的应用之一是作为缓存层&#xff0c;用于存储频繁访问的数据&#xff0c;从而减轻数据库的负载。 通过…

【LangChain4j快速入门】5分钟用Java接入AI大模型,Spring Boot整合实战!| 附源码

【LangChain4j快速入门】5分钟用Java接入AI大模型&#xff0c;Spring Boot整合实战&#xff01; 前言&#xff1a;当Java遇上大模型 在AI浪潮席卷全球的今天&#xff0c;Java开发者如何快速拥抱大语言模型&#xff1f;LangChain4j作为专为Java打造的AI开发框架&#xff0c;以…

2025第十七届“华中杯”大学生数学建模挑战赛题目B 题 校园共享单车的调度与维护问题完整成品正文33页(不含附录)文章思路 模型 代码 结果分享

校园共享单车运营优化与调度模型研究 摘 要 本研究聚焦校园共享单车点位布局、供需平衡、运营效率及故障车辆回收四大核心问题&#xff0c;通过构建一系列数学模型&#xff0c;系统分析与优化共享单车的运维体系。 针对问题一&#xff0c;我们建立了基于多时段观测的库存估算…

Unity游戏多语言工具包

由于一开始的代码没有考虑多语言场景&#xff0c;导致代码中提示框和UI显示直接用了中文&#xff0c;最近开始提取代码的中文&#xff0c;提取起来太麻烦&#xff0c;所以拓展了之前的多语言包&#xff0c;降低了操作复杂度。最后把工具代码提取出来到单独项目里面&#xff0c;…

.NET MCP 文档

MCP 概述 MCP&#xff08;Model Context Protocol&#xff09;是由 Anthropic 推出的一种开放协议&#xff0c;类似 AI 的 USB-C 扩展坞&#xff0c;用于在大模型和数据源之间建立安全的通信&#xff08;授权&#xff09;&#xff0c;让 AI 应用能够安全地访问和操作本地或远程…

【Linux】vim配置----超详细

目录 一、插件管理器准备 二、目录准备 三、安装插件 一、插件管理器准备 Vim-plug 是一个Vim插件管理器&#xff0c;利用异步并行可以快速地安装、更新和卸载插件。它的安装和配置都非常简单&#xff0c;而且在操作过程中会给出很多易读的反馈信息&#xff0c;是一个自由、…

PHP实现图片自动添加水印效果

<?php // 设置原始图片路径和水印图片路径 $original_image original.jpg; $watermark_image watermark.png;// 创建图片资源 $original imagecreatefromjpeg($original_image); $watermark imagecreatefrompng($watermark_image);// 获取图片尺寸 $original_width im…

检查新接手LINUX服务器应用的部署情况和正在运行的服务

当接手一台新的 Linux 服务器时&#xff0c;第一要务就是摸清系统上已经安装部署了哪些应用和服务。 本文将以 CentOS7为例&#xff0c;详细介绍如何系统地排查已安装的应用和服务&#xff0c;包括它们的安装方式和安装位置。 1.查看系统基本信息 首先获取系统整体信息&…

使用注解方式整合ssm时,启动tomcat扫描不到resource下面的xxxmapper.xml问题,解决方法

解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.mapper.方法 在Spring与Mybatis整合时&#xff0c;可能会遇到这样的报错 原因&#xff1a; 其原因为mapper路径的映射错误&#xff0c;表示在尝试执行某个 Mapper 接口的方法时…