递归函数应少用
例子:
<?php function reverse_r($str) { if(strlen($str)>0) { reverse_r(substr($str,1)); } echo substr($str,0,1); return; } function reverse_i($str) { for($i=1;$i<=strlen($str);$i++) { echo substr($str,-$i,1); } return; } reverse_r('hello'); echo "<br>"; reverse_i('hello'); ?>
输出为:
olleh olleh
在这个程序清单中实现了两个函数,这两个函数都可以以相反的顺序打印字符串的内容,函数reverse_r()是通过递归实现的,而函数reverse_i()是通过循环实现的。
函数reverse_r()以一个字符串作为输入参数,当调用他/她的时候,它会继续调用它自己,每次传递从字符串的第二个到最后一个字符,例如,如果调用:
reverse_r('hello');
他会用下面的参数多次调用自己:
reverse_r('ello'); reverse_r('llo'); reverse_r('lo'); reverse_r('o'); reverse_r('');
每次调用这个函数都在服务器的内存中生成一段该函数代码的新副本,但每次使用的参数是不同的,这有点像我们每次调用不同的函数,这样会使我们避免将这些函数的调用实例混淆。
在每次调用中,传入字符串的长度都会被测试,当到达字符串末尾的时候(strlen()==0),条件失败,最近的一次函数调用(reverse_r(''))会被继续执行下一行代码,就是将传入字符串的第一个字符显示出来--在这个情况下没有字符,因为字符串是空的。
下一步,这个函数实例又将控制返回到调用它的实例中,也就是reverse_r('o'),这样就打印出了字符串的第一个字符("o")然后将控制返回到调用它的实例中。
如此继续打印一个字符后返回到调用它的上一层函数实例中,知道程序控制返回主程序。
虽然递归看上去美观,但程序员常会忘记给出递归的终止条件,这意味者函数会一直冲服下去知道服务器内存耗尽,或者达到最大调用次数。