我想知道为什么以下输出 7 7 6 7
而不是 5 6 6 7
my $a = 5;
printf("%d %d %d %d",$a,++$a , $a++ , $a);
我很确定它与参数编译的顺序有关
谢谢,
最佳答案
在开始之前,让我指出通常应该避免在表达式中设置和读取变量的情况。
首先,让我们看看操作数评估顺序。这不是为许多运算符定义的,而是为列表运算符定义的。它被记录为以从左到右的顺序评估其操作数 [1]。这意味着 printf
的参数按以下顺序计算:
"%d %d %d %d"
$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;
}
到时候
$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
@_
中。因此,如果您调用带有两个参数的函数,它们将存储在 $_[0]
和 $_[1]
中。数组 @_
是一个本地数组,但是它的元素是实际标量参数的别名。” 关于perl - 编译顺序和后前缀运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16570415/