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

设计灵感的网站天河网站建设报价

设计灵感的网站,天河网站建设报价,在线平面设计作图网站,兖州住房与城乡建设局网站递归 递归是函数调用自身的一种编程技术。在C语言中,递归的实现会占用内存栈(Call Stack),每次递归调用都会在栈上分配一个新的 “栈帧(Stack Frame)”,用于存储本次调用的函数局部变量、返回地…

递归

递归是函数调用自身的一种编程技术。在C语言中,递归的实现会占用内存栈(Call Stack),每次递归调用都会在栈上分配一个新的 “栈帧(Stack Frame)”,用于存储本次调用的函数局部变量、返回地址、参数等信息。简单点说:自己调自己。

顾名思义:

例子: fun(void){//一定要有结束条件 fun()}例子: 从 1 + 2 + 3 + ... + 100 
函数递归的缺陷: 非常耗内存 不建议在函数中使用递归,如果将栈的内存耗尽,程序执行会出现报错:Segmetation fault (core dumped)

那么,在递归的过程中到底发生了什么事情呢? 以下将通过文字解析和图示说明递归对内存的占用情况,让大家直观的看见递归的过程。

栈帧(Stack Frame)的组成

每次函数调用(包括递归调用),都会在内存栈区中分配一个栈帧,主要用于存储以下内容:

  1. 函数参数:函数调用时传入的参数。
  2. 返回地址:函数执行完后需要返回到调用函数的位置,返回地址存储在栈帧中。
  3. 局部变量:函数内部定义的局部变量。
  4. 其他信息:如寄存器保存、栈指针、帧指针等(具体取决于编译器和硬件架构)。

递归调用时,每次调用都会创建一个新的栈帧,压入到内存栈中。递归结束时,函数逐层返回,栈帧依次弹出释放。

递归的内存占用过程

代码一:(上述示例)
使用递归的方式从 1 + 2 + 3 + … + 100 :
递归分析
递归代码
代码图示
下面举一个更复杂的例子。
代码二:

#include <stdio.h>void recursiveFunction(int n) {if (n == 0) {printf("Recursion ends.\n");return;}printf("Entering recursion: n = %d\n", n);// 递归调用recursiveFunction(n - 1);printf("Exiting recursion: n = %d\n", n);
}int main() {recursiveFunction(3);return 0;
}

执行过程分析:

  1. 初次调用 recursiveFunction(3),程序会在栈中分配一个栈帧,用于存储 n = 3 的值。
  2. 函数内部调用 recursiveFunction(2),再次分配栈帧,存储 n = 2
  3. 如此递归,直到 n = 0,递归结束,开始逐层返回,栈帧依次弹出。
图示解析(递归占用内存的变化)

假设每个栈帧包含以下内容:

  • 函数参数 n。
  • 函数的返回地址。
  • 函数内部的局部变量(假设没有其他局部变量)。

调用栈变化过程

1. 初始状态(main 函数调用 recursiveFunction(3)):

|--------------------|
|  main() Frame      |  <-- 栈顶
|--------------------|

2. 第一次递归调用(recursiveFunction(3)):

|--------------------|
|  recursiveFunction |
|  参数: n = 3       |
|  返回地址: main()  |
|--------------------|
|  main() Frame      |
|--------------------|

3. 第二次递归调用(recursiveFunction(2)):

|--------------------|
|  recursiveFunction |
|  参数: n = 2       |
|  返回地址: recursiveFunction(3) |
|--------------------|
|  recursiveFunction |
|  参数: n = 3       |
|  返回地址: main()  |
|--------------------|
|  main() Frame      |
|--------------------|

4. 第三次递归调用(recursiveFunction(1)):

|--------------------|
|  recursiveFunction |
|  参数: n = 1       |
|  返回地址: recursiveFunction(2) |
|--------------------|
|  recursiveFunction |
|  参数: n = 2       |
|  返回地址: recursiveFunction(3) |
|--------------------|
|  recursiveFunction |
|  参数: n = 3       |
|  返回地址: main()  |
|--------------------|
|  main() Frame      |
|--------------------|

5. 第四次递归调用(recursiveFunction(0)):

|--------------------|
|  recursiveFunction |
|  参数: n = 0       |
|  返回地址: recursiveFunction(1) |
|--------------------|
|  recursiveFunction |
|  参数: n = 1       |
|  返回地址: recursiveFunction(2) |
|--------------------|
|  recursiveFunction |
|  参数: n = 2       |
|  返回地址: recursiveFunction(3) |
|--------------------|
|  recursiveFunction |
|  参数: n = 3       |
|  返回地址: main()  |
|--------------------|
|  main() Frame      |
|--------------------|

6. 递归返回(n = 0 开始返回):

  • 栈帧逐层弹出,释放内存,最终只剩下 main() 的栈帧。
递归的内存占用与栈深度

递归深度与内存占用的关系

  • 每次递归调用会分配一个新的栈帧,因此递归深度越大,占用的栈内存越多。
  • 如果递归深度过大,可能导致栈溢出(Stack Overflow)

栈溢出代码

#include <stdio.h>void recursiveFunction(int n) {printf("n = %d\n", n);recursiveFunction(n + 1);  // 无限递归
}int main() {recursiveFunction(1);return 0;
}

运行上述程序会导致栈溢出,因为递归调用的栈帧无限增长,超过了栈的容量。

ulimit -a // 自行查看 stack size 栈的内存空间大小,开发过程中注意栈的使用量
优化递归的内存占用

1. 尾递归优化

  • 尾递归是指递归调用发生在函数的最后一步,编译器可以优化为循环,避免创建多个栈帧。
    代码:
#include <stdio.h>void tailRecursiveFunction(int n, int result) {if (n == 0) {printf("Result: %d\n", result);return;}tailRecursiveFunction(n - 1, result + n);
}int main() {tailRecursiveFunction(5, 0);  // 计算 1+2+3+4+5return 0;
}
  • 尾递归可以被优化为循环,避免栈溢出。

2. 转换为迭代

  • 如果递归深度过大,可以将递归转换为迭代,用循环替代递归。
    代码:
#include <stdio.h>void iterativeFunction(int n) {while (n > 0) {printf("n = %d\n", n);n--;}
}int main() {iterativeFunction(5);return 0;
}

综上。便是递归的内存占用过程。递归虽然简单优雅,但需要仔细处理内存占用和递归深度问题,特别是在资源受限的嵌入式系统中需要特别注意内存空间的使用情况。

  • 内存占用的特点:
    • 每次递归调用占用一个栈帧,存储函数参数、返回地址、局部变量等。
    • 栈帧数量与递归深度成正比。
  • 图示说明:
    • 栈的内存布局是递归调用的直观体现,栈帧逐层压入和弹出的过程展示了递归的内存管理。
  • 优化建议:
    • 使用尾递归或将递归转换为迭代以避免栈溢出。
    • 控制递归深度,避免过深的递归调用。

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

http://www.yayakq.cn/news/757717/

相关文章:

  • 网站建设方案平台架构重庆无障碍网站建设
  • 广州网站推广自助wordpress 4.7.1下载
  • 德庆网站建设公司wordpress 破解主题下载地址
  • 环保类网站模板免费下载wordpress 远程图片本地化
  • 推荐几个看黄的网站免费手机端网站模板下载工具
  • 宁波东钱湖建设局网站wordpress评论发邮件
  • 建设网站找谁郑州网站建设学校
  • 深圳住建设局网站公租房酒水代理加盟免费铺货
  • cms系统创建静态网站wordpress加会员中心
  • 网页教程网站wordpress在文章底部加上说明
  • 深圳注明企业网站设计wordpress pdf检索
  • 发明迷网站豆渣做豆腐智慧团建网站密码
  • 石家庄新钥匙网站建设网站备案登录
  • 网站程序开发制作十大品牌网页心得体会400字
  • 微信网站流程二手优品哪个网站做
  • 建设网站贵吗wordpress访客切换主题
  • 哈尔滨seo建站专业企业网站建设多少钱服务
  • 宜兴网站设计网站建设阶段的推广
  • 遵义网站开发培训网站如何做图片自动切换
  • 财经直播网站建设wordpress菜单显示用户
  • 淄博哪里有网站建设平台织梦网站地图模板样式
  • 工艺品网站域名wordpress加js
  • 天津网站制作南昌湖州网站开发区火炬手
  • 如何自己做网站建设定制号码需要多少钱
  • 佛山商城网站制作广西工程建设质量管理协会网站
  • dw做框架网站徐州市经济技术开发区建设局网站
  • 泉州cms建站系统呼和浩特网站seo优化方案
  • 东莞网络推广公司排行榜长沙有实力seo优化
  • 淘宝联盟网站建设不完整标准件网站开发
  • 杭州seo优化seo免费课程