sno*_*kin 7 perl printf prefix-operator postfix-operator
我想知道为什么以下输出7 7 6 7而不是5 6 6 7
my $a = 5;
printf("%d %d %d %d",$a,++$a , $a++ , $a);
Run Code Online (Sandbox Code Playgroud)
我很确定它与参数编译的顺序有关
谢谢,
ike*_*ami 14
在开始之前,让我指出一个人应该避免在表达式中设置和读取变量的情况.
首先,让我们看一下操作数评估顺序.这不是为许多运算符定义的,而是为列表运算符定义的.记录下以从左到右的顺序评估其操作数[1].这意味着printf将按以下顺序评估参数:
"%d %d %d %d"$a++$a$a++$a关键在于知道$a不会$a在堆栈上放置值的副本.它放置标量本身(a SV*,用C表示).在Perl术语中,我们说堆栈元素别名为$a[2].在计算理论中,你会说参数是通过引用传递的.
这同样适用++$a,但$a++必然会$a在堆栈上放置一份副本.
这意味着我们可以将上述printf调用视为等效
use Data::Alias qw( alias );
{
local @_;
alias $_[0] = "%d %d %d %d";
alias $_[1] = $a; # Places $a on the stack.
alias $_[2] = ++$a; # Adds one to $a and places $a on the stack.
alias $_[3] = $a++; # Places a copy of $a on the stack and adds one to $a.
alias $_[4] = $a; # Places $a on the stack.
&CORE::printf;
}
Run Code Online (Sandbox Code Playgroud)
到时候$a++被召唤,$a包含6个.
到时候printf被召唤,$a包含7个.
解决方法是复制值.
$ perl -le'$a = 5; my @b = ($a, ++$a, $a++, $a); print "@b";'
7 7 6 7
$ perl -le'$a = 5; my @b = (0+$a, 0+(++$a), $a++, $a); print "@b";'
5 6 6 7
Run Code Online (Sandbox Code Playgroud)
从perlop开始,"在列表上下文中,它只是列表参数分隔符,并将其参数插入到列表中.这些参数也从左到右进行计算."
从perlsyn,"传入的任何参数都显示在数组中@_.因此,如果你调用一个带有两个参数的函数,那些将存储在$_[0]和中$_[1].数组@_是一个本地数组,但它的元素是实际标量参数的别名. "
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |