关于现有perl子例程的三个问题
我试图使用以下perl函数,但我不太清楚三点:关于现有perl子例程的三个问题,perl,Perl,我试图使用以下perl函数,但我不太清楚三点: sub inittwiddle { my ($m,$n,$aref) = @_; my $i; $$aref[0] = $n+1; for ($i=1; $i != $n-$m+1; $i++) { $$aref[$i] = 0; } while($i != $n+1) { $$aref[$i] = $i+$m-$n; $i++;
sub inittwiddle {
my ($m,$n,$aref) = @_;
my $i;
$$aref[0] = $n+1;
for ($i=1; $i != $n-$m+1; $i++) {
$$aref[$i] = 0;
}
while($i != $n+1) {
$$aref[$i] = $i+$m-$n;
$i++;
}
$$aref[$n+1] = -2;
$$aref[1] = 1 if ( $m == 0 );
}
首先,my($m,$n,$aref)=@代码>代表什么
第二,如何理解像$$aref[0]=$n+1这样的事物的$$
代码>
这个函数被调用为inittwidle($M,$N,\@p)代码>p代表什么?第一个问题只是参数传递。调用perl sub时,其参数位于特殊数组@
中。第一行只获取数组中的前3项,并将它们放入这3个局部变量中
另外两个问题涉及参考文献。我建议你看一看\@p
正在将引用传递给数组@p
。然后,将该引用放入$$aref
,然后使用$$aref[0]
访问数组的第一个元素(这可能更清楚地理解为${$aref}[0]
)
@
是传递给函数的参数列表。通过执行my($m,$n,$aref)=@
您正在将$\u0]
分配给$m
,$\u1]
分配给$n
,$\u2]
分配给$aref
$aref
是一个标量值,包含对数组的引用。要引用数组中的元素,您可以通过$aref->[0]
(这更为惯用),或者通过取消引用数组引用来访问它们。通过在前面添加一个@
,可以引用数组(即@$aref
)。但是,您需要数组中的第一个元素,它是标量,因此它是通过$$aref[0]
获得的。添加括号(${$aref}[0]
)或使用箭头符号($aref->[0]
)可以稍微澄清这一点
\@p
是对数组@p
的引用。由于函数将标量作为第三个参数,因此必须传入标量<代码>\@p
就是这样。当您将数组引用传递到这样的函数中时,请务必注意,对数组的任何更改(例如执行$$aref[0]=$n+1
)都是对原始数组的更改。如果您想避免这种情况,您可以通过执行my@tmparr=@$aref代码>在函数中
首先,my($m,$n,$aref)=@代码>代表什么
将一组参数传递给子例程时,它们将作为列表(有时称为数组)传递给名为@
的特殊数组
在这种情况下,子例程将变量$m
、$n
和$aref
设置为此特殊数组中的前三个值
与此类似:
my $m = @_[0];
my $n = @_[1];
my $aref = @_[2];
第二,如何理解像$$aref[0]=$n+1这样的事物的$$
代码>
现在,我们进入参考文献。引用是指向另一个Perl变量的指针。假设我有一个这样的数组:
@my_list = ("one", "two", "three", "four");
我可以通过以下操作创建指向此列表的指针:
my $my_list_ref = \@my_list;
变量$my\u list\u ref
现在指向@my\u list
。变量@my_list
前面的反斜杠告诉Perl,我不想使$my_list\u ref
等于@my_list
。相反,我只希望$my_list\u ref
指向@my_list
现在,如果我想实际引用$my_list\u ref
所指向的数据,我将执行所谓的取消引用操作。我通过在它前面放一个@
来实现:
print join ",", @{ $my_list_ref }; #prints "one, two, three, four"
如果我想引用列表中$my_list_ref
指向的特定值,我可以使用相同类型的语法:
print ${ $my_list_ref }[0]; #Prints 'one'
print ${ $my_list_ref }[1]; #Prints 'two'
将引用变量放在大括号中有助于澄清您在做什么,但同时也会使解析变得更加困难。为了解决这个问题,Perl允许您进行一些语法简化
在简单情况下,可以删除大括号:
print $$my_list_ref[0]; #Prints 'one'
print $$my_list_ref[1]; #Prints 'two'
注意双美元符号!这是您在子例程中看到的
大多数情况下,您会看到->
语法,即:
这个函数被调用为inittwidle($M,$N,\@p)代码>什么是\@p
代表的
现在,我们进入一个问题,为什么首先要使用引用。首先,让我们看一下Perl子程序的一些局限性:
所有参数都在一个@
数组中传递。如果我有一个以两个列表为参数的子程序呢?它们都被咀嚼到单个@
数组中
如果我将一个非常非常大的列表传递到我的子例程中,那么当该列表被复制到@
数组中时,可能会占用大量内存
在Perl子例程中,我传递的所有变量在子例程中都具有独立的标识。在子例程中更改它们不会在它们离开子例程后更改其值。如果我想改变他们的价值观呢
使用引用可以解决所有这些问题。编写此子例程的开发人员试图解决问题2和问题3。电话:
inittwiddle($M, $N, \@p);
获取两个标量变量,并引用数组@p
。如果数组@p
中有一百万个值,那么将整个列表复制到子例程可能需要很长时间。另外,开发人员看起来也在更改@p
中的项目。当开发者说:
$$aref[0] = $n + 1;
他实际上正在将$p[0]
更改为$n+1
。当子例程返回时,$p[0]
将具有与子例程之前不同的值。请记住,@$aref
不仅仅是@p
的副本,它指向@p
,所以它是@p
您应该阅读以了解有关参考的更多信息。对于初学者,还需要注意的是,由于@p
是由r传入的
$$aref[0] = $n + 1;