子程序修改形参可以影响原变量?...

子程序修改形参可以影响原变量?...

sub test {
        $_[0]="b";
}
$s="a";
test($s);
print $s;

这个输出b,我本以为输出a的,我以为像c语言里那样,调用test函数是值传递而不是引用传递或者其他的,所以函数内部改变了是无效的,为什么输出b?~
习惯上这么写

[Copy to clipboard] [ - ]
CODE:
sub test {
        my $s = shift;  #或者   my $s = $_[0];
        $s="b";
        print $s;
}
my $s="a";
test($s);
print $s;

perl子例程参数传递方式类似于引用(或者地址)传递

你可以理解为引用传递,所以习惯sub{后的第一句就把参数值赋给一个新的变量
不是类似啊!!! 解释清楚些吧。。。

否则如果按引用传递理解
sub test {
        my $s = shift;  #或者   my $s = $_[0];
        $s="b";
        print $s;
}
那这样$s是形参的引用啊!

解释一下

这样应该能更容易理解

[Copy to clipboard] [ - ]
CODE:
sub test {
       print "\$_[0]:\t",\$_[0],"\n";
        my $aa = shift;
        $aa="b";
        print "\$aa:\t",\$aa,"\n";
        
}
my $s="a";
test($s);
print "\$s:\t",\$s,"\n";



[Copy to clipboard] [ - ]
CODE:
$_[0]:        SCALAR(0x182fabc)
$aa:        SCALAR(0x182fa20)
$s:        SCALAR(0x182fabc)

因为 $_[0]  与 $s 地址相同 所以改变 $_[0] 后 $s也改变
大骆驼上有,对于@_变量的解释。 对@_ 之类的,最好 是先copy。
对@_整个改变是没有问题的
怕就怕对单个元素进行改变
如下

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl
use strict;
use warnings;

sub change1 {
        @_ = qw ( one two three );
        }


sub change2 {
        $_[0] = "one";
        }

my @test1 = qw ( 1 2 3 );
my @test2 = qw ( 1 2 3 );
change1 ( @test1 );
print "@test1 \n";
change2 ( @test2 );
print "@test2 \n";

运行结果

QUOTE:
1 2 3
one 2 3

恩,用地址来解释是好懂些了,这样的话就跟c语言的地址操作一样了,perl中的\操组符相当于c的 &操作符,都是取地址

对于传递scalar类型的变量,$_[0]和原变量的地址是一致的

但是对于传递array类型的变量,函数体内部对于@_的地址和原数组地址不一样,但是@_
里的每个元素的还是scalar类型的,还是跟以前数组里的元素的地址一样。

综合楼上帖子,写了个scalar和array传递的例子,大家看看就知道啦

sub test {
       print "\$_[0]:\t",\$_[0],"\n";
        my $aa = shift;
        $aa="b";
        print "\$aa:\t",\$aa,"\n";
        
}
my $s="a";
test($s);
print "\$s:\t",\$s,"\n";

sub testa {
        print \@_;
        print "\$_[0]:\t",\$_[2],"\n";
        
}

my @a=qw(a b c);
print \@a . "\n";
print \$a[2] . "\n";
testa(@a);
<Programming Perl 3rd> - 6.2 Semantics

...
The array @_ is a local array, but its values are aliases to the actual scalar parameters. (This is known as pass-by-reference semantics.) Thus you can modify the actual parameters if you modify the corresponding element of @_.
...

写过一篇分析这个的blog:
perl之陷阱:foreach的implicit alias和@_的alias
http://www.surfybeach.net/blog/archives/5
看了你的blog

原来foreach循环有个奇特的地方。。。

@a=qw(1 2 3 4);

foreach(@a) {$_+=1;}

print @a;

foreach $b(@a) {$b+=1;}

print @a;

foreach (@a) {$b=$_;$b+=1;}

print @a;

运行一下有点明白。。 原来foreach $b(@a)中的$b是对@a元素的引用。。。