搜索

C语言函数递归调用问题。

gecimao 发表于 2019-04-18 14:25 | 查看: | 回复:

  1.我用fun1()一直调用其它函数或者自己本身时,原来函数会不会一直存在于内存中?(PS:我经过测试,函数在调用过程中,原函数会一直存在内存中,至到。。。。。)

  2.直到函数调用结束,然后逐个返回结束命令 (PS:这结束语句是方便理解用的) 或者逐个返回一个返回值。直到返回至最先开始调用的fun1()这个函数。然后结束。是不是这样?

  可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。

  展开全部函数其实没有释放内存的概念,因为函数都是在指令区,而不是通常所说的释放内存对应的数据区,不过在整个程序执行完之后指令区也是要释放的。

  所以在函数调用过程中原调用函数是不会退出的-----即你所说的释放内存。

  首先main中调用test, 进入test后要求读入一个char, 你输入1后执行case 1中语句,所以输出“已调用”,然后就执行test()语句,即递归调用,此时main调用的test要等新的test执行完毕才能继续执行后继的i++语句;

  再次进入test之后与从main中进入时一样,如果输入的是1会接着递归调用test,由于你输入了5次1,所以会继续调用5次test;

  倒数第二次的test继续执行i++, 所以i=2了,case 1执行完毕,但由于没有写break语句,所以继续执行default 语句,输出222222, 退出switch语句,判断c==27, 由于c是全局变量,且最后一次输入的刚好是ESC, 所以判断满足, 退出while循环,输出i=1, 到此倒数第二次test执行完毕;

  与倒数第二次类似的继续执行倒数第三、倒数第四、倒数第五和最终的第一次test后继代码,也就输出如你列出的结果了。更多追问追答追问也就是说,函数是在CPU中进行运算的,递归调用的话不会在内存用开辟新的空间,而是在CPU中开辟新空间?追答CPU是纯计算用的,里边只有寄存器和很少量的缓存,不管是不是递归调用都不会在CPU中开辟空间。 递归调用主要消耗内存的栈空间, 可以认为调用一次函数就要增加一次栈空间, 不递归调用的话只增加一次栈空间。追问递归调用时在内存中开辟新空间,然后在CPU中运算?

  但楼上说的是这的 系统栈是固定的,递归调用次数过多会造成栈溢出,并不是开辟空间,系统栈根据电脑不同大小也不同。

  系统栈是固定的?而且递归调用次数过多还会造成栈溢出?并不是开辟新空间?堆会溢出吗?

  这是对的吗?追答系统会对每个程序分配栈空间,大小是是固定, 每次调用函数时会将当前函数的上下文入栈, 直到被调用函数执行完毕在将当前函数的上下文出栈。 所以如果递归调用的深度很深会导致大量的上下文入栈, 最终导致爆栈, 即栈溢出。

  可以认为栈是系统给程序的一个数组,开始里边啥都没有,调用函数后就加一条数据,如果越加越多最终会溢出, 之前所说的增加一次栈空间更确切的说应该是增加一次栈数据, 总的栈空间不会增加。追问那这样的话堆和栈的意思不就一样了吗?

  问了这么多,悬赏我是一定会加高的。追答堆是用户手动分配释放的,也就是用户控制的,只要内存中还有空间就可以分配;

  栈是系统控制的,用户无法手动分配释放,程序(进程)的栈空间是在编译链接就确定了的,程序执行过程中无法动态增大。

  一般无需考虑增加栈空间,大部分都是够用的,对递归算法来说也尽量不要过深,否则应该考虑用别的算法。追问最后一个问题。递归调用可以在堆中执行吗?

  堆和栈的区别是什么?难道堆只能存放数据而不能存放类似递归的数据吗?追答递归不能在堆中执行, 严格的说这个是由系统进行函数调用的过程决定的。

  堆和栈的区别挺多,最根本的是堆空间对用户(程序员)来说可控, 栈空间是不可控的,由系统专用, 详细区别参见:

  实际上堆和栈都是存放的数据,但堆是用户手动放数据的地方, 栈是系统自动放数据的地方, 而递归调用是系统相关的数据,所以不能放到堆中。

  C语言函数调用整个过程是当准备调用函数时,先将形参以从右往左进行压栈程序跳转到函数入口,将函数的局部变量压栈(如果函数内部再调用函数就是在重复这个过程),函数返回时出栈,递归是在最后一个点上面函数返回,前面分配的资源根本没有释放,递归只有在最后一个返回点上面,根据递归顺序反过来释放资源,这也是为什么当递归的数据量比较大或者递归的层次比较深的时候,很容易造成内存溢出的原因那函数递归调用是在内存中进行还是在CPU中进行运算的?我一直觉得是在内存中,可楼上说了之后我就不确定了。内存一般分两种堆,栈,堆(像malloc分配的就是堆)是低位地址向高位地址进发,栈是从高位地址向低位地址进发,递归的运算(绝大部分的程序运算,少数除外)是在CPU的寄存器中对数据进行操作的!

  递归的过程就是利用这点,把函数压入栈中,但是这个函数的结果需要执行另一个函数,再继续压入栈中,知道出现递归出口,就是最后一个函数有了结果

  开始回调,一个一个出栈,跟楼主的结论2差不多追问那递归调用的话一直在内存用开辟新空间,内存占用会不会很大。还有,要怎么样才能算出一个函数所占用的内存空间呢?

本文链接:http://windsorflowers.net/diguixiangliangzhiling/122.html
随机为您推荐歌词

联系我们 | 关于我们 | 网友投稿 | 版权声明 | 广告服务 | 站点统计 | 网站地图

版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright @ 2012-2013 织梦猫 版权所有  Powered by Dedecms 5.7
渝ICP备10013703号  

回顶部