【C语言】函数递归详解(一)

目录

1.什么是递归:

1.1递归的思想:

1.2递归的限制条件:

2.递归举例:

2.1举例1:求n的阶乘:

[2.1.1 分析和代码实现:](#2.1.1 分析和代码实现:)

2.1.2图示递归过程:

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

2.2.1分析和代码实现:

2.2.2图示递归过程:


1.什么是递归:

❓递归是学习C语言函数绕不开的一个话题,那什么是递归呢
⭐递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。

写一个简单的C语言递归代码:

cpp 复制代码
#include<stdio.h>
int main()
{
	printf("hehe\n");
	mian();
	return 0;
}

上述就是一个简单的递归程序,只不过上面的递归只是为了演示递归的基本形式,不是为了解决问题,代码最终会陷入死递归,导致栈溢出(Stack overflow)。

栈溢出的原因:

⭐我们每次调用printf()函数时都会在栈区开辟一块空间,因为上述代码会死递归,所以会一直调用printf()函数,但是栈区的空间是有限的,当栈区满了之后我们再调printf()函数时,系统想继续分配空间此时就会栈溢出(Stack overflow)。

1.1递归的思想:

把一个大型复杂的问题层层转化为一个与原问题相似,但规模较小的子问题来求解;直到子问题不能再被拆分,递归就结束了。所以递归过程就是把大事化小的过程

递归中的递就是递推 的意思,归就是回归的意思,接下来慢慢体会 。

1.2递归的限制条件:

递归在书写的时候,有2个必要条件:

1.递归存在限制条件,当满足这个限制条件时,递归便不再继续。

2.每次递归调用之后越来越接近这个限制条件。(渐渐停下来)

在下面的例子中,我们会逐步体会这两个限制条件

2.递归举例:

2.1举例1:求n的阶乘:

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

自然数n的阶乘写作n!

2.1.1 分析和代码实现:

以5!为例子我们进行分析

5!=5*4*3*2*1 = 5*4!

4!= 4*3*2*1 = 4*3!

3!= 3*2*1 = 3*2!

2!= 2*1 = 2*1!

1!= 1 = 1*0!

0!=1

通过观察5!我们可以发现当n>0时,n!=n*(n-1)!,当n=0时,n!=1。

如下图所示:

因此我们可以定义求n!函数为Fact(n),当n>0时,Fact(n)=n*Fact(n-1),当n=0时,Fact(n)=1。

代码实现如下:

cpp 复制代码
#include<stdio.h>
int Fact(int n)
{
	if (n > 0) 
	{
		return n * Fact(n - 1);
	}
	else
	{
		return 1;
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fact(n);
	printf("%d", ret);
}

运行结果如下:

2.1.2图示递归过程:

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

输入一个整数m,按照顺序打印整数的每一位

例如:

输入:1234 输出:1 2 3 4

输入:520 输出:5 2 0

2.2.1分析和代码实现:

这个题目,放在我们面前,首先想到的是,怎么得到这个数的每一位呢?

如果n是一位数,那么取出的数字就是它本身,如果n超过一位数(即n>9),就需要拆分每一位。

例如1234:

1234%10得到4,1234/10得到123,相当于去掉了4,继续对123%10得到3,123/10得到12,以此类推,不断重复%10和/ 10的操作,直到1234的每一位都得到;但是我们按照此方法得到的不是1 2 3 4而是倒着的4 3 2 1.

那么我们可以这么想,每一个数字的最低位置是最容易得到的,通过%10就可以得到

我们设想写一个函数Print()来打印n的每一位,如下表示:

Print(n)
如果n是1234,则表示为
Print(1234)//打印1234的每一位
其中1234中的4可以通过%10得到
那么Print(1234)可以分为两步:
1.Print(1234/10)//相当于Print(123)打印123的每一位
2.printf(1234%10)//打印4
完成了上述两个步骤就完成了1234的每一位打印
那么Print(123)又可以拆分为Print(123/10)+printf(123%10)

以此类推下去就有:

直到被打印的数字变成一位数的时候,就不再需要拆分,递归完成,有了上述的分析,代码可以清晰的写出,如下所示:

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

运行结果如下:

2.2.2图示递归过程:

以上便是我为大家带来的函数递归的第一部分内容,若有不足,望各位大佬在评论区指出,谢谢大家!可以留下你们点赞、收藏和关注,这是对我极大的鼓励,我也会更加努力创作更优质的作品。再次感谢大家!

相关推荐
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师2 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java4 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山4 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
hikktn5 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
睡觉谁叫~~~5 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程5 小时前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust