读书人

c编译器是如何避免递归方法的

发布时间: 2012-03-09 21:42:54 作者: rapoo

c编译器是如何处理递归方法的
c编译器是如何处理递归方法的
basic编译器是如何处理递归方法的
它们在处理递归方法上有哪些不同呢

[解决办法]
BASIC不知道,C也无外乎函数调用,压栈,还能怎么处理?
[解决办法]
所谓的递归就是不断的调用自身
就是函数调用而已
[解决办法]
都是用堆栈保存状态。
[解决办法]
递归调用不需要编译器、解释器做特殊处理(除了有优化的),只是普通的函数调用,只不过调用的时函数自己而已

[解决办法]
前辈告诉我们:

利用编译器递归的模板算阶乘的代码如下,希望编译期就求值完毕,也就是说比如这么写 int res = factorial< 3 >::result; 就相当于写int res = 6;

template< unsigned int num >
struct factorial
{
enum
{
result = ( num == 0 )? 1 : num * factorial< num - 1 >::result
};
};

上面的代码看起来不错,但是无法通过编译(VC.NET 2003),会报一个C1202: 递归类型或函数依赖项上下文太复杂。

想要编过就得再带一个特化版的factorial:

template<>
struct factorial< 0 >
{
enum
{
result = 1
};
};
这样写的话原来的定义就可以简化为 result = num * factorial< num - 1 >::result了

仔细看原来的代码,递归明明是可以中止的啊?但是仔细一想,不能要求编译器那么聪明,它不可能编译到
num == 0的时候一看哈哈发现能中止(如果不能中止就停不下来了),应该是直接一看是递归,然后再一看没有特化版,就直接报错了(我猜的)。

试了一下,具现 factorial< num >的地方不管num给多大,编译器都是立即报出错误,可见一定是在真正开始递归之前就已经下结论了

这样的缺点是只要用到模板递归,就一定要带一个特化版,心里总有些不爽。当然有些人会觉得这样看起来比较清楚,各有所好吧


[解决办法]
普通的调用,返回,不过在返回的时候多做了一些处理。即判断,然后才跳转。
每调用一次函数都会判断是否满足条件,不满足,则将本次处理结果和函数返回地址压入堆栈(可能多次压入),满足条件,则将堆栈中的数据弹出,跳转到函数返回地址处做处理,处理完毕,函数返回。当然,压入多少次就要弹出多少次了,保持堆栈平衡嘛。也就是调用了多少次函数,就要返回多少次了。
以上是从汇编语言角度考虑的,简单总结就是:
不满足递归条件,则不停压栈,满足条件,则层层返回。

[解决办法]
主要是利用栈来实现的
压栈出栈的过程

你可以参考徐波编译的c与指针
上面有关于递归的具体实现的例子
[解决办法]
后进先出,basic也应该这样吧。
[解决办法]
楼主你怎么想知道那些呢?

如果牵涉到最下面就是汇编了。

读书人网 >C语言

热点推荐