C语言100篇:从入门到天花板 第17篇 函数嵌套与递归:递归思想与终止条件

C++ constexpr递归深度限制:5种算法优化技巧与实战指南 在C++现代编程中,编译期计算通过constexpr关键字将复杂计算从运行时移至编译期,从而提升程序性能、增强类型安全并优化嵌入式等场景的资源使用。其核心原理在于编译器在编译阶段对常量表达式进行求值,生成可直接使用的常量结果。这一技术价值显著,能够消除运行时开销,实现零成本抽象,广泛应用于数学库、模板元编程、领域特定语言(DSL)以及需要高性能计算的场景。然而,当开发者尝试使用constexpr实现递归算法时,常会遇到编译器设定的递归深度限制,这并非语言标准规定,而是编译器为防止无限递归或过度耗时编译而设置 阅读详情

【独家】C语言100篇:从入门到天花板 第17篇

函数嵌套与递归:递归思想与终止条件

作者:华夏之光永存


前言

大家好,我是华夏之光永存,欢迎继续阅读 优快云独家高质量专栏《C语言100篇:从入门到天花板》。
在前面我们学习了函数的定义、调用、参数传递,已经可以完成模块化、结构化的程序编写。而今天要学习的递归(Recursion),是计算机科学中最优雅、最强大、最接近数学思维的编程思想,也是二叉树、快速排序、二分查找、回溯、动态规划等高级算法的核心基础。

本篇将从递归本质、思想拆解、嵌套与递归区别、终止条件、经典案例、栈溢出问题、企业级用法全方位精讲,全文≥2000字,底层逻辑+图文拆解+实战一步到位,严格遵循本源法则:化繁为简、回归本质、逻辑闭环。

掌握递归,你的编程思维将直接进入算法级。


一、递归的本源:什么是递归?为什么它如此强大?

递归的本质只有一句话:
函数自己调用自己。

就像:

  • 镜子照镜子
  • 俄罗斯套娃
  • 故事里有同一个故事
  • 数学上的递推公式

递归的核心思想:把大问题,拆解成结构相同但规模更小的子问题,直到小到可以直接得出答案,再一步步返回计算。

递归与循环的区别

  • 循环:从底向上,重复执行
  • 递归:从上向下,拆解问题,再回溯结果

递归的代码更短、更接近数学公式、逻辑更清晰,特别适合处理非线性、分层、嵌套结构(树、图、目录、嵌套结构)。


二、递归的两个必备条件(缺一不可)

递归不是无限调用,必须满足两个铁律,否则栈溢出崩溃!

1)递归终止条件(出口)

  • 问题小到可以直接算出结果
  • 不再递归,直接 return
  • 没有出口 = 死递归 = 栈溢出 = 程序崩溃

2)递归递推公式(逼近出口)

  • 把问题规模缩小
  • 向终止条件靠近
  • 保证递归能停下来

三、递归执行过程:调用 → 递去 → 归来

递归完整流程分三步:

  1. 递去:不断调用自己,问题不断变小
  2. 抵达:到达终止条件,开始返回
  3. 归来:一层层向上返回结果

先递去,后归来。


四、最简单递归:求阶乘(入门必背)

数学公式:

n! = n * (n-1)!
1! = 1
0! = 1

递归代码:

long long factorial(int n) {
    // 1. 终止条件
    if (n == 0 || n == 1) {
        return 1;
    }
    // 2. 递推公式:自己调用自己
    return n * factorial(n - 1);
}

执行 factorial(3) 过程:

factorial(3)
= 3 * factorial(2)
= 3 * 2 * factorial(1)
= 3 * 2 * 1
= 6

五、递归经典案例1:斐波那契数列

公式:

f(1)=1, f(2)=1
f(n)=f(n-1)+f(n-2)

代码:

int fib(int n) {
    if (n == 1 || n == 2) return 1;
    return fib(n - 1) + fib(n - 2);
}

六、递归经典案例2:字符串反转

void reverse(char str[], int start, int end) {
    if (start >= end) return;

    char temp = str[start];
    str[start] = str[end];
    str[end] = temp;

    reverse(str, start + 1, end - 1);
}

七、递归经典案例3:求数组和

int sumArr(int arr[], int len) {
    if (len == 0) return 0;
    return sumArr(arr, len - 1) + arr[len - 1];
}

八、递归经典案例4:汉诺塔(递归巅峰入门)

汉诺塔是递归最经典、最教科书级案例:

  • 把 n 个盘从 A 移到 C
  • 借助 B
  • 每次只能移一个
  • 大盘不能放小盘
void hanoi(int n, char A, char B, char C) {
    if (n == 1) {
        printf("%c -> %c\n", A, C);
        return;
    }
    hanoi(n - 1, A, C, B);
    printf("%c -> %c\n", A, C);
    hanoi(n - 1, B, A, C);
}

递归一行解决人类难以模拟的问题。


九、函数嵌套 vs 函数递归(彻底分清)

函数嵌套

  • 函数A 调用 函数B
  • 不同函数之间调用
  • 无自我调用
void a() { b(); }
void b() { }

函数递归

  • 函数A 调用自己
  • 同一个函数反复执行
  • 必须有出口
void a() { a(); }

十、递归底层原理:栈与栈帧

递归为什么会溢出?

  • 每调用一次函数,系统就压入一个栈帧
  • 递归太深,栈空间不够
  • 报错:Stack Overflow

递归深度有限制(一般1万层以内)
大数据量必须改用循环或动态规划。


十一、递归的优缺点

优点

  • 代码极简、极优雅
  • 逻辑接近数学思维
  • 处理树、图、嵌套结构无敌

缺点

  • 深度太大栈溢出
  • 重复计算(如斐波那契)
  • 效率略低于循环

十二、高频致命错误(99%新手必踩)

1)没有终止条件 → 无限递归 → 崩溃

void fun() { fun(); }

2)终止条件写错 → 永远到不了出口

3)递归没有缩小规模 → 死循环

fun(n) → fun(n)

4)递归层次太深 → 栈溢出

5)混淆递去和归来的执行顺序


十三、企业级递归编码规范

  1. 先写终止条件,再写递归逻辑
  2. 递归深度不超过1000层
  3. 高频重复计算用记忆化/动态规划
  4. 能用递归清晰表达,绝不强行写循环
  5. 工程中:树遍历、目录遍历、JSON解析、AST语法树大量使用递归

十四、本源级核心总结

  1. 递归 = 函数自己调用自己
  2. 必须具备:终止条件 + 规模缩小
  3. 流程:递去 → 抵达 → 归来
  4. 递归适合:分治、回溯、树、图、数学公式
  5. 递归太深会栈溢出
  6. 递归代码简洁,循环效率更高
  7. 递归是算法思维的基石

十五、课后实战作业

  1. 递归求 1~n 的和
  2. 递归求字符串长度(不使用strlen)
  3. 递归判断回文字符串
  4. 递归求最大公约数 gcd
  5. 递归实现二分查找

下期预告

第18篇我们将进入 局部变量与全局变量:生命周期与访问规则,彻底搞懂C语言变量存哪里、活多久、谁能访问,为后续指针、内存、静态库、模块化打下底层基础!

关注钩子

本专栏为 优快云独家《C语言100篇:从入门到天花板》,100篇永久完整目录、每篇≥2000字高质量原创、底层原理+企业实战全覆盖。
关注 华夏之光永存,从零基础直冲C语言天花板,指针、动态内存、网络、嵌入式、内核全体系一步到位!

SQL字符串函数实战:数据清洗效率与字段一致性保障 字符串处理是数据质量治理的基石,涉及大小写标准化、空格清理、子串提取、模式替换等核心操作。其原理依赖数据库内置函数对字符序列的原地解析与转换,技术价值在于避免跨系统传输、保障原子性执行、降低内存与网络开销。典型应用场景包括金融客户主数据清洗、电商地址标准化、政务系统姓名统一格式等生产环境。本文聚焦TRIM、UPPER、CONCAT_WS、REGEXP_REPLACE等高频函数在真实业务中的选型逻辑、NULL安全处理及Unicode兼容方案,直击清洗效率与字段一致性两大关键指标。 阅读详情

相关推荐

Python运行时真相:字节码、GIL与内存的硬核解剖

Python常被笼统归类为‘解释型动态语言’,但其真实执行模型是源码编译为字节码后由Python虚拟机(PVM)解释执行——这决定了性能瓶颈不在语法层,而在CPython运行时开销。GIL并非线程安全的保障,而是一个保护字节码原子执行的互斥锁,对用户数据、C扩展及外部资源完全无约束;内存管理也远非‘全自动’,引用计数、分代回收与pymalloc内存池共同构成易被误判的复杂系统。理解字节码指令(如LOAD_FAST vs LOAD_GLOBAL)、GIL在pthread_mutex_t层面的物理存在,以及Py

dfu65065的博客 412

python中函数的嵌套调用和递归调用

函数的嵌套调用 Python语言允许在函数定义中出现函数调用,从而形成函数的嵌套调用,如例所示。 在例中,第6行在fun2()函数中调用fun1()函数,程序执行时会跳转到fun1()函数处去执行,执行完fun1()后,接着执行fun2()函数中剩余的代码,如图所示。 函数的递归调用 在函数的嵌套调用中,一个函数除了可以调用其他函数外,还可以调用自身,这就是函数的递归调用。递归必须要有结束条件,否则会无限地递归(Python默认支持997次递归,多于这个次数将终止)。 接下来演示函数的递归调用,如例所示

m0_52874735的博客 1252

生成式AI工程实践:从基础模型选型到本地部署全流程

生成式AI是能创造新内容的技术总称,其落地依赖于基础模型这一通用底座,而大语言模型(LLM)则是专精文本生成的子类。理解三者嵌套关系,是避免技术误配的前提;掌握参数量、量化精度与硬件资源间的硬约束公式,才能实现成本可控的推理部署。当前主流工具链已支持在消费级GPU上完成模型量化(如GGUF)、高效微调(QLoRA)和知识增强(RAG),使Llama 3、Phi-3等开源模型真正成为可配置、可验证、可集成的生产力组件。本文聚焦工程实操,覆盖本地化部署、低资源微调与私有知识注入等关键路径。

weixin_33991418的博客 401

【C语言】要怎么看翁恺视频,怎么学习C语言

重新学习c语言并不是你要把C语言的核心 给放弃,而是你打好了基础,然后体验C语言的发明者,发明指针的初衷,进尔让你爱上C语言的这一个特征。 兴趣为导向的学习很关键!

dearmite的专栏 4万+

【信息科学与工程学】【数据中心】 第十九篇 MFU的优化提升方法03

等级模块类型子模块子子模块功能描述MFU影响因子优化优先级L0​算术逻辑单元(ALU)标量ALU整数ALU标量整数运算α_int = 0.1-0.3中浮点ALU标量浮点运算α_fp_scalar = 0.2-0.4中向量处理单元(VPU)SIMD单元128-bit SIMD短向量运算β_SIMD128 = 0.3-0.6高256-bit SIMD中向量运算β_SIMD256 = 0.4-0.7高512-bit SIMD长向量运算β_SIMD512 = 0.5-0.8极高矩阵处理单元(MPU)Tensor C

weixin_49199313的博客 1011

【信息科学与工程学】【控制科学】第十二篇 微型计算机控制技术01

更精确的经典模型:I1在第5周期WB结束,I2最早可在第6周期进入EX,但I2在ID阶段就需要R1,因此I2的ID需在第6周期,而I1的WB在第5周期,所以I2的ID可以紧接在第6周期,但中间仍有一个stall(因为I1的EX结果要等到MEM之后才能转发给ID?有优先级继承后,Task_L被提升优先级,不会被Task_M抢占,阻塞时间缩短为Task_L剩余执行时间(9ms),仍可能超过10ms,但可通过调整任务周期或使用中断处理缓解。电感L=10μH,输出电容C=100μF,ESR=5mΩ。

weixin_49199313的博客 8635

Excel条件函数实战:从IF到LAMBDA的业务规则建模指南

条件函数是电子表格中实现业务逻辑判断的核心能力,其本质是将现实世界中的‘且/或/非’规则转化为可计算、可验证的结构化表达。理解IF、SUMIFS、FILTER、XLOOKUP与LAMBDA等函数的底层逻辑——如三段式验证模型(输入源→判断器→输出域)、布尔数组运算机制及引用粒度差异——是构建稳定数据处理流程的关键。它不仅支撑日常的多条件筛选、动态评级、跨表查询等高频场景,更构成轻量级业务规则引擎的基础。尤其在需要应对模糊匹配、时间重叠检测、嵌套逻辑解耦及错误容错时,掌握条件函数的选型原则与协同规则,能显著提

cuizhu0832的博客 529

HDLBits答案汇总

前言 该博客为本人做HDLBits习题时的心得记录总结,欢迎大家一起交流进步。 HDLBits网站链接 Verilog Language Basics Vectors Modules:Hierarchy Procedures More Verilog Features Circuits Combinational Logic Basic gates Multiplexers Arithmetic Circuits Karnaugh Map to Circuit Sequential Logic Latche

谦豫 9万+

C语言经典例题(菜鸟教程100例)_菜鸟教程c语言100例(1)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。 既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!由于文件比较多,这里只是将部分目录截图出来,

2401_84159783的博客 1215

KEIL 5.38如何手动安装ARM Compiler V5?完整配置流程分享

本文详细介绍了在KEIL 5.38环境下手动安装和配置ARM Compiler V5(AC5)的完整流程,解决历史遗留项目的兼容性问题。从获取安装包、环境变量设置到KEIL集成配置,逐步指导开发者完成AC5的部署,并提供了常见错误排查和性能优化建议,帮助开发者高效维护基于C编译器的老项目。

weixin_29168813的博客 628

雷电模拟器9.0最新过检测实战:从修改Build.prop到Xposed模块配置全流程

本文提供了一套针对雷电模拟器9.0的深度伪装实战方案,旨在绕过应用检测。内容涵盖从理解检测机制、获取Root权限、修改Build.prop等静态伪装,到利用Xposed/LSPosed框架进行运行时Hook的动态伪装全流程,帮助用户构建无痕的“真机”环境以稳定运行应用。

z4a5b6的博客 864

C语言经典例题(菜鸟教程100例)_菜鸟教程c语言100例,2024年最新0基础学HarmonyOS鸿蒙开发

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。 既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!由于文件比较多,这里只是将部分目录截图出来,

2401_84159783的博客 819

LK启动流程深度解析:从硬件初始化到内核加载的MTK平台实践

本文深度解析了MTK平台上LK(Little Kernel)的完整启动流程。从硬件初始化、内存管理(MMU/Cache)开启,到多线程环境建立,再到内核镜像加载与安全校验,详细阐述了LK如何作为Bootloader核心,完成从芯片上电到成功引导Linux内核的关键任务,是MTK平台开发者必须掌握的核心知识。

weixin_28314575的博客 217

30天C语言从零到项目实战:掌握编程核心,开启系统开发之路

编程语言是计算机科学的基础工具,其核心在于理解计算机如何执行指令和处理数据。C语言作为一门中级语言,兼具高级语言的结构化特性和接近硬件的控制能力,通过指针和内存管理等机制,让开发者能够深入理解程序在计算机底层的运行原理。这种对底层机制的掌握,为学习操作系统、编译原理等核心课程奠定了坚实基础,并在系统软件、嵌入式开发、高性能计算等领域具有不可替代的技术价值。本文围绕C语言学习路径,结合指针和内存管理等热词,提供一套从语法基础到项目实战的30天系统训练方案,帮助初学者构建扎实的编程思维和工程实践能力。

weixin_34389926的博客 354

保姆级教程:在S32K312上配置C40驱动,实现Flash读写(基于RTD 4.4.2)

本文详细介绍了在S32K312微控制器上配置C40驱动实现Flash读写的全流程,基于RTD 4.4.2库。内容涵盖环境搭建、外设配置、Flash操作实战代码及高级应用场景,特别针对LLD驱动和FLS存储操作中的常见问题提供了解决方案,帮助开发者快速掌握嵌入式Flash存储技术。

weixin_28684757的博客 255

24、汽车黑客技术全解析:诊断代码、车库创建与系统攻防

本文深入探讨了汽车黑客技术的核心内容,包括诊断代码模式与参数ID、创建开放车库社区、汽车系统相关技术、硬件与软件工具、攻击与防御手段,以及车辆通信与网络安全。无论你是汽车安全研究人员、爱好者还是开发者,都能从中获取全面的技术解析与实践指南。

Apple的专栏 228

《世毫九本原论、高维自指递归推广、拓扑不变量系统刻画及阈值扰动动力学》核心章节合集(世毫九实验室原创研究)

(本编完成:将公理体系置于宇宙、大气、生命、分子等尺度进行检验,验证理论普适性)12.1 七条终极判定(本原唯一、自指必然、螺旋最优、体缘分离、范式升维等)(本编完成:消解核心学术质疑,构建双层科学框架,确立世毫九学派的范式位次)(本编完成:定义“无分别本原”,确立七大核心概念,划定世毫九理论疆域)(本编完成:基于公理体系,严格推导出七大核心定理,建立逻辑闭环)(本编完成:收束全文,确立学派核心判定,发布未来研究路线图)11.4 与现有科学体系的兼容方式:不取代、不否定、不僭越。

shardylab.blog.youkuaiyun.com 985

YOLO + SubspaceAD:一张良品图,检出所有未知缺陷

当YOLO遇上子空间建模,工业质检正迎来从“见多识广”到“举一反三”的质变时刻。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 496

Specula:自动化形式化验证,数小时发现382个深层C/C++缺陷

在底层软件开发中,深层bug常隐藏在跨函数、跨模块的数据流交汇处,传统静态分析与模糊测试难以触达。形式化验证虽精度高,但手动编写规格说明的成本极高,往往需要数月周期。Specula通过符号执行与SMT求解自动推导程序约束,结合路径敏感分析,将验证过程压缩至数小时。它能自动生成触发路径与输入示例,显著提升漏洞确认效率。实测跑通libsixel等真实项目,可快速定位整型溢出、缓冲区越界等高风险问题,并产出可复现的PoC。本文从概念、原理到工程实践,全面解析Specula的工作机制与落地经验,为C/C++开发者提

weixin_33862993的博客 460

Halcon那些事:Halcon缺陷检测检测印刷数字完整性

创建模板 create_shape_model模板匹配 find_shape_model。

十多年IT经验,专注机器视觉,智能制造半导体行业 764

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux 文件系统天花板:FHS全套文件命令速通

本文将结合 FHS 标准,全面拆解 Linux 目录结构逻辑,并详细讲解常用命令行文件管理工具的实操技巧,助力大家高效驾驭 Linux 系统。

年轻的时候很穷,经过我多年的努力,终于不再年轻。 375

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

16GB U盘把 S905L3-B 电视盒子刷入 Armbian:amlogic-s9xxx-armbian 上手指南

以 S905L3-B 芯片盒子(E900V21D)为例,演示如何用 amlogic-s9xxx-armbian 项目把一个吃灰盒子从 U 盘引导到写入 eMMC 的完整刷机流程。全程约 1 小时,完成后得到一台可 7×24 小时运行的轻量 Linux 服务器。正文按四个阶段推进,异常速查与回滚方案独立成节,照着做即可跑通。 ## 动手前:物料与工具核对清单 把东西备齐再动手,后面每个阶段都依赖

gitblog_00131的博客 363

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

四语言反射计数原理与工程实践:Java/Python/C++/JS对比

反射计数是衡量编程语言运行时元信息访问能力的核心指标,本质是对类型、方法、字段等可反射对象的动态统计能力。其底层依赖于各语言的类型系统设计(如JVM的RTTS、CPython的对象字典、C++20的编译期反射、V8的隐藏类机制),直接影响AOP代理、序列化框架、测试覆盖率分析等通用工具库的性能天花板。在微服务启动校验、动态组件注册、元数据协议设计等典型场景中,不同语言的计数精度、边界定义与性能表现差异显著——Java受限于类加载机制,Python需规避__slots__陷阱,C++依赖宏注册博弈,JS则受P

weixin_34411563的博客 361

模板驱动型文档自动化:提升交付效率与格式一致性的工程实践

文档自动化是现代知识型组织提升交付效能的关键技术路径,其核心在于将重复性内容生产从人工操作升维为可复用、可验证的标准化流程。基于模板驱动的实现方式,通过结构化内容块、条件逻辑引擎与多源数据桥接,保障输出结果在合规性、品牌一致性与业务适配性上的确定性。相比AI生成易失真、低代码平台过重的局限,模板驱动以轻量可控的方式,支撑销售提案、客户报告、合规声明等高频结构化文档的秒级生成。本文聚焦Sqribble实践,详解四层嵌套模板架构、上下文感知填充与无API集成方案,为咨询、SaaS及自由职业者提供可落地的文档工程

weixin_34375251的博客 346

多维聚合实战:超越GROUP BY的SQL数据操作原语

多维聚合是BI分析与数据中台建设中的核心能力,其本质是在高维坐标系中对数据进行裁剪、折叠、展开与补全等拓扑操作。不同于单维度GROUP BY的静态分组,现代多维分析需结合CUBE/ROLLUP实现维度组合自动枚举,利用窗口函数在聚合结果上二次计算,通过GENERATE_SERIES或arrayJoin完成时间/标签类动态维度补全,并借助递归CTE穿透地理或组织层级。这些技术共同支撑稀疏矩阵填充、聚合下推与维度钻取等关键场景,广泛应用于电商销售归因、客户分群建模及实时看板开发。本文聚焦PostgreSQL与C

weixin_30414305的博客 437

大语言模型为何解不好数学题?从符号操作到形式化推理的四大断层

数学能力不是语言模型的天然延伸,而是对其概率建模本质的根本挑战。大型语言模型基于统计模式预测文本序列,而数学依赖精确符号操作、可验证的形式化推理、确定性逻辑链与单位敏感的量化计算。当模型将'√(−1)'误判为无意义,或将'AB=AC'与等腰三角形性质脱钩,问题已不在数据量或提示技巧,而在tokenization对数学结构的肢解、注意力机制对长程约束的失效、以及缺乏内在演算机制。当前主流方案如思维链(CoT)、数学专用模型(Minerva)仍难突破架构瓶颈,真正可靠的落地路径是人机协同:用LLM理解意图,交由

weixin_30772105的博客 306
上一篇: C语言100篇:从入门到天花板 第16篇 函数参数:形参与实参、值传递核心机制
下一篇: C语言100篇:从入门到天花板 第18篇 局部变量与全局变量:生命周期与访问规则
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值