当前位置: 首页 > news >正文

函数递归(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的时候,需要很长时间才能算出结果,这个计算所花费的时间,是我们很难接受的,这也说明递归的写法是非常低效的,那是为什么呢?其实递归程序会不断的展开,在展开的过程中,我们很容易就能发现,在递归的过程中会有重复计算,而且递归层次越深,冗余计算就会越多。在这里插入图片描述
就像上面的图片上展示的,计算一个数值,就要将它拆分成另外两个数,以此类推,会循环很多很多次,也造成了巨大的计算量,所以在有些时候我们不妨试试另一种方法,例如迭代的方法,其实循环也算是迭代的一种,下图计算将递归的方法转换成迭代的方式去实现这个代码,效率就要高出很多了。有时候,递归虽好,但是也会引⼊⼀些问题,所以我们⼀定不要迷恋递归,适可而止就好。在这里插入图片描述

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

相关文章:

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

函数递归 一. 递归是什么1.1 递归的思想1.2 递归的限制条件 二. 递归举例2.1 求n的阶乘2.2 按顺序打印一个整数的每一位 三. 递归与迭代3.1 求第n个斐波那契数 一. 递归是什么 递归是学习C语言很重要的一个知识&#xff0c;递归就是函数自己调用自己&#xff0c;是一种解决问题…...

uniapp 接口请求封装

根目录下创建 config目录 api.js request.js // request.js // 封装一个通用的网络请求函数 适当调整 function httpRequest(options) {const userToken uni.getStorageSync(access_token).token;return new Promise((resolve, reject) > {uni.request({url: ${options.ur…...

C++中的观察者模式

目录 观察者模式&#xff08;Observer Pattern&#xff09; 实际应用 股票价格监控系统 发布-订阅系统 总结 观察者模式&#xff08;Observer Pattern&#xff09; 观察者模式是一种行为型设计模式&#xff0c;它定义了对象间的一对多依赖关系。当一个对象的状态发生改变…...

conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式

1、pytorch版本安装&#xff08;卸载也会有问题&#xff09; &#xff08;1&#xff09;版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 &#xff08;2&#xff09;对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…...

第 5 章:面向生产的 Spring Boot

在 4.1.2 节中&#xff0c;我们介绍了 Spring Boot 的四大核心组成部分&#xff0c;第 4 章主要介绍了其中的起步依赖与自动配置&#xff0c;本章将重点介绍 Spring Boot Actuator&#xff0c;包括如何通过 Actuator 提供的各种端点&#xff08;endpoint&#xff09;了解系统的…...

在 Windows 操作系统中,可以通过命令行工具来杀死进程

1. 使用 taskkill 命令 taskkill 命令是一个用于终止进程的命令行工具&#xff0c;可以通过进程名称或进程 ID (PID) 来杀死进程。 按进程名称杀死进程 taskkill /IM processname.exe /Fprocessname.exe 是进程的名称。/F 参数表示强制终止进程。 例如&#xff0c;终止名为…...

uni-app文件下载 h5 xls 乱码 锟斤拷 Blob pdf打不开

原先下载方式&#xff0c;PC管理端和浏览器打开文件能下载&#xff0c;xls没出现乱码&#xff0c;pdf能正常显示,H5下载xls乱码锟斤拷&#xff0c;PDF显示空白内容 怀疑是前端问题&#xff0c;也尝试过修改后端代码 后端设置编码格式 response.setCharacterEncoding(characte…...

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…...

stable diffusion中的negative prompt是如何工作的

https://stable-diffusion-art.com/how-negative-prompt-work/https://stable-diffusion-art.com/how-negative-prompt-work/https://zhuanlan.zhihu.com/p/644879268...

STM32项目分享:智能小区充电桩系统

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

PDU模块中浪涌保护模块与空开模块的应用

由于PDU具体应用的特殊性&#xff0c;其在规划设计时具有应用场景的针对性&#xff0c;同时PDU的高度定制化的特点&#xff0c;是其他电气联接与保护产品所不具备的。 PDU基础的输出输入功能外&#xff0c;其电路的控制与电压保护器同时也极为重要。空气开关和浪涌保护器相关功…...

19、Go Gin框架集成Swagger

介绍&#xff1a; Swagger 支持在 Gin 路由中使用一系列注释来描述 API 的各个方面。以下是一些常用的 Swagger 注释属性&#xff0c;这些属性可以在 Gin 路由的注释中使用&#xff1a; Summary: 路由的简短摘要。Description: 路由的详细描述。Tags: 用于对路由进行分类的标…...

自动同步库数据——kettle开发36

kettle中的那些人工智能。 一、kettle的AI能力目录 跨库同步 2.自动开发 3.自动优化 二、AI实例 1、跨库同步 sqlsever表同步至oracle数据库 1.1源库sqlserver 1.2目标库oracle 1.3可视化跨库同步 使用多表复制向导 选择跨库的表&#xff0c;下一步下一步&#xff0c;即可…...

MSOCache在电脑中可以删除吗?

MSOCache文件夹在电脑中是可以删除的。但删除前需要了解以下几点&#xff1a; MSOCache文件夹的作用&#xff1a; MSOCache文件夹是Microsoft Office的本地安装源&#xff0c;用于存储Office安装和更新过程中所需的临时文件&#xff0c;如安装程序所需的组件、配置设置以及更新…...

数据网格和视图入门

WinForms数据网格&#xff08;GridControl类&#xff09;是一个数据感知控件&#xff0c;可以以各种格式&#xff08;视图&#xff09;显示数据。本主题包含以下部分&#xff0c;这些部分将指导您如何使用网格控件及其视图和列&#xff08;字段&#xff09;。 Grid Control’s…...

雨的轮回与生命的律动

雨的轮回与生命的律动 我们生活在一个充满变数的世界里&#xff0c;许多事情无法预测&#xff0c;如同这不知何时会停歇的雨。然而&#xff0c;尽管我们无法预知雨停的确切时刻&#xff0c;但我们深知&#xff0c;这场雨终将会过去&#xff0c;阳光终将再次洒满大地。这种对未…...

CANopen for Python 使用教程(二)

系列文章目录 前言 CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务&#xff0c;而不是符合标准的主实施。 该库支持 Python 3.6 及以上版本。 一、特点 该库主要用作主库。 NMT 主站…...

前方碰撞缓解系统技术规范(简化版)

前方碰撞缓解系统技术规范(简化版) 1 系统概述2 工作时序3 预警目标4 功能条件5 HMI开关6 显示需求7 相关子功能8 TTC标定参考9 指标需求1 系统概述 前方碰撞缓解系统包含LW潜在危险报警、FCW前方碰撞预警和AEB自动紧急制动三个部分。 LW潜在危险报警:根据本车与前车保持的…...

数据赋能(117)——体系:数据收集——实施过程、应用特点

实施过程 数据收集过程是一个系统化、有序的步骤集合&#xff0c;旨在确保能够准确、高效地获取所需数据。以下是数据收集过程的基本步骤&#xff1a; 明确数据需求&#xff1a;这是数据收集的第一步&#xff0c;需要明确需要收集哪些类型的数据&#xff0c;这些数据将如何支…...

【吃包子game】

如果您想要编写一个简单的“吃包子”游戏代码&#xff0c;可以使用Python语言来实现。下面是一个简单的例子&#xff0c;该游戏会随机生成一定数量的包子&#xff0c;玩家每次可以吃掉一个包子&#xff0c;直到包子被吃光为止。 import random def eat_dumplings():# 随机生成…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...