C语言(长期更新)第8讲 函数递归
C语言(长期更新)
第8讲:函数递归
跟着潼心走,轻松拿捏C语言,困惑通通走,一去不回头~欢迎开始今天的学习内容,你的支持就是博主最大的动力。
目录
C语言(长期更新)
第8讲
函数递归
知识回顾
前言
8.1 什么是递归
8.1.1 where——啥时候用
8.1.2 how——怎么用
8.1.3 what——具体含义
8.2 递归实例1:计算阶乘
8.2.1分析与代码实现
8.2.2 画图分析
8.3 递归实例2:顺序打印一个整数的每一位
8.3.1分析与代码实现
8.3.2 画图分析
知识回顾
上节课我们学习了一些VS实用的调试技巧,今天我们来学习函数递归的内容,坐稳了,我们发车,gogogo!
前言
我们在先前解决问题时常常会用到循环来解决一些重复的操作,往往写代码时需要写很多行代码。今天我们来介绍一种全新解决问题的方法——函数递归(Recursion)
8.1 什么是递归
递归就是函数自己调用自己
举个🌰
比如上面的代码,在main函数中调用main函数,导致main函数无限调用,无限次打印"hehe"
运行一段时间后,弹出报错警告,我们看到报错信息中有一个stack overflow,就是栈溢出的意思。为什么会这样捏?因为每次main函数的运行都需要在内存中开辟空间,空间不够用了就造成栈溢出了。
上面是函数递归的错误使用,只是为了方便说明,下面我们就来详细介绍一下函数递归
8.1.1 where——啥时候用
函数递归常用于将一个大规模的问题转化为规模较小的同类子问题,直至问题不可继续拆解
这种大化小的思想赋予了函数递归常常以几行简单代码就能解决复杂问题的特性
8.1.2 how——怎么用
- 函数递归是有限制条件的,达到限制条件终止递归
- 每次递归都会逼近这个限制条件,以避免栈溢出
8.1.3 what——具体含义
递归二字递为递推,归为回归
8.2 递归实例1:计算阶乘
8.2.1分析与代码实现
我们知道一个数字的阶乘(Factorial)就是从1乘到这个数的积。可我们也可以换一种思路
你想,1!=1,2!=1*2=1!*2,...依此类推可得 n!=(n-1)!*n
唉,这不就递归了吗,算一个数的阶乘被转化为算比他小1的数的阶乘,比他小1的结成有转化为哦算比他小2的数的阶乘。以大化小,妙哉!
下面我们写代码
8.2.2 画图分析
先逐层函数递归,将大的问题拆解,层层深挖,推至无处可推,在逐层回归问题,一步一步将值代入,这就是递归。
8.3 递归实例2:顺序打印一个整数的每一位
8.3.1分析与代码实现
给一个数我们最容易得到的就是这个数的个位
想要拿到最高位的数字最容易想到的办法就是一层一层剥下来。每次除以10剥取最后一位,再取余
每一次都是对取过余的数做除以10的操作这就是重复性的同类子问题,因此我们可以使用递归
下面我们写代码
8.3.2 画图分析
8.4 迭代
递归虽然好用,但是也存在一些问题
比如说我们在计算阶乘时使用的Fac()函数,是可以产生正确的结果,但是在递归函数调用的过程中涉及一些运行时的开销。
在C语言中每一次函数调用,都需要为本次函数调用在内存的栈区,申请一块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧。
函数不返回,函数对应的栈帧空间就一直占用,所以如果函数调用中存在递归调用的话,每一次递归函数调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。
所以如果采用函数递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stackoverflow)的问题。
当受到这些问题的影响而无法使用函数递归时,我们就只能使用迭代(Iteration)了
迭代其实就是我们经常使用的循环
好了今天的学习内容就到这里啦,谢谢你的陪伴,我是潼心,下次再见~如果这篇文章对你有帮助的话。请务必给主播一个一键三连,球球了,这对主播很重要~