C语言学习笔记(五):函数递归 目录1. 什么是递归2. 递归的核心要素3. 递归经典案例3.1 求n的阶乘3.2 顺序打印一个整数的每一位4. 递归的问题与优化4.1 栈溢出风险5. 递归与循环的选择1. 什么是递归递归是一种编程技术指的是一个函数在其定义内部调用自身。最简单的递归程序虽然是错误的#includestdio.hintmain(){printf(hehe\n);main();// main函数自己调用自己return0;}这个程序会一直打印hehe直到程序崩溃。因为它是死递归没有终止条件最终会导致栈溢出。生活类比俄罗斯套娃打开一个大娃娃里面还有一个小娃娃再打开还有更小的……镜子中的镜子两面镜子对着照里面会出现无数层影像递归的核心思想就是把一个大型复杂问题层层转化为一个与原问题相似、但规模较小的子问题来求解直到子问题不能再拆分递归就结束了大事化小。2. 递归的核心要素一个正确的递归函数必须包含两个关键部分终止条件基础情况不再进行递归调用、能直接返回结果的特定条件。没有它递归会无限进行下去最终导致栈溢出。递归调用递推阶段函数自己调用自己每次调用时问题的规模都要比上一次更小逐步逼近终止条件。3. 递归经典案例3.1 求n的阶乘题目计算正整数 n 的阶乘0! 1不考虑溢出数学公式当 n 0 时0! 1当 n 0 时n! n × (n-1)!代码实现#includestdio.hintFact(intn){if(n0)return1;// 终止条件elsereturnn*Fact(n-1);// 递归调用规模变小}intmain(){intn0;scanf(%d,n);intretFact(n);printf(%d\n,ret);return0;}执行过程以 n5 为例Fact(5) 5 * Fact(4) 5 * 4 * Fact(3) 5 * 4 * 3 * Fact(2) 5 * 4 * 3 * 2 * Fact(1) 5 * 4 * 3 * 2 * 1 * Fact(0) 5 * 4 * 3 * 2 * 1 * 1 120递归写法 vs 循环写法递归写法intFact(intn){if(n0)return1;elsereturnn*Fact(n-1);}循环写法intFact(intn){intret1;for(inti1;in;i){ret*i;}returnret;}3.2 顺序打印一个整数的每一位题目输入一个正整数按顺序打印它的每一位数字。输入1234 → 输出1 2 3 4输入520 → 输出5 2 0思路分析一个数的最低位最容易得到1234 % 10 4去掉最低位1234 / 10 123把问题拆解为先打印前面所有位再打印最后一位当数字变成一位数时直接打印不再拆分代码实现#includestdio.hvoidPrint(intn){if(n9)// 如果不是一位数{Print(n/10);// 先递归打印前面所有位}printf(%d ,n%10);// 再打印最后一位}intmain(){intm0;scanf(%d,m);Print(m);return0;}执行过程以 1234 为例Print(1234) → Print(123) → Print(12) → Print(1) → printf(1) → printf(2) → printf(3) → printf(4) 输出结果1 2 3 44. 递归的问题与优化4.1 栈溢出风险每次函数调用都需要在内存的栈区申请一块空间称为栈帧来保存局部变量和函数调用信息。如果递归层次太深栈空间会被耗尽导致栈溢出。#includestdio.hintcount0;voidtest(){count;printf(当前递归深度%d\n,count);intbuffer[1000]{0};// 占用栈空间test();// 无限递归}intmain(){test();return0;}运行到一定深度后程序会崩溃因为栈空间被耗尽了。5. 递归与循环的选择很多递归问题都可以改写成循环版本循环通常效率更高。求阶乘对比递归写法intFact(intn){if(n0)return1;elsereturnn*Fact(n-1);}循环写法intFact(intn){intret1;for(inti1;in;i){ret*i;}returnret;}选择建议递归的优点是代码简洁、思路清晰适合树/图遍历、分治算法、回溯算法等场景循环的优点是效率高没有栈溢出风险一般建议递归深度 100 层且没有大量重复计算时可以放心使用递归如果递归存在明显性能问题改成循环版本总结递归就是函数自己调用自己记住两点终止条件和递归调用。终止条件让递归停下来递归调用让问题规模不断变小。递归能让代码变得很简洁但要注意栈溢出风险深度超过100层时建议改成循环。

相关新闻

最新新闻

C++动态数组原理与std::vector最佳实践

C++动态数组原理与std::vector最佳实践

1. 动态数组的核心概念与应用场景 动态数组是C中最基础也最重要的数据结构之一,它解决了静态数组长度固定的局限性。我在实际工程中经常遇到需要处理未知数量数据的场景,比如读取用户输入、解析日志文件或处理网络数据包时,动态数组都是首选解…

2026/8/9 14:51:44
ComfyUI-KJNodes:如何通过智能节点系统提升AI绘画工作流效率?

ComfyUI-KJNodes:如何通过智能节点系统提升AI绘画工作流效率?

ComfyUI-KJNodes:如何通过智能节点系统提升AI绘画工作流效率? 【免费下载链接】ComfyUI-KJNodes Various custom nodes for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-KJNodes ComfyUI-KJNodes 是专为ComfyUI设计的自定义节点…

2026/8/9 14:51:44
B站自动化任务管理终极指南:5分钟学会BiliBiliToolPro完整使用教程

B站自动化任务管理终极指南:5分钟学会BiliBiliToolPro完整使用教程

B站自动化任务管理终极指南:5分钟学会BiliBiliToolPro完整使用教程 【免费下载链接】BiliBiliToolPro B 站(bilibili)自动任务工具,支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。 项目地址: https://gitcod…

2026/8/9 14:51:44
完美世界竞技平台报JavaScript Error错误怎么办?Intel 13/14代CPU降频配合软领驱动大师修复

完美世界竞技平台报JavaScript Error错误怎么办?Intel 13/14代CPU降频配合软领驱动大师修复

完美世界竞技平台启动时弹出 JavaScript Error,很多玩家会先怀疑平台文件损坏,或者认为是 Node 环境异常。实际排查中,有一类情况很常见:搭载 Intel 第 13/14 代处理器的电脑,因为默认频率过高导致系统在运行 JS 进程时…

2026/8/9 14:51:44
解析 _for-sale DNS 记录:域名出售新方式的优势、实现及常见错误

解析 _for-sale DNS 记录:域名出售新方式的优势、实现及常见错误

跳转到主要内容 网站规范:优秀网站的特质 所有主题 检查清单 MCP 关于 贡献内容 搜索 ⌘K 所有主题 检查清单 搜索 更新日志 已考虑事项 MCP 服务器 关于 贡献内容 GitHub 分类 基础 SEO 可访问性 安全性 知名 URI 代理准备情况 性能 隐私 弹性 国际化 基础 SEO 可访…

2026/8/9 14:51:44
原创AU项目技术解析:从多媒体整合到本地部署实践

原创AU项目技术解析:从多媒体整合到本地部署实践

这次我们来看一个名为“浪潮05”的原创AU项目。从标题“登陴慷慨三通鼓”来看,这很可能是一个基于“小潮team”创作背景的、融合了音乐、叙事或多媒体元素的同人作品或独立创作项目。这类项目通常涉及音频处理、视频剪辑、原创配乐或互动叙事等技术栈。对于技术爱好…

2026/8/9 14:46:44