魔术师般的 函数(3)(内含有函数栈帧)

(本文接续上文http://t.csdn.cn/btk8T

目录:非递归             递归和非递归的区别                   防止栈溢出的方法                    函数栈帧

(7)非递归   即为不是递归的,内常用迭代(也就是循环)

(8)递归和非递归的比较

递归 :优点:  可以把一个大问题分解成一个个的小问题,减化代码量,

            缺点:计算机无脑套入,导致运算量大,所以容易会栈溢出 (下面,在拓展上面有解释以前也解释过),也就是无法使用,计算。

非递归:优点:可以减轻计算机的计算量,不容易栈溢出。

          缺点:对于问题理解不到位会写出一堆代码(很冗余)而且·这一部分需要程序员自己计算化简之后,再写入程序内。题目越难,越难写出来,越长。

        总结:      1. 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。

                     2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。

                        3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开 销。

例如:用函数写求第n个斐波那契数

利用递归写

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

用非递归写

int count = 0;
int fib(int n)
{
 if(n == 3)
 count++;
 if (n <= 2)         
 return 1;
    else
    return fib(n - 1) + fib(n - 2);
}

当利用较大的数计算时最后的结果,第一个就算不出来,第二个可以算出来。

(9)总结一下,防止栈溢出方法。

 1. 将递归改写成非递归。

2. 使用static对象替代 nonstatic 局部对象。在递归函数设计中,可以使用 static(变为静态变量放到静态区) 对象替代 nonstatic 局部对象(即栈对象),(但是此做法作用微乎其微)。

内存分为三个区:栈区 堆区 静态区    局部变量默认放到栈区,当栈区满了就会溢出。

拓展,函数栈帧的创建和销毁:(尽量理解,不需要必须理解)(以下以汇编代码,16进制表示)

(首先声明,函数栈帧问题的演示方法各编译器下可能不同,但是大同小异)(本文章用vs2013演示)

首先说一下寄存器分为五种:eax ebx ecx edx   ebp  esp。

而后两个则是维护函数栈帧的。

每一个函数调用都需要在栈区(在内存中)有一个空间,从其中的高地址到低地址

esp ebp两个寄存器会自动维护正在使用的函数调用。

以下用main函数讲解:

在一开始时就会确定两个位置为两个寄存器放的位置,而当读取到函数的内容时寄存器则会变化位置  call是调用

该图为上面的代码,然后该图右面为进行步骤

 

1到2为移动 

 

 

 

 

 

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值