|
使用 可以对全局变量进行修改,但目前比 更常用的机制是使用指针,Perl 中的指针是可以打印变量地址的,这种情况在脚本中似乎有点不可思议。
定义一个指针:
指针也是一个标量,它表示的是变量的地址,我们可以如下定义一个指针:
$p = \$name;
这样,就把标量 $name 的地址赋给了 $p ,$p 就是对标量 $name 的引用,而对一个标量的解引用的方式是 $$p :
[code=perl]$sca = 5;
$p = \$sca;
print "$p\n";
print "$$p\n";[/mw_shl_code]
运行输出:
$ ./pointer.pl
SCALAR(0x8c8f7e8)
5 上面,在打印时,$p 变量的格式为 SCALAR(0x8c8f7e8),前面的 SCALAR 即为标量之意。
由于指针本质上是标量型变量,而非 typeglob 别名,所以可以通过 my 将其声明为专用的词法变量。之所以这么说,是因为 typeglob 别名只能关联到特定的符号表上。实际上,可以将标量变量,数组变量,散列变量,函数的地址赋值给指针变量,如: |
[code=perl]$ ./pointer.pl | SCALAR(0x80767e8) | 5 | ------------- | 456 | 4 | ------------- | val80key100 | 100 | 80 | ------------- | hello perl world | [beyes@beyes pointer]$ cat pointer.pl | #!/usr/bin/perl | | | $sca = 5; | $p = \$sca; | print "$p
"; | print "$p
"; | print "-------------
"; | | | @arr = (4,5,6); | $p = \@arr; | print @$p, "
"; | print $p[0], "
"; | print "-------------
"; | | | %hash = ("key" => 100, | "val" => 80 | ); | | | $p = \%hash; | print %$p, "
"; | print $p{key}, "
"; | print $p{val}, "
"; | | | print "-------------
"; | | | $p = \&hello; | &$p; | | | sub hello { | print "hello perl world
"; | }[/mw_shl_code] |
运行输出:
$ ./pointer.pl
SCALAR(0x80767e8)
5
-------------
456
4
-------------
val80key100
100
80
-------------
hello perl world 注意上面各种指针解引用时的形式。
我们可以使用 来在子函数中修改全局变量,现在有了指针,则又多了一个好用的办法。当一个子函数接收参数时,它会把参数保存到特殊的 @_ 数组中。比如,当把两个数组同时传递给一个子函数时,这两个数组都会被保存到 @_ 中,然后连接成单个列表。如果不知道其中前一个数组长度的话,那几本上没法拆开这两个数组。然而,如果传递给子函数是两个指针,且它们分别包含有这两个数组地址的话,这样就很方便实现数组内容的分离了,并且可以按照地址访问数组内容。同时,如果我们在子函数中利用指针修改相关的值,那么实际修改的就是传递进来的实际变量,而不是它的副本。考虑下面的代码:
[code=perl]
#!/usr/bin/perl
#两个全局的数组变量
my @list1 = (1..10);
my @list2 = (5, 11, 15, 20);
#将数组的指针传递到子函数中
print "The total is : ", &addemup(\@list1, \@list2), ".\n";
sub addemup {
my ($arr1, $arr2) = (shift, shift); #连续使用两次 shift,第 1 次传递 @list 的地址到 $arr1,第 2 次传递 @list2 的地址到 $arr2
#打印指针所指示的地址
print "address_arr1: $arr1\n";
print "address_arr2: $arr2\n";
my $total = 0;
my $i = 0;
foreach $num (@$arr1, @$arr2) { #将两个数组中的值全部相加
$total += $num;
}
foreach $num (@$arr1) { #改变第 1 个数组中的各个值,即每个值都加上 10
$arr1->[$i] = $num + 10;
$i++;
}
$total;
}
print "--------In main area-----------\n";
foreach (@list1) {
print "$_ ";
}
print "\n";[/mw_shl_code]
运行输出:$ ./p5.pl
address_arr1: ARRAY(0x83a17b8)
address_arr2: ARRAY(0x83a1958)
The total is : 106.
--------In main area-----------
11 12 13 14 15 16 17 18 19 20 |
|