​【c语言】函数递归

1. 递归是什么

 递归是c语言学习上绕不开的话题,那么什么是递归呢?

递归实际上是自己调用自己。

2. 递归的限制条件

递归在书写的时候有两个限制条件:

递归存在限制条件,当满足这个限制条件式,递归将不再继续。

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

3. 递归举例

举例1:求n的阶乘

一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1.

那n的阶乘就可以写为:

n!= n * (n - 1)!

n - 1的阶乘又可以写为:

(n - 1)! = (n - 1) * (n - 2)!

...

最后得到2的阶乘:

2! = 2 * 1

这样我们就可以认为n! 从n * (n - 1)开始右边的乘数将会重复调用m * (m- 1) 这个函数,函数传参为n - 1,当传参被减为1时则停止调用(递归的限制条件)。这样调用函数的方式就被称为递归。

代码实现:

int fac(int m)
{int x = 0;if (n > 1){return fac(m - 1) * m;}else{return 1;}
}
int main()
{int x = 0;int n = 0;while(scand("%d",n)==1){x = fac(n);}printf("%d", x);return 0;
}

执行结果 :

执行步骤:

比如当我们输入4时就是按照下面的方式执行的 

向下展开的过程被称为递推,递推完后向上返回结果的过程被称为回归。

举例2:顺序打印一个整数的每一位

我们可以知道a%10后可以得到a的个位,a/10后可以删去a的个位。

那我们就可以这样写:

int main()
{int a = 1234;int ret = 0;while(a > 0){ret = a % 10;a /= 10;printf("%d ", ret);}return 0;
}

但这个代码是倒序打印一个整数的每一位,不符合题目的要求。那有什么方法能让它先打印整数的最大位呢?这时就要运用到递归了,递归是先递推把a展开后,然后再回归打印整数的每一位。

代码实现:

void A(int n)
{int ret = 0;if (n > 10){ret = n % 10;A(n / 10);printf("%d ", ret);}elseprintf("%d ", n);
}
int main()
{int n = 0;scanf("%d", &n);A(n);return 0;
}

执行结果: 

4. 递归与迭代

递归是⼀种很好的编程技巧,但是很多技巧⼀样,也是可能被误⽤的。

在递归函数调⽤的过程中涉及⼀些运⾏时的开销。

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

所以不想用递归就得想其他的方法,通常就是迭代的方式(通常就是循环的方式)。

例如,上面的举例1我们也可以使用循环的方式进行实现。

Fact(int n)
{int ret = 1;for (int i = 1; i <= n; i++){ret *= i;}return ret;
}
int main()
{int n = 0;scanf("%d", &n);int ret = Fact(n);printf("%d", ret);return 0;
}

 上诉代码的效率是比递归方式效率高的。

事实上,我们看到的许多问题是以递归的形式进⾏解释的,这只是因为它⽐⾮递归的形式更加晰,
但是这些问题的迭代实现往往⽐递归实现效率更⾼。
当⼀个问题⾮常复杂,难以使⽤迭代的⽅式实现时,此时递归实现的简洁性便可以补偿它所带来的运⾏时开销。

举例3:求第n个斐波那契数

法1:递归

A(int n)
{if (n > 2)return A(n - 1) + A(n - 2);elsereturn 1;
}
int main()
{int n = 0;scanf("%d", &n);int ret = A(n);printf("%d", ret);return 0;
}

法2:迭代

int main()
{int a = 1, b = 1, c;int n = 0;scanf("%d", &n);if (n > 2){while (n - 2){c = a;a = b;b = b + c;n--;}}printf("%d", b);return 0;
}

虽然上面的两种方法都可以得到正确的结果,但是使用递归的方法时,我们会发现这个方法计算的非常的慢,而使用迭代的方法计算则可以立即得到结果。(如下图)

这是因为每次递归调用都会在内存中创建一个新的栈帧来保存局部变量和返回地址,而导致内存的使用和时间开销的增加。

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

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

相关文章

PDF中公式转word

效果&#xff1a;实现pdf中公式免编辑 step1: 截图CtrlAltA&#xff0c;复制 step2: SimpleTex - Snip & Get 网页或客户端均可&#xff0c;无次数限制&#xff0c;效果还不错。还支持手写、文字识别 单张图片&#xff1a;选 手写板 step3: 导出结果选择 注&#xff1a;…

在flutter中集成Excel导入和导出

flutter中集成Excel导入和导出功能 1、需要的依赖 在pubspec.yaml #excel导出syncfusion_flutter_xlsio: ^24.1.45open_file: ^3.0.1#导入excelflutter_excel: ^1.0.1#选择文件的依赖file_picker: ^6.1.1&#xff08;1&#xff09;依赖说明 在测试时&#xff0c;我们在使用导…

《汇编语言:基于linux环境》通过sys_read, sys_write 实现大小写英文字母转换

x64 syscall 参数构造表 ; nasm -f elf64 -g -F dwarf uppercaser2.asm ; ld -o uppercaser2 uppercaser2.o ; gdb uppercaser2; ./uppercaser2 > (输出文件) < (输入文件) ;./uppercaser2 > 2.txt <1.txtSECTION .bssBUFFLEN equ 1024Buff: resb BUFFLENSECTION…

Qt 范例阅读: QStateMachine状态机框架 和 SCXML 引擎简单记录(方便后续有需求能想到这两个东西)

一、QStateMachine 简单应用&#xff1a; 实现按钮的文本切换 QStateMachine machine; //定义状态机&#xff08;头文件定义&#xff09;QState *off new QState(); //添加off 状态off->assignProperty(ui->pushButton_2, "text", "Off"); //绑定该…

Docker上安装配置tomcat

目录 1. 拉取镜像 2. 创建运行镜像 3. 查看是否创建成功 ps&#xff1a;如果出现404错误 tomcat目录结构 1. 拉取镜像 这里使用 tomcat:8.5.40 版本作为安装 docker pull tomcat:8.5.40 2. 创建运行镜像 docker run -d --name tomcat -p 8080:8080 \--privilegedtrue …

【红包封面发放+微信红包封面制作教程】小黑猫祝大家小年快乐~

今年终于成功获得了微信红包封面~是我们家的小黑猫&#xff0c;嘿嘿。 封面获取方式 一共还有600份&#xff0c;数量有限&#xff0c;大家想要的话请关注文末的公众号&#xff0c;访问红包封面相关的推文获取~ 平时公众号主要发布一些技术类工具知识&#xff0c;希望能帮到大…

个人网站如何让搜索引擎收录

当我们花费功夫搭建好个人网站&#xff0c;如何能让搜索引擎搜索到个人网站呢&#xff1f;比如百度&#xff0c;根本百度不到自己网站的内容。这时候就要使用到搜索引擎提供的站点收录功能了&#xff0c;但是点开百度的搜索资源平台&#xff0c;添加自己的站点时&#xff0c;就…

Notion 开源替代品:兼容 Miro 绘图 | 开源日报 No.162

toeverything/AFFiNE Stars: 25.6k License: NOASSERTION AFFiNE 是下一代知识库&#xff0c;将规划、排序和创建集于一身。它是一个注重隐私、开源、可定制且即插即用的替代方案&#xff0c;可以与 Notion 和 Miro 相媲美。主要功能和优势包括&#xff1a; 超融合&#xff1…

模拟请求ElasticSearch

Step1 安装chrome的这个插件 Step2 打开插件&#xff0c;GET的json填什么。 在IDEA的debug模式&#xff0c;走到Java代码的searchBuilder&#xff0c; 在这个searchBuilder变量里&#xff0c;对里面query变量点右侧 view按钮&#xff0c; IDEA里会显示出一个json&#xff…

MySQL 备份恢复

1.1 MySQL日志管理 在数据库保存数据时&#xff0c;有时候不可避免会出现数据丢失或者被破坏&#xff0c;这样情况下&#xff0c;我们必须保证数据的安全性和完整性&#xff0c;就需要使用日志来查看或者恢复数据了。 数据库中数据丢失或被破坏可能原因&#xff1a; 误删除数…

编程实例分享,眼镜店电脑系统软件,配件验光管理顾客信息记录查询系统软件教程

编程实例分享&#xff0c;眼镜店电脑系统软件&#xff0c;配件验光管理顾客信息记录查询系统软件教程 一、前言 以下教程以 佳易王眼镜店顾客档案管理系统软件V16.0为例说明 如上图&#xff0c; 点击顾客档案&#xff0c;在这里可以对顾客档案信息记录保存查询&#xff0c;…

【学员分享-考试心得】国产数据库潜力无限,云贝教育OBCP认证培训帮您解难题

近年来&#xff0c;随着国产化转型的推进&#xff0c;国外数据库的岗位需求逐渐减少&#xff0c;让许多IT从业者倍感压力。在这种情况下&#xff0c;了解国产数据库成为了求职市场上的竞争力。云贝老师们将聚焦于OceanBase、PostgreSQL、TDSQL等IT培训&#xff0c;探讨其对国产…