📄 perl 语言-perl 中文教程(第十二章).htm
字号:
= ['solid' , 'black' , ['1','2','3'] ,
['4','5','6']];<BR> 此语句建立了一个含四个元素的三维数组,变量$line指向该数组。前两个元素是标量,存贮线条的类型和颜色,后两个元素是匿名数组的引用,存贮线条的起点和终点。访问其元素语法如下:<BR></P>
<BLOCKQUOTE>
<P>$arrayReference->[$index] single-dimensional array
<BR>$arrayReference->[$index1][$index2] two-dimensional array
<BR>$arrayReference->[$index1][$index2][$index3] three-dimensional
array </P></BLOCKQUOTE>
<P> 可以创建在你的智力、设计经验和计算机的内存允许的情况下极尽复杂的结构,但最好对可能读到或管理你的代码的人友好一些--尽量使代码简单些。另一方面,如果你想向别人炫耀你的编程能力,Perl给你足够的机会和能力编写连自己都难免糊涂的代码。:)<BR> 建议:当你想使用多于三维的数组时,最好考虑使用其它数据结构来简化代码。<BR> 下面为创建和使用二维数组的例子:<BR></P>
<BLOCKQUOTE>
<P>1 #!/usr/bin/perl<BR>2 #<BR>3 # Using
Multi-dimensional Array references<BR>4 #<BR>5 $line =
['solid', 'black', ['1','2','3'] , ['4', '5', '6']];<BR>6 print
"\$line->[0] = $line->[0] \n";<BR>7 print "\$line->[1] =
$line->[1] \n";<BR>8 print "\$line->[2][0] =
$line->[2][0] \n";<BR>9 print "\$line->[2][1] =
$line->[2][1] \n";<BR>10 print "\$line->[2][2] = $line->[2][2]
\n";<BR>11 print "\$line->[3][0] = $line->[3][0] \n";<BR>12 print
"\$line->[3][1] = $line->[3][1] \n";<BR>13 print
"\$line->[3][2] = $line->[3][2] \n";<BR>14 print "\n"; # The
obligatory output beautifier. </P></BLOCKQUOTE>
<P> 结果输出如下:<BR></P>
<BLOCKQUOTE>
<P>$line->[0] = solid<BR>$line->[1] = black<BR>$line->[2][0] =
1<BR>$line->[2][1] = 2<BR>$line->[2][2] = 3<BR>$line->[3][0] =
4<BR>$line->[3][1] = 5<BR>$line->[3][2] = 6 </P></BLOCKQUOTE>
<P> 那么三维数组又如何呢?下面是上例略为改动的版本。<BR></P>
<BLOCKQUOTE>
<P>1 #!/usr/bin/perl<BR>2 #<BR>3 # Using
Multi-dimensional Array references again<BR>4 #<BR>5 $line =
['solid', 'black', ['1','2','3', ['4', '5', '6']]];<BR>6 print
"\$line->[0] = $line->[0] \n";<BR>7 print "\$line->[1] =
$line->[1] \n";<BR>8 print "\$line->[2][0] =
$line->[2][0] \n";<BR>9 print "\$line->[2][1] =
$line->[2][1] \n";<BR>10 print "\$line->[2][2] = $line->[2][2]
\n";<BR>11 print "\$line->[2][3][0] = $line->[2][3][0] \n";<BR>12
print "\$line->[2][3][1] = $line->[2][3][1] \n";<BR>13 print
"\$line->[2][3][2] = $line->[2][3][2] \n";<BR>14 print "\n";
</P></BLOCKQUOTE>
<P> 结果输出如下:<BR></P>
<BLOCKQUOTE>
<P>$line->[0] = solid <BR>$line->[1] = black <BR>$line->[2][0]
= 1 <BR>$line->[2][1] = 2 <BR>$line->[2][2] = 3
<BR>$line->[2][3][0] = 4 <BR>$line->[2][3][1] = 5
<BR>$line->[2][3][2] = 6 </P></BLOCKQUOTE>
<P> 访问第三层元素的方式形如$line->[2][3][0],类似于C语言中的Array_pointer[2][3][0]。本例中,下标均为数字,当然亦可用变量代替。用这种方法可以把数组和哈希表结合起来构成复杂的结构,如下:<BR></P>
<BLOCKQUOTE>
<P>1 #!/usr/bin/perl<BR>2 #<BR>3 # Using Multi-dimensional Array and
Hash references<BR>4 #<BR>5 %cube = (<BR>6 '0', ['0', '0', '0'],<BR>7
'1', ['0', '0', '1'],<BR>8 '2', ['0', '1', '0'],<BR>9 '3', ['0', '1',
'1'],<BR>10 '4', ['1', '0', '0'],<BR>11 '5', ['1', '0', '1'],<BR>12 '6',
['1', '1', '0'],<BR>13 '7', ['1', '1', '1']<BR>14 );<BR>15 $pointer =
\%cube;<BR>16 print "\n Da Cube \n";<BR>17 foreach $i (sort keys
%$pointer) {<BR>18 $list = $$pointer{$i};<BR>19 $x =
$list->[0];<BR>20 $y = $list->[1];<BR>21 $z = $list->[2];<BR>22
printf " Point $i = $x,$y,$z \n";<BR>23 } </P></BLOCKQUOTE>
<P> 结果输出如下:<BR></P>
<BLOCKQUOTE>
<P>Da Cube <BR>Point 0 = 0,0,0 <BR>Point 1 = 0,0,1 <BR>Point 2 = 0,1,0
<BR>Point 3 = 0,1,1 <BR>Point 4 = 1,0,0 <BR>Point 5 = 1,0,1 <BR>Point 6
= 1,1,0 <BR>Point 7 = 1,1,1 </P></BLOCKQUOTE>
<P> 这是一个定义立方体的例子。%cube中保存的是点号和坐标,坐标是个含三个数字的数组。变量$list获取坐标数组的引用:$list
= $$ pointer{$i}; 然后访问各坐标值:$x = $list->[0]; ...
也可用如下方法给$x、$y和$z赋值:($x,$y,$z) =
@$list;<BR> 使用哈希表和数组时,用$和用->是类似的,对数组而言下面两个语句等效:<BR> $$names[0]
= "kamran";<BR> $names->[0] =
"kamran";<BR> 对哈希表而言下面两个语句等效:<BR> $$lastnames{"kamran"}
= "Husain";<BR> $lastnames->{"kamran"} =
"Husain";<BR> Perl中的数组可以在运行中创建和扩展。当数组的引用第一次在等式左边出现时,该数组自动被创建,简单变量和多维数组也是一样。如下句,如果数组contours不存在,则被创建:<BR> $contours[$x][$y][$z]
= &xlate($mouseX, $mouseY);<BR><BR><A
name=6>六、子程序的引用</A><BR> perl中子程序的引用与C中函数的指针类似,构造方法如下:<BR> $pointer_to_sub
= sub {... declaration of sub
...};<BR> 通过所构造的引用调用子程序的方法为:<BR> &$pointer_to_sub(parameters);<BR><BR><A
name=6.1>子程序模板</A><BR> 子程序的返回值不仅限于数据,还可以返回子程序的引用。返回的子程序在调用处执行,但却是在最初被创建的调用处被设置,这是由Perl对Closure处理的方式决定的。Closure意即如果你定义了一个函数,它就以最初定义的内容运行。(Closure详见OOP的参考书)下面的例子中,设置了多个错误信息显示子程序,这样的子程序定义方法可用于创建模板。<BR></P>
<BLOCKQUOTE>
<P>#!/usr/bin/perl<BR>sub errorMsg {<BR> my $lvl =
shift;<BR> #<BR> # define the subroutine to run when
called.<BR> #<BR> return sub {<BR> my $msg =
shift; # Define the error type now.<BR> print "Err Level
$lvl:$msg\n"; }; # print later. <BR> }<BR>$severe =
errorMsg("Severe");<BR>$fatal = errorMsg("Fatal");<BR>$annoy =
errorMsg("Annoying");<BR><BR>&$severe("Divide by
zero");<BR>&$fatal("Did you forget to use a
semi-colon?");<BR>&$annoy("Uninitialized variable in use");
</P></BLOCKQUOTE>
<P> 结果输出如下:<BR></P>
<BLOCKQUOTE>
<P>Err Level Severe:Divide by zero<BR>Err Level Fatal:Did you forget to
use a semi-colon?<BR>Err Level Annoying:Uninitialized variable in use
</P></BLOCKQUOTE>
<P> 上例中,子程序errorMsg使用了局域变量$lvl,用于返回给调用者。当errorMsg被调用时,$lvl的值设置到返回的子程序内容中,虽然是用的my函数。三次调用设置了三个不同的$lvl变量值。当errorMsg返回时,$lvl的值保存到每次被声明时所产生的子程序代码中。最后三句对产生的子程序引用进行调用时$msg的值被替换,但$lvl的值仍是相应子程序代码创建时的值。<BR> 很混淆是吗?是的,所以这样的代码在Perl程序中很少见。<BR><BR><A
name=7>七、数组与子程序</A><BR> 数组利于管理相关数据,本节讨论如何向子程序传递多个数组。前面我们讲过用@_传递子程序的参数,但是@_是一个单维数组,不管你传递的参数是多少个数组,都按序存贮在@_中,故用形如my(@a,@b)=@_;
的语句来获取参数值时,全部值都赋给了@a,而@b为空。那么怎么把一个以上的数组传递给子程序呢?方法是用引用。见下例:<BR></P>
<BLOCKQUOTE>
<P>#!/usr/bin/perl<BR>@names = (mickey, goofy, daffy );<BR>@phones =
(5551234, 5554321, 666 );<BR>$i = 0;<BR>sub listem {<BR> my
($a,$b) = @_;<BR> foreach (@$a) {<BR> print "a[$i] =
" . @$a[$i] . " " . "\tb[$i] = " . @$b[$i] ."\n";<BR>
$i++;<BR> }<BR>}<BR>&listem(\@names, \@phones);
</P></BLOCKQUOTE>
<P> 结果输出如下:<BR></P>
<BLOCKQUOTE><PRE>a[0] = mickey b[0] = 5551234
a[1] = goofy b[1] = 5554321
a[2] = daffy b[2] = 666
</PRE></BLOCKQUOTE>
<P>注意: </P>
<BLOCKQUOTE>
<P>1、当想传递给子程序的参数是多于一个的数组时一定要使用引用。<BR>2、一定不要在子程序中使用形如 (@variable)=@_;
的语句处理参数,除非你想把所有参数集中到一个长的数组中。 </P></BLOCKQUOTE>
<P><A name=8></A><FONT
color=#003300>八、文件句柄的引用</FONT><BR> 有时,必须将同一信息输出到不同的文件,例如,某程序可能在一个实例中输出到屏幕,另一个输出到打印机,再一个输出到记录文件,甚至同时输出到这三个文件。相比较于每种处理写一个单独的语句,可以有更好的实现方式如下:<BR> spitOut(\*STDIN);<BR> spitOut(\*LPHANDLE);<BR> spitOut(\*LOGHANDLE);<BR> 其中子程序spitOut的代码如下:<BR></P>
<BLOCKQUOTE>
<P>sub spitOut {<BR> my $fh = shift;<BR> print $fh "Gee
Wilbur, I like this lettuce\n";<BR>} </P></BLOCKQUOTE>
<P> 注意其中文件句柄引用的语法为\*FILEHANDLE。</P></DIV></DIV></TD></TR></TBODY></TABLE>
<DIV align=center></DIV>
<DIV align=center><BR></DIV>
<DIV align=center><SPAN class=myFont><A
href="http://www.sun126.com/perl5/perl5-11.htm">上页</A> <A
href="http://www.sun126.com/perl5/perl5-13.htm">下页</A> <A
href="http://www.sun126.com/perl5/perl5index.htm">回目录</A> <A
href="http://www.sun126.com/perl5/perl5-12.htm#a"><FONT face="Arial, 宋体">Go
Top</FONT></A></SPAN><BR><BR></DIV>
<TABLE height=50 cellSpacing=0 cellPadding=0 width="100%" bgColor=#000000
border=0>
<TBODY>
<TR>
<TD bgColor=#cccc99 height=4>
<DIV align=center><IMG height=4 src="" width=4></DIV></TD></TR>
<TR>
<TD height=50>
<DIV align=center><FONT class=myfont size=2><SPAN class=myfont><FONT
color=#99cc99><A href="http://www.sun126.com/bbs/ccb/index.cgi"><FONT
color=#99cc99>中国CCB论坛</FONT></A> 整理 麻辣
2003.7.10</FONT></SPAN></FONT><FONT class=myfont color=#99cc99
size=2><SPAN class=myfont><FONT
color=#99cc66><BR></FONT></SPAN></FONT><SPAN class=myfont><FONT
class=myfont><SPAN class=myfont><FONT face="Arial, Helvetica, sans-serif"
color=#99cc99>© 2000
http://www.sun126.com</FONT></SPAN></FONT></SPAN></DIV></TD></TR></TBODY></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -