网站搜索排名优化软件,flash xml网站,怎么建立一个网站存照片视频的链接,东莞常平镇地图一、栈在说函数递归的时候#xff0c;顺便说一下栈的概念。栈是一个后进先出的压入(push)和弹出(pop)式数据结构。在程序运行时#xff0c;系统每次向栈中压入一个对象#xff0c;然后栈指针向下移动一个位置。当系统从栈中弹出一个对象时#xff0c;最近进栈的对象将被弹出…一、栈在说函数递归的时候顺便说一下栈的概念。栈是一个后进先出的压入(push)和弹出(pop)式数据结构。在程序运行时系统每次向栈中压入一个对象然后栈指针向下移动一个位置。当系统从栈中弹出一个对象时最近进栈的对象将被弹出。然后栈指针向上移动一个位置。程序员经常利用栈这种数据结构来处理那些最适合用后进先出逻辑来描述的编程问题。这里讨论的程序中的栈在每个程序中都是存在的它不需要程序员编写代码去维护而是由运行是系统自动处理。所谓的系统自动维护实际上就是编译器所产生的程序代码。尽管在源代码中看不到它们但程序员应该对此有所了解。再来看看程序中的栈是如何工作的。当一个函数(调用者)调用另一个函数(被调用者)时运行时系统将把调用者的所有实参和返回地址压入到栈中栈指针将移到合适的位置来容纳这些数据。最后进栈的是调用者的返回地址。当被调用者开始执行时系统把被调用者的自变量压入到栈中并把栈指针再向下移以保证有足够的空间存储被调用者声明的所有自变量。当调用者把实参压入栈后被调用者就在栈中以自变量的形式建立了形参。被调用者内部的其他自变量也是存放在栈中的。由于这些进栈操作栈指针已经移动所有这些局部变量之下。但是被调用者记录了它刚开始执行时的初始栈指针以他为参考用正或负的偏移值来访问栈中的变量。当被调用者准备返回时系统弹出栈中所有的自变量这时栈指针移动了被调用者刚开始执行时的位置。接着被调用者返回系统从栈中弹出返回地址调用者就可以继续执行了。当调用者继续执行时系统还将从栈中弹出调用者的实参于是栈指针回到了调用发生前的位置。可能刚开始学的人看不太懂上面的讲解栈涉及到指针问题具体可以看看一些数据结构的书。要想学好编程语言数据结构是一定要学的。二、递归递归是函数实现的一个很重要的环节很多程序中都或多或少的使用了递归函数。递归的意思就是函数自己调用自己本身或者在自己函数调用的下级函数中调用自己。递归之所以能实现是因为函数的每个执行过程都在栈中有自己的形参和局部变量的拷贝这些拷贝和函数的其他执行过程毫不相干。这种机制是当代大多数程序设计语言实现子程序结构的基础是使得递归成为可能。假定某个调用函数调用了一个被调用函数再假定被调用函数又反过来调用了调用函数。这第二个调用就被称为调用函数的递归因为它发生在调用函数的当前执行过程运行完毕之前。而且因为这个原先的调用函数、现在的被调用函数在栈中较低的位置有它独立的一组参数和自变量原先的参数和变量将不受影响所以递归能正常工作。程序遍历执行这些函数的过程就被称为递归下降。程序员需保证递归函数不会随意改变静态变量和全局变量的值以避免在递归下降过程中的上层函数出错。程序员还必须确保有一个终止条件来结束递归下降过程并且返回到顶层。例如这样的程序就是递归void a(int);main(){int num5;a(num);}void a(int num){if(num0) return;printf(%dnum);a(--num);}在函数a()里面又调用了自己也就是自己调用本身这样就是递归。那么有些人可能要想这不是死循环吗所以在递归函数中一定要有return语句没有return语句的递归函数是死循环。我们分析上面的例子先调用a(5)然后输出5再在函数中调用本身a(4)接着回到函数起点输出4……一直到调用a(0)这时发现已经满足if条件不在调用而是返回了所以这个递归一共进行了5次。如果没有这个return肯定是死循环的。虽然递归不难理解但是很多在在使用递归函数的时候问题多多。这里面一般有两个原因一是如何往下递归也就是不知道怎么取一个变量递归下去二是不知道怎么终止递归经常弄个死循环出来。下面看几个例子1.求12……100的和先分析一下。第一递归变量的问题从题目上看应该取12……100这些变量的值作为递归的条件第二就是如何终止的问题从题目上看应该是当数为100的时候就不能往下加了。那么我们试着写一下程序。int add(int);main(){int num1sn;snadd(num);printf(%d\nsn);getch();}int add(int num){static int sn;snnum;if(num100) return sn;add(num);}分析一下程序前调用add(1)然后在子函数中把这个1加到sn上面。接着调用add(2)再把sn加2上来。这样一直到100到了100的时候先加上来然后发现满足了if条件这时返回sn的值也就是12……100的值了。这里有一个问题一定要注意就是static intsn;有些人就不明白为什么要使用static类型修饰符为什么不使用int sn0;如果使用intsn0;这样的语句在每次调用函数add()的时候sn的值都是赋值为0也就是第一步虽然加了1上来可是第二次调用的时候sn又回到了0。我们前面说了static能保证本次初始化的值是上次执行后的值这样也就保证了前面想加的结果不会丢失。如果你修改为intsn0最后结果一定是最后的100这个值而不是5050。2.求数列s(n)s(n-1)s(n-2)的第n项。其中s(1)s(2)1。可以看出终止条件一定是s(1)s(2)1。递归下降的参数一定是n。int a(int);main(){int ns;scanf(%dn);sa(n);printf(%d\ns);getch();}int a(int n){if(n《3) return 1;return a(n-1)a(n-2);}这个题目主要说明的是在函数中不一定只有一个return语句可以有很多但是每次对归的时候只有一个起作用。题目不难理解这儿不分析了。说了这些递归其实它和函数的调用没有大的区别主要就是一个终止条件要选好。递归函数很多时候都能用循环来处理。main(){int n20array20;int i;for(i0;i {if(i《2) arrayi1;elsearrayiarrayi-1arrayi-2;}printf(%d\narray19);getch();上面的程序就是实现一模一样的功能的。但是它有一个缺陷就是n的值不是通过键盘输入来得到。如果想通过键盘来得到n可以这样main(){int ni;int s11s21tempscanf(%dn);for(i3;i《n;i){temps2;s2s1;s1temp;}printf(%d\ns2);getch();}但是在某些场合使用递归比使用循环要简单的多。而且有些题目一看就知道应该使用递归而不是循环来处理。