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

C语言—简单认知函数递归

C语言—简单认知函数递归

1. 什么是递归

在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。

#include<stdio.h>intmain(){printf("hehe\n");main();//main函数中⼜调⽤了main函数return0;}

上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问题,代码最终也会陷⼊死递归,导致栈溢出。

1.1 递归的思想

把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。

1.2 递归的限制条件

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

  • 递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。
  • 每次递归调⽤之后越来越接近这个限制条件。

2. 递归的限制条件

2.1 举例1:求n的阶乘

⼀个正整数的阶乘是所有⼩于及等于该数的正整数的积,并且0的阶乘为1。
⾃然数n的阶乘写作n!。

分析和代码实现

我们知道n的阶乘的公式: n! = n ∗ (n − 1)!

举例: 5! = 5*4*3*2*1 4! = 4*3*2*1 所以:5! = 5*4!

这样的思路就是把⼀个较⼤的问题,转换为⼀个与原问题相似,但规模较⼩的问题来求解的。
我们可以写出函数Fact求n的阶乘,假设Fact(n)就是求n的阶乘,那么Fact(n-1)就是求n-1的阶乘,函数如下:

#include<stdio.h>intFact(intn){if(n==0)return1;elsereturnn*Fact(n-1);}intmain(){intn=0;scanf("%d",&n);intret=Fact(n);printf("%d\n",ret);return0;}

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

输⼊⼀个整数m,按照顺序打印整数的每⼀位。

输⼊:1234 输出:1 2 3 4 输⼊:520 输出:5 2 0
分析和代码实现

如果n是⼀位数,n的每⼀位就是n⾃⼰。
n是超过1位数的话,就得拆分每⼀位。

1234%10就能得到4,然后1234/10得到123,这就相当于去掉了4 然后继续对123%10,就得到了3,再除10去掉3,以此类推 不断的 %10 和 /10 操作,直到依次得到 4 3 2 1

我们发现⼀个数字的最低位是最容易得到的,通过%10就能得到
那我们假设想写⼀个函数Print来打印n的每⼀位,如下表⽰:

Print(n) 如果n是1234,那表⽰为 Print(1234) //打印1234的每⼀位 其中1234中的4可以通过%10得到,那么 Print(1234)就可以拆分为两步: 1. Print(1234/10) //打印123的每⼀位 2. printf(1234%10) //打印4 完成上述2步,那就完成了1234每⼀位的打印 那么Print(123)⼜可以拆分为Print(123/10) + printf(123%10)

直到被打印的数字变成⼀位数的时候,就不需要再拆分,递归结束。
那么代码完成也就⽐较清楚:

voidPrint(intn){if(n>9){Print(n/10);}printf("%d ",n%10);}intmain(){intm=0;scanf("%d",&m);Print(m);return0;}

3. 递归的举例

递归是⼀种很好的编程技巧,但是和很多技巧⼀样,也是可能被误⽤的,就像举例1⼀样,看到推导的公式,很容易就被写成递归的形式:

intFact(intn){if(n==0)return1;elsereturnn*Fact(n-1);}

Fact函数是可以产⽣正确的结果,但是在递归函数调⽤的过程中涉及⼀些运⾏时的开销。
所以如果不想使⽤递归,就得想其他的办法,通常就是迭代的⽅式(通常就是循环的⽅式)。
⽐如:计算 n 的阶乘,也是可以产⽣1~n的数字累计乘在⼀起的。

intFact(intn){inti=0;intret=1;for(i=1;i<=n;i++){ret*=i;}returnret;}

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

http://www.jsqmd.com/news/750440/

相关文章:

  • 3步拯救你的艾尔登法环存档:EldenRingSaveCopier完整指南
  • KMS_VL_ALL_AIO:Windows和Office免费激活终极指南
  • Windows任务栏美化革命:TranslucentTB透明化工具深度体验指南
  • 终极KMS激活解决方案:如何免费智能激活Windows与Office全系列产品
  • DS4Windows:让PS4/PS5手柄在Windows上获得完美游戏体验的终极方案
  • 如何在Obsidian中实现Excel表格编辑:5个实战技巧让你告别数据管理烦恼
  • ncmdumpGUI终极指南:快速解密网易云音乐NCM文件的完整解决方案
  • DS4Windows终极指南:3步实现PlayStation手柄在Windows完美兼容
  • 2026年深圳抖音短视频代运营公司选择指南:多维护筛选本土服务商 - 深圳昊客网络
  • STM32F407做FFT频谱分析时,你踩过‘栅栏效应’和‘频谱泄露’的坑吗?
  • MBC方法:解决LLM内存扩展与持续学习难题
  • 思源宋体TTF:为什么这款免费字体能解决你90%的中文排版难题?
  • Flash Attention 2.0 安装踩坑记:从 ‘No module named torch‘ 到成功运行的完整避坑指南
  • 实测 Taotoken 聚合 API 的响应延迟与稳定性观感分享
  • MyBatis-Plus分页查询踩坑记:从默认500条限制到灵活突破的完整配置流程
  • Android端Switch文件一键传输全攻略:NS-USBLoader移动版实战指南
  • 告别rpx!在UniApp项目中用PostCSS插件一键切换rem单位(附配置详解)
  • Translumo终极指南:3步实现屏幕实时翻译的完整教程
  • 微信立减金“沉睡福利”变可用额度:2026回收渠道与价格全解析 - 可可收
  • 如何在 MATLAB 中调用 Taotoken 聚合大模型 API 接口
  • 通过 curl 命令直接测试 Taotoken API 连通性与基础功能
  • 3个技巧彻底掌握Translumo:从手动翻译到实时屏幕翻译的蜕变之旅
  • 从光纤到网线:手把手拆解ADOP万兆电口模块里的CDR芯片选型与配置
  • DeepBI:通过竞品分析重塑亚马逊广告投放策略
  • 【GitHub 爆火 5k+Star】【Hugging Face ml-intern 】全解析:从论文到模型发布,ML 开发全流程自动化
  • 高效智能抖音批量下载器:一站式解决视频合集保存难题
  • 山东大学软件学院项目实训-创新实训-计科智伴(二)——只能互动与练习
  • 2026年3月吸音板公司口碑推荐,空心格栅/七槽格栅/木饰面/A级防火板/集成墙板/防撞板/木塑面,吸音板企业哪家好 - 品牌推荐师
  • 3大核心特性解析:MyTV-Android如何为老旧电视注入新活力
  • Vivado 2019.1 + Petalinux 实战:分离式设备树与PL动态加载避坑指南