曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4154|回复: 0
打印 上一主题 下一主题

硬引用(hadr referencee) --- 使用指针

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
跳转到指定楼层
楼主
发表于 2011-10-16 18:07:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用
符号引用
可以对全局变量进行修改,但目前比
符号引用
更常用的机制是使用指针,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
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-19 06:45 , Processed in 0.084630 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表