Perl Learning 3 Subroutine

来源:互联网 发布:du(仅限数据连接) 编辑:程序博客网 时间:2024/06/03 20:16

【本文原创,转载请说明】

赶在期末了,后天就是第一门。。这两天学的是子函数的用法。

要定义你自己的子程序,可使用关键字sub、子程序名(不包含与号)以及用花括号封闭起来的代码块,这部分代码就是子程序的主体。

在任意表达式中使用子程序名(前面加上与号)来调用它:&hsl

任何Perl子程序都有返回值,那么规定每次必须写“return”某值就显得非常费事,我们可以将其简化。在子程序的执行过程中,它会不断进行运算,而最后一次运算结果(不管是什么)都会被自动当成子程序的返回值。子程序中的变量是全局变量。


Perl子程序可以有参数(argument),要传递参数列表到子程序里,只要在子程序调用的后面加上被括号圈引的列表表达式就行了。例如:


参数列表将会被传入子程序,让子程序随意使用。当然,得先将这个列表存在某处,Perl会自动将参数列表化名为特殊的数组变量@_,该变量在子程序执行期间有效。子程序可以访问这个数组,以判断参数的个数以及参数的值。这表示子程序的第一个参数存储于$_[0],第二个参数存储于$_[1]...


实际上,@_变量是子程序的私有变量。假如已经有了全局变量@_,则该变量在子程序调用前会先被存起来,并在子程序返回时恢复原本的值。

我们可以借助my操作符来创建私有变量,称之为词法变量(lexical variable)


这些变量属于封闭语句块的私有变量(或者也可以称作有限作用域(scoped)变量),语句块之外任何地方的$m$n都完全不受这两个私有变量的影响。

将上面两行合并:

在真实的Perl代码中,常常会把更长的列表作为参数传递给子程序。但我们需要写一些代码来检查列表参数的个数。

改进后的max函数:


以上这段代码使用了一般会称为“高水线(high-watermark)”的算法:大水过后,在最后一波浪消退时,高水线会标示出所见过的最高水位。

My操作符并不会更改变量赋值时的上下文:

在my操作符不加括号时,只能用来声明单词词法变量。在我们平常Perl编程当中,我们最好对每个变量都使用my声明,让它保持在自己所在的词法作用域内。

Use strict编译指令是要告诉Perl内部的编译器接下来的代码应该稍加严谨一点。

如果想在子程序执行到一半时停止执行,用return,它会立即停止执行并从子程序内返回某个值。而且不再执行子程序的其余部分。


会返回3,因为3dino的下标。

将子程序定义放在调用之前,可以不同添加&进行引用。但如果该子程序额Perl内置函数同名,我们就必须使用&去调用。

子程序不仅可以返回标量值,如果我们在列表上下文调用它,它还能返回列表值。

结果为11,10,9,8,7,6

在子程序中可以使用my操作符来创建私有变量,但每次调用这个子程序的时候,这个私有变量都会被重新定义。而使用state操作符来声明变量,我们便可以在子程序的多次调用期间保留变量之前的值,并将变量的作用域局限于子程序内部。

这段代码是正确的,但不幸的是我没有编译成功:


因为要用state,得加上use feature ‘state’,但是还是不过,因为linux服务器上的perl5.8.8的,而state5.10才出来的,所以我就没有更新了。

课后习题:


第一题:


第二题:

直接调用得到结果:

第三题:


第四题:

结果行不通。

我用我电脑中的虚拟机跑,在答案的帮助下,进一步的了解了state的用法。


答案给出的第一题:

简直太精简了,这个子程序使用$sum来存储到目前为止的总和。每次子程序开始执行时,$sum都会是新创建的变量,因此其值为undef。之后,foreach循环会以$_作为控制变量来逐项处理@_里的参数

第三题:



在average里面,如果参数列表是空的,子程序就会结束,返回undef,表示没有平均值。正因为此,在above_average中的循环控制变量为$element,而不是Perl最爱的默认变量$_

随着Perl编程的不断深入,我发现很多方法真的不是靠想就能想出来的,一定要多去编。





0 0
原创粉丝点击