首页 > 其他分享 >C语言:函数递归

C语言:函数递归

时间:2024-11-14 15:43:52浏览次数:3  
标签:函数 递归 int 函数调用 C语言 main Fact

#include<stdio.h>
int main()
{
	printf("haha\n");
	main();
	return 0;
}

先来看这段代码,这是最简易的一段递归的代码。当我们打印完haha后会main函数调用自己,这样就会使屏幕一直打印haha,但是会停止,这是为什么呢?因为当我们为main函数在栈区开出的内存被不断使用,最后导致栈溢出,最后程序就崩了。当然这是一段不正确的递归函数,这里只是先用它引出递归的思路。说白了,递归的本质就是函数自己调用自己。

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

这是一段用递归思路写出来的算阶乘的代码,当n为1时,阶乘就等于1,当n大于1后,我们会发现

我们的Fact(n)函数所返回的值就等于Fact(n-1)*n,这时我们就可以使用递归使函数自己调用自己,最后算出阶乘。递归分成递推和回归。在这段代码中,当我们输入n为3时,Fact(3)函数返回时需要得到Fact(2)的值,再不断推到Fact(1)的值,这就是递归中的递推。当我们推出Fact(1)的值之后,我们就可以依次求出Fact(2),Fact(3)的值,这就是递归的回归。

如果我们使用递归函数,有两个要求需要满足。1.递归需要限制条件2.递归调用之后必须要变得更加接近限制条件。有了这两个条件才是正确的递归函数,否则会使函数不断递归,最后栈溢出。

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

这是一段打印整数每一位的代码,使用print函数来打印每一位的数,要从第一位开始。所以我们可以用n/10从n递推到第一位,然后一位位回归,回归时取得都是最后一位,所以用n%10。

综上所述,递归其实是一个很好的编程方式,但有时候也会有不足之处,例如用于斐波那契数列时,由于递归后很多数据都会重复计算,降低了计算的速率。不仅如此,在C语言中每一次函数调用,都需要为本次函数调用内存的栈区,申请一块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧。函数不返回,函数对应的栈帧空间就一直占用,所以如果函数调用中存在递归调用的话,每一次递归函数调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。所以如果采用函数递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stack overflow)的问题。

标签:函数,递归,int,函数调用,C语言,main,Fact
From: https://blog.csdn.net/shdbdndj/article/details/143768975

相关文章

  • 【Pytorch】神经网络介绍|激活函数|使用pytorch搭建方法
    神经网络神经网络介绍概念神经网络人工神经网络ANN也称神经网络NN是一种模仿生物神经网络结构和功能的计算模型人脑可以看作是一个生物神经网络,由众多神经元连接而成,神经网络可以看作是模拟生物神经元的过程输入层inputLayer:输入x的那一层输出层output......
  • 高级语言调用C接口(二)回调函数(1)
    前言先说一下上一篇文章给出了各高级语言类型和C类型的对应关系,只包含基本类型,不包含结构体等复杂结构,高级语言只有常见的JAVA(Android通用)、C#、Python、Arkts(鸿蒙系)。其它语言如delphi、PB之类的古老语言目前使用的人非常稀少,默认不写了;还有js调用需要编译位wasm,但限制非......
  • Day 13 迭代器 三元表达式 列表生成式 字典生成式 生成器 递归
    目录0上节课回顾0.1闭包函数0.2装饰器1迭代器2三元表达式和列表推导式2.1三元表达式(三目表达式)2.2列表推导式3字典生成式4生成器4.1yield关键字5递归0上节课回顾0.1闭包函数函数内部的变量无法被全局的相同名字的变量修改,局部变量和全局变量不是同一种东西deff1......
  • Day 14 匿名函数 内置函数 面向对象编程
    目录0上节课复习0.1迭代器0.1.1可迭代对象0.1.2迭代器对象0.1.3for循环原理0.2三元表达式0.3列表推导式0.4字典生成器0.5生成器0.5.1生成器表达式0.6递归0.7二分法1匿名函数1.1有名函数1.2匿名函数2内置函数2.1掌握2.2了解3面向过程编程0上节课复习0.1迭代......
  • C语言之动态内存申请
    动态内存的作用在开发中根据实际需求开辟内存内存申请分类静态内存申请(静态分配)1,在程序编译或运行过程中,按事先规定大小分配内存空间的分配方式,如inta[10];2,必须事先知道所需空间的大小3,分配在栈区或全局变量区,一般以数组形式4,按计划分配特点:在程序运行......
  • 探索 Python 函数式编程的瑞士军刀:Toolz 库
    文章目录探索Python函数式编程的瑞士军刀:Toolz库第一部分:背景介绍第二部分:Toolz库概述第三部分:安装Toolz库第四部分:Toolz库函数使用方法1.高阶函数2.计算管道3.字典合并4.分组5.累积计算第五部分:Toolz库使用场景场景1:学生分数统计场景2:数据流处理场景3:......
  • R语言使用caret包构建岭回归模型实战,构建回归模型、通过method参数指定算法名称、通过
    R语言使用caret包构建岭回归模型实战,构建回归模型、通过method参数指定算法名称、通过trainControl函数控制训练过程目录R语言使用caret包构建岭回归模型(RidgeRegression )构建回归模型、通过method参数指定算法名称、通过trainControl函数控制训练过程 #导入包和库#仿......
  • R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表
    R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表连接、data.table使用自定义函数及Reduce函数实现一次性性多表连接目录R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表连接#data.table是什么?#dat......
  • 《内存函数》
    内存函数1.memcpy函数(1)介绍这里通过memcpy的定义我们可以看这个函数包含三个参数,destination就是拷贝的目的地,source就是拷贝的源头,num就是拷贝的个数。(2)使用这里要包含头文件string.h这里的个数最好写成sizeof(类型)*个数的形式,因为你拷贝什么类型未定(3)memcpy函数......
  • C语言编程 1.11 寻找素数对
     #include<stdio.h>#include<math.h>intsushu(longlongn)        {            longlongsqrt_n=sqrt(n);            for(longlongi=2;i<=sqrt_n;i++)                {                 ......