当前位置:首页 > PHP学习宝典-第八章(一)

PHP学习宝典-第八章(一)

点击次数:1342  更新日期:2011-01-03
\n

PHP学习宝典-第八章

函式的定义及应用

本章重点

2 使用内建的PHP函式

2 浏览线上函式手册

2 使用者定义函式

2 进价技巧:可变参数、参引呼叫和可变函式


任何程序语言都有某种程序抽象处理能力(procedural abstraction,就是帮程序码某段区块命名,以便在编写其它程序码区段时能够取用)。某些script语言缺乏这种能力,而根据我们的经验,这会使复杂的伺服端程序码很快变得无法管理。


PHP用来提供这种抽象处理的机制就是函式(function)。PHP中实际上有两种类型的函式,一种是已经由PHP开发者内建在语言中,另一种是由每个PHP程序设计师自己定义的。


本章中,我们来看看如何使用PHP已提供的大量函式,然后再学会如何定义属于自己的函式。很幸运地,使用内建函式和自己定义的函式并没有什么区别。


使用函式

使用(或呼叫)函式的基本语法如下:


function_name(expression_1, expression_2,…,expression_n)

它是函式名称后带有括号并以逗号分隔输入运算式,(称为函式参数)列表的型式出现。根据具体定义,呼叫函式可以不带参数,也可以同时带入多个参数。


当PHP遇到有函式呼叫,它首先对每个参数运算式评算求值,然后使用这些值做为该函式的输入。函式执行后,回传值(如果有回传值)就是整个函式运算式的结果。


下面所列出的例子都是PHP内建函式的有效呼叫方式:


sqtr(9) //平方根函式,结果是「3」

rand(10,10+10) //回传介于「10」和「20」之间的数值

strlen(“This has 22 characters”) //回传数值「22」

pi() //回传p的近似值


这些函式分别用1,2,1和0个参数进行呼叫。

回传值与附带作用

每个函式呼叫都算是一个PHP运算式(与其它运算式一样),在程序码中包含函式只有两个原因:为了取得回传值,或者为了得到附带作用。

函式的回传值是函式运算的值。使用这个值,可以像使用其它任何运算式的求值结果一样,例如,可以把它指定到某个变数,如下所示:

my_pi = pi();

或者,可以把它嵌入复杂的运算式中,如下所示:


approx = sprt(approx)* sqrt(approx)


函式还可以用来实现各种不同的附带作用,其中包括将资料写入档案、资料库操作以及把内容输出示显示在浏览器视窗上。同时使用回传与附带作用出是可行的,例如,我们常常使用一个附带作用的函数并同时回传值来检查这个函数是否执行正常



函式的结果可以是任何型别,通常都把array型别用来当成传回多个值的函式。


函式手册


PHP的架构设计得很聪明,让它很容易由其它开发人员进行扩展延伸。其本的PHP语言本身很容易懂,出很有弹性,大多数PHP功能都存在大量的内建函式中。这是指开发人员可以自由添加新的内建函式,并且能够为PHP有所贡献,这种方式非常好,因为它不会改变PHP使用者可能依赖的任何部份。


虽然本书涵盍了许多内建函式,对其中某些函式的讲解比线上手册的讲解更详细,但http://www.php.net所提供的手册还是函式资讯的重要参考资源。在本书中,我们会在某种程度上摘选我们想要的主题来延伸介绍,而PHP手册的内容仍旧是PHP在每个方面上最完整的参考。虽然我们希望跟随PHP的未来版本即时更新本书,但线上说明还是会关于PHP新功能的最新功能的最新资讯,包括那些还处于正在开发状态的功能。所以有空看看PHP官方网站和线上提供的不同资源可是非常有帮助的。


虽然下面的资讯在本书结稿时是正确的(第二版再版的时间是2002年)。但可能有些细节部份已过时,或者由于线上手册有了更新版本或重新组织而不再适用。


想要查寻线上手册,可进入http://www.php.net网站,并选中右上方导航列中的「documentaion」选项标签,这样会转到一个含有各种格式且包含民其使用手册资讯的链接。我们想要看的是线是可注解的使用手册(目前连接位置在Documentation网页的View Online选项上),该手册允许使用者把自己的注解资料张贴到每一页中。[请注意:手册注解系统不是张贴问题的地方!如果有使用上的疑问,可参看邮寄清单(mailing list)部份,它位于www.php.net的「support」选项标签中,或者参阅本书有关PHP资源的附录D。手册注解系统是在使用者自己理解后要用自己的话进行解释和提出意见的地方,不过确是我们能做出贡献的途径,这也是有可能就会变成未来的正式版本,这的确是我们能做出贡献的好途径,这也是指出易混淆与可能有问题的好地方,不过这里都以「英文」来沟通哦!]

使用手册中的绝大部份是函式的考次料,其中每个内建函式都有单独一份说明页面。每页从函式名称和单行的说明开始,然后是属于C语言风格的函式标头宣告(下一节会讲解到),后面是个稍长的说明,可能还有一两个例子,然后(在注解手册中)是来自使用者的注解和意见报告。


在手册中的标头

对于那些不熟悉C语言函式标头的人,函式手册的最开头部份可能会看不懂。基格式是:

return-type function-name(typle argl,type2 arg2,…);

它指示了期望的函式回传值型值,函式名称和期望的参数型别等。

下面是个基本标头描述:

string substr (string string,int startl [,int length]);

这就表示函式substr会传回一个字符串,并期望取得一个字符串和两个整数为参数。实际上,length两边的方括号表示了这个参数是选择性的,因此呼叫substr时,可带一个string字符串和一个int整数,或是带一个string字符串和两个int整数。

与在C语言中的情况不同,这些手册标头中宣告的参数型别并非是绝对必要的。如果用一个数字当成一个参数来呼叫substr,也不会有错误出现,它是由PHP在开始执行该函式之前,把第一个参数转换成字符串。不过参数型别的确表现了函式创造者的初衷,另外最好是按照手册中注明的型别来使用函式,或者对型别转换的有关事项要有足够的了解,这样才能够保得到预期的结果。

一般来说,函式手册中用的型别名称是六种基本型别之一,或者是用它们的别名:integet(或int)、double(或float、real)、Boolean、string、array、object、resource和NULI。另外,可以看到void和mixed的类型。Viod型态的函式根本不传回任何值,而mixed参数型别意味着参数可以是任何型别。

查询函式手册

在手册中查询关于某函式的资讯的最佳途径是什么呢?这主要取决于你的好奇心和有兴趣的部份是那种?关于函式的最常见问题是:

我要用X函式,它又该如何使用呢?

我需要完成某项Y任务,有函式能帮我完成这一任务吗?

对于第一种情况,完整版本的线上手册提供民根据函式名称的自动查询。在右上方导航列下面,「search for」文字框预设搜寻的模式是函数的名称,并且会在找到该函数后显示此函数显示此函数的网页(你也可以选取取其它搜寻对象,包含整个网站的mailing list,这里是当你不知道所需函数名称时,但是可以猜出所需函数的概略字样时搜寻的好地方)。

以第二种情况来寻找的话,最好是使用函式参考文献(Funcrion Reference ,PHP手册中的其中一篇)的层次组织结构,该函式参考文献分成108章。例如,前面提到的substr函式在「Headers in Documentation」部分内的「String functions」部分。读者可以浏览函式参考文献的章节列表,以选择最适合你要完成的任务所属的那一章。或者,如果恰好知道一个函式的名字,该函式可能与完成的工作处于同一范围领域,此时就可以直接按下Quick Ref按钮连接到相关章节。

使用者定义的函式

使用者定义的函式在PHP中并非必要的。你也可以只用基本的语言结构和大量内建函式就能够构建出有用的Web网站了。不过如果发现自己的程序码内容变得越来越长了,而且愈来愈难了解和管理时,这表示要想一想应该把自己的某些程序码转成函式了。

什么是函式?

函式就中一种包裹某段程序码区块并给它取个名字的程序写法,这方便于以后只用一行程序码就能够使用该程序码区块。假如在写程序时,在多处都要使用到该程序码区块时,函式是最有效的方式,不过即使只使用一次,函式的建立与编写也会对程序结构有所帮助,因为可以使你的程序码更具可读性。

函式定义语法

函式可定义为以下形式:

function function-name(argument1, argument2,..)

{

statement1;

statement2;



}

函式定义有四个部份:

专用的「function」一词

帮函式取的名称

函式的参数列表(以逗号分隔的符号变数)

函式本体(大括号内的一系列叙述语句)

和变数名称一样,函式名称也必须由英文字母、数字和底线(_)组成,并且它不能以数字当开头。与变数名称不同的是,函式名称在储存前会被转换成小写,因此可将函式名称视为不区分大小写。

当呼叫使用定义的函式时发生的情况简述如下:

1. PHP会按照名字找寻该函式(如果函式还没有被定义过,则会显示错误讯息)。

2. PHP把参数(或称「实际参数」)的值替代函式定义中参数列表里的变数(或称「形式参数」)。

3. 执行函式本体的叙述语句。如果执行到叙述中「return」语句,则函式会停止执行并传回指定的值。否则,函式会一直执行到最后一道,并且不传回任何值。

请小心,有经验的程序设计师也许会注意到,前面的说明暗示了其为按值呼叫(call-by-value),而不是按参引呼叫(call-by-reference)。在本章最后一节会说明它们的差别,并示范如何进行按参引来呼叫。

函式定义的范例

举一个虚构的例子,请设想下面的这段程序码,目的是帮助我们决定购卖多少瓶装饮料(也许未来的什么时候,超商老品就已在使用可摧式的无线Web浏览器查看比较采买的价格了)。

liters_1 = 1.0;

price_1 = 1.59;

liters_2 = 1.5;

price_2 = 2.09;

per_liter_1 = price_1 / liters_1;

per_liter_2 = price_2 / liters_2;

if(per_literl<per_liter2)

print(“The first deal is better! < BR >”);

else

print(“The second deal is better!< BR >”);

因为这种类型的比较在我们的Web网页程序码中随处可见,我们很想把它做成可重复使用的函式。这样做的一种途径是按照范例来重写:

function better_deal (amount_1,price_1,

amount_2,price_2)

{

per_amount_1 = price_1/amount_1;

per_amount_2 = price_2/amount_2;

return(per_amount_1<per_amount_2);

}

liters_1 = 1.0;

price_1 = 1.59;

liters_2 = 1.5;

price_2 = 2.09;

if(better_deal(liters_1,price_1,

liters_2,price_2))

print(“The first deal is better!< BR >”);

else

price(“The second deal is better!< BR >”);

better_deal函式抽取了以前程序码中进行算术运算和比较的那三行程序码,它带有四个数字当作参数,并传回一个Boolean 运算式的值。和任何其它Boolean值一样,可以把它嵌入到if叙述的测试部份。虽然这个函式比原来的程序码还长,但这样重写后有两个优点:可以在程序其它多个位置使用这个函式(节省了整体程序行数),如果决定改变计算方式,只需要修改一个地方就好了。

还有一种替代方案,如果价格比较就是为了印出哪笔交易更划算,那可以直接把输出显示叙述句放到函式里,如下所示:

function print_better_deal(amount_1,price_1,

amount_2,price_2)

{

per_amount_1 = price_1 / amount_1;

per_amount_2 = price_2 / amount_2;

if(per_amout_1<per_amount_2)

print(“The first deal is better!< BR >”);

else

print(“The second deal is better!< BR >”);

}

liters_1 = 1.0;

price_1 = 1.59;

liters_2 = 1.5;

price_2 = 2,09;

print_better_deal(liters_1,price_1,

liters_2,price_2);

第一个函式使用return语句传送一个Boolean结果,然后该结果用于在一个if叙述的测试中。第二个函式没有return语句,因为它完成了其附带作用:在使用者浏览器是显示文字。当这个函式的最后一个叙述
语句执行完毕后,PHP接着执行函式呼叫后的下一条叙述语句。

形式参数与实际参数的对比

在前面的例子中,传递给函式的参数是「变数」,但并不是必须都如此处理。实际参数(即函式呼叫中的参数)可以是能够评算求值的任何运算式。在我们的例子中,可以给函式呼叫传入数字,而不用变数,如下所示:

Print_bettet_deal(1.0,1.59,1.5,2.09);

还要注意,在这个例子中有两处实际参数变数与形式参数同名的情况(如price_1还有实际参数与形式参数名称不同的(如liters_1与amount_1不同)。下一节介绍的内容中会提到两种方式都没有问题,函式的形式参数名称完全独立存在于函式外部,即使函数呼叫自己也是同样的。

参数数目不匹配

如果呼叫函式时带有的参数个数比定义中的参数个数少时,会怎样呢?或者,如果附带的参数比较多,又会怎样呢?正如读者所期待的,PHP可以容忍这些情况,而它会根据正常PHP4的错误回报设定,你会在浏览器看到所印出的警告讯息。

PHP4的预设错误回报设定会回报每一种除了执行期提醒之外类型的所有错误讯息,因为执行期提醒是所检查到较不重要的问题,而你所看到函数除入参数不足的警告被视为一种执行期的警告问题(较重要的错误种类),如果你真的需要有时使用函数定传入较少的参数时不想看到这种警告讯息时,你有两种选择来抑制这种警告:

你可以在程序中暂时更改错误回报,使用下列语法

errot_reporting(E_ALL – (E_NOTICE + E_WARNING));
这会将程序在出现下一个error_reporting()之间(如果有出现的话)关闭执行期提醒以及执行期警告(请注意这样做是危险的,因为其它你有兴趣的错误讯息可能也会被隐藏起来)。

你可以针对任何单一叙述使用错误控制符号@来抑制错误讯息的出现,你可以在任何叙述之前使用它来关闭针对这个叙述产生的错误讯息,例如,如果函数呼叫my_function()会产生一个警告,那么@ my_function()将不会产生,请注意这样做也是危险的,因为除了语法解析错误之外的所有类型错误都会被隐藏起来。

我们并不建议使用这些变相的选择,但是因为我们并无法保证永不出错所以偶尔会使用这些技巧,事实PHP提供一种方法来预测参数的撰写函数方式(请参阅本章稍后的「进阶函式技巧」内的「可变参数个数」),使用它们是比隐藏错误讯息呈现更好的主意。

不要将PHP的回报水准降低,我们比较赞同当你在开发新的程序码时将它调为最高水准,你可以在php.ini档案内设定这个选项(请参阅第37章)或是只要在程序的一开始加入error_reporting(E_ALL);语法,除此之外,调升回报水准意谓着当你忘记指事实上变数的内容时将会出现警告,这也是最易发生的费时错误。

太多参数个数

如果你传入太多的函数参数,那么额外的参数将单纯的被省略,即使错误回报被设定为E_ALL亦然,我们在「进阶函式技巧」部分将会介绍,这种弹性将会使我们能够将函数的参数部分传入变动的参数。

函式和变数作用域

正如我们在第五章中所提到的,函式外面关于变数作用域(作用范围)的规则很简单;在PHP程序码档案执行过程中的任何时候指定变数,该值将在档案的后续执行过程中一直存在。在函式定义本体中,这个规则得稍微有一点复杂要多留意。

管理函式本体中变数的基本原理是:「每个函式皆具有自己的独立世界」。也就是说,除非进行特殊宣告,否则函式内部的变数名称与其它地方使用到的名称就算相同也没有冲突。[这是属于PHP的特质,而不是错误。函式是要在不同本文内容中重复呼叫取用的,因此其行为应该独立于本文内容之外。如果不这样限定作用域(作用范围),会浪费很多时间来解决由于程序码中不同部份使用了同名变数而产生的问题。]

自从要存取的变数值只有形式参数变数(它们的值是从实际参数复制来的),还有那些在函式内定义的所有为数。这表示可以在函式内使用区域变数,你不必担心它们会对外面的世界有所影响。例如,请思考下面的函式以及随后的使用:

function SayMyABCs()
count = 0 ;

while (count< 10 >

{

print(chr(ord(ˋAˊ)+ count));

count = count + 1;

}

count = 0;

sayMyABCs();

count = count + 1;

ptint(“Now I′ve made count function call(s).< BR >”);

sayMyABCs()
count = count + 1;

ptint(“Now I′ve made count function call(s).< BR >”);

SayMyABCs()的用途是印出一个字母序列(函式chr()和ord()在字母和相对应的ASCII码之间进行转换,这里使用它们只不是为了产生字母序列而已),程序码的输出结果如下:

ABCDEFGHIJ

NOW I know 10 letters

NOW I′ve made 1 function call(s).

ABCDEFGHIJ

NOW I know 10 letters

NOW I′ve made 2 function call(s).

函式定义和函式外的程序码都用了名称为count的变数,但它们实际不指不同的变数,彼此不会产生问题。

在函式内部指定变数的预设行为是不与外界有所交互影响的,每次呼叫函式时就好像新建立了些变数一样。不过这些行为都可以用特殊的宣告方式来覆盖。

全域变数(global宣告)vs. 区域变数

在函式内定义变数的作用域,在预设情况下是局限于该函式之内,属于区域性的,意谓(我们在前面部分解释过)它信与函数外面的变数没有任何关系。透过使用global宣告,就可以让PHP知道,现在需要让这个变数名称和它在函式外的环境中拥有同样的含义的含义与作用。这种宣告的语法就是用global,后面带有以逗号分隔的变数列表,并用分号来结尾。为了看到效果,可考虑前一个例子的新版本写法。唯一的不同是把count 宣告为plobal型式,在函式内去掉了把它指定为「0」的语句:

Function SayMyABCs2()

{

Global count;

While(count< 10)

}

Print(chr(ord(ˋAˊ) + count));

count = count + 1;

}

Print(“< BR >Now I know count letters< BR >”);

}

count = 0;

SayMyABCs2()

count = count + 1;

Print(“Now I′ve made count function call(s).< BR >”);

SayMyABCs2();

count = count + 1;

Print(“Now I′ve made count function call(s).< BR >”);

这个修订后的版本在浏览器输出:

ABCDEFGHIJ

NOW I know 10 letters

NOW I′ve made 11 function call(s).

NOW I know 11 letters

NOW I′ve made 12 function call(s).

这种方式是有问题的,global宣告就是问题的来源。现在只有一个cuont变数,它在函式内和函式外都是递增值,当第二次呼叫SayMyABCs()时,cuont已经变成是「ll」了因此根本不会进入印出字母的回圈。

虽然这个例子显示了使用global所带来的问题,但只要使用得当,它还是可以非常有用的,尤其是因为PHP提供了一些变数可以其它程序码执行之前捆绑到每个页面上(在第九章将进行讲解)。它能够让函式看到这些变数,而省去了每次在呼叫中把它们作为参数再传入函式的麻烦。

静态变数(static宣告)

在预设情况下,函式对自己的执行并没有保留任何记忆,对于每个函式呼叫,区域变数都会认定成是新建的。Static宣告可以帮某些特定变数覆盖这一行为,使得正在多次叫同一个函式时能够保留变数的「值」。利用这一点,我们可以修改前面的函式,使它保留一些记忆:

Finction SayMyABCs3()

{

Static count = 0; //只在第一次呼叫时指派

limit = count + 10;

While(count<limit)

{

Print(chr(ord(ˋAˊ)+count));

count = count + 1;

}

Print(“< BR >Now I know count letters< BR >”);

}

count = 0;

SayMyABCs3()

count = count + 1;

Print(“Now I′ve made count function call(s).< BR >”);

SayMyABCs3()

count = count + 1;

Print(“Now I′ve made count function call(s).< BR >”);

这种记忆增强版本可以得到下面的输出:

ABCDEFGHIJ

NOW I know 10 letters

NOW I′ve made 1 function call(s).

KLMNOPQRST

NOW I know 20 letters

NOW I′ve made 2 function call(s).

Static关键字允许有初始的指定,这个指定只有在该函式还没有被呼叫过的时候才有效。第一次执行SayMyABCs时,count变数的区域内版本被设为「0」。第二次呼叫这个函式时,它的值就是上次执行结束时具有的值,因此能够继续前面的工作。请注意,在函式外对count所做的更改对区域内、的值没有作用。

函式作用域

关于变数名称作用域(作用范围)的规则相当简单,而函式名称的作用域规则就更简单了。在PHP中只有一条规则:函式必须在使有用它的中某处定义一次(并且只能定义一次,请参考下面的新功能部份就可以了解PHP4与PHP3中这一功能之间的差别)。函式名称的作用域暗指为全域的,因此在script中定义的函式可在script中其它任何地方便用。但为了清楚起见,最好是在使用函式程序码之前对所有的函式进行定义。

在PHP3 中,函式只能在定义后使用。这意味着嗫安全的方法是,在使用函式前,在一个给定的script中先定义所有函式(或将它们的定义含括入内)。PHP4在执行script前对其进行了预先编译,这样做的效果是能够在实际执行程序码之前就发现所有函式的定义。因此,函式和程序码能够以任何顺序出现在script中,只要所有函式被定义了一次(并且只有一次)就行。

档案的含括(include)的请求(require)

在一系列Web网站页面中使用同样的函式集是很常见的,通常的处理方式是用include或require,这两种方法都会把其它档案的内容导入正要执行的档案中。使用任何一种形式都比复制函式定义(即在需要使用它们的每页天头重复写一次)要好得多,因为将来有需要修改函式时,只需要修改一次。

例如,在PHP档案的最上方,可能有下面这样的程序码:

include “basic-functions.inc”

include “advanced-function.inc”;

(..code that uses basic and advanced functions..)

这些程序码含括了两个不同的函式定义档案(请注意,对于include()和require(),其后方括号都是可选择性的)。只要这些档案内容只有函式定义,在含括它们的次序上就无关紧要了。

Include和require都具有在被呼叫的该处接合入档案内容的效果。两者唯一不同的就是如果含括号档案找不到会产生何种错误,include()会显示一个警告讯息并仍会继续执行程序,但是require()会在找不到档案时产生严重的错误。

请注意现在include()与require()在网页载入时拥有静态的档案片段,但是include()会在网页执行时动态的载入程序,除此之外,这会使得程序根据include/require会产生不同的效果,然而现在include与require两者皆会动态载入,这意谓如果有一个include/requires格式在回圈中执行十次,那么将会含括十次。

只要含括一次

有时候你真的只要含括一个档案一次,但是不可以超过一次,这是在定义函数时常出现的问题,例如,有两个不同函数定义的档案可能同样含括一个相同内含括工具函数的档案,这会使得程序反应重复定制函数的错误讯息。

我们可以使用include_once()与requires_once来解决这种问题,它们不同的是将已经含括一次给定档案名称时不再第二次含括进档案内,通常含括函数或类别定义档案时使用_once版本的含括是较理想的。

include_once()与require_once()于PHP 4.0.1p12新增。

含括路径

当你含括一个档案名称,PHP会在你的include_path(在php.ini档案内设定)指定目录内搜此档案,预设的路径会含括目前网页所在最上层的相同目录,你可以参阅第37章更详细的如何在你的含括路径上加入位置。

Warning

请记住included(和required)档是以预设的HTML模式来解析,而不是以PHP模式。这意谓着任代号included档中要有PHP标签在开始和结尾的位置来包住让PHP直译的内容。

递回

某些类似C和C++的编译语言对如何定义函式给予了一些复杂的次序限制。为了知道如何编译一个函式,编译器必须了解该函式呼叫的所有函式,这意味着必须先定义被呼叫的函式。因此,如果两个函式互相呼叫,或者一个函式呼叫自己本身,那该怎么办呢?这样的情况会导致像C语言的设计者把函式宣告(或称原型)与函式定义(或称实作)分离开来。这种思考方式是,使用宣告把计划使用函式的参数类型和回传值型别提前告知编译器,编译器有了这些资讯就可以完全按照任何次序来处理实际的定义。

在PHP中就没有这外问题,因此不再需要单独分离的函式原型。在PHP3中,函需在使用前先定义,但定义某个函式呼叫另一个函式,并不算真正使用了这个函式。当PHP3遇到函式A定义,如果函式A本体内包含对函式B的呼叫,而函式B还未定义,PHP3并不会阻止这样做。函式B要在函式A真正执行前进行定义就可以了。不过这在PHP4中,顺序根本就不是问题。

这意味着递回函式(呼叫自己本身的函式)没什么使用上的问题。举例来说,我们可以定义一个递回函式,然后立即呼叫它:

function countdown (num_arg)

{

if(num_arg >0)

{

print(“Counting down from num_arg < BR >”);

countdown(num_arg – 1);

}

}

Countdown(10);

浏览器产生的输出为:

Counting down from 10

Counting down from 9

Counting down from 8

Counting down from 7

Counting down from 6

Counting down from 5

Counting down from 4

Counting down from 3

Counting down from 2

Counting down from 1

与所有递回函式相同,除了递回情形之外,确保函式有一个基本方案(非递回分支)是很重要的,基本方案最终还是要发生的。如果基本方案从未被启动,就像是个测试条件永远为真的while回圈,函式呼叫的回圈就会无限地进行下去。对于前面的这个函式,我们知道基本情形将会发生,因为每次启动递回都会把数字减小,最后就会到「0」。当然,这里先假设输入的是正整数,而不能是负数或浮点数。请注意,「大于0」的评算测试确保了即使不是正整数也不会发生无穷回圈,因为进行的不是「不等于0」的测试。

同样地,在相互呼叫的递回函式(函式互相呼叫彼此)也没有什限制。请看下面的定义以及呼叫的实例:

Function countdown_first(num_arg)

{

If(num_arg >0)

{

Print(“Counting dow(first)from num_arg< BR >”);

Countdown_second(num_arg – 1);

}

}

Function countdown_second(num_arg)

{

If(num_arg>0)

{

Print(“Counting dow(second)from num_arg< BR >”);

Countdown_first(num_arg – 1);

}

}

Countdown_first(5);

上面的程序码会产生这样的浏览器输出:

Counting down (first) from 5

Counting down (first) from 4

Counting down (first) from 3

Counting down (first) from 2

Counting down (first) from 1

(请接着看第二篇)


\n

出处:南方Linux

\n