前增量与后增量

9
它们有什么区别?这是我想到的,但我不确定...
如果您使用前缀递增,例如在一个带有++j的for循环中,那么您基本上是在说:“复制j的值以供在循环中使用,然后递增j,然后使用j的副本通过循环语句。” 如果您在同一循环中使用后缀递增 j ++,则基本上是在说:“复制 j 的值以供在循环中使用,然后使用 j 的副本通过循环语句,然后递增 j。”
我不确定的原因是因为我创建了一个 for 循环,将 j 的值乘以 10,然后输出 j=1 到 j=12 的结果,同时使用后缀和前缀递增。人类可读的输出与后缀和前缀递增完全相同。我在想,“如果没有某种复制操作,输出怎么会完全相同?”
所以,我猜测,在 php 中,前缀和后缀递增之间的差异真正变得重要,当我使用引用(在 php 中充当指针)而不是返回值的名称时?这是因为不会复制引用的副本,因此前缀递增将是:“递增 j,然后使用更改后的 j 值通过循环语句,然后再次递增 j...”,而后缀递增将像这样:“使用 j 的值进行语句循环,然后更改 j 的值,然后使用新的 j 值通过循环...”

5
这种行为与编程语言无关(或至少不特定于PHP),因此这实际上是一个为什么在for循环的迭代部分将前缀递增改为后缀递增没有任何区别?的重复问题。 - Mark Elliot
3
除了Mark所说的内容,这个问题表明您对于for循环的实际作用有相当根本的误解......完全没有涉及复制 - for循环的第三个子句只是在循环体的末尾执行。您可以在其中放置任何语句,不会发生特殊复制。 - tobyodavies
1
而且,无引用不起指针作用。 - netcoder
2
@Fohsap:不,PHP中的所有变量都是指针(自PHP4以来):zval*。指针指向特定的内存位置。无论是5.2还是5.3,在PHP中都没有这样的东西。但是有引用,它们指向PHP符号树中的条目,但您仍然无法使它们指向您选择的内存位置。因此,再次强调,引用不是指针,也不起到指针的作用。 - netcoder
1
@netcoder +1 - 我对引用和指针的试金石是“你能进行指针算术运算吗?”在PHP中,显然是不行的。 - tobyodavies
显示剩余4条评论
3个回答

31

前缀或后缀增量并不会像魔术般地延迟到以后才执行。它只是内联简写。

在此输入图片描述

// pre-increment
$var = 5;
print(++$var); // increments first, then passes value (now 6) to print()

// post-increment
$var = 5;
print($var++); // passes value (still 5) to print(), then increments

现在让我们看一个循环。

for ($i = 0; $i < 9; $i++) {
    print($i);
}
循环声明的最后一部分($i++)只是在每次循环后执行的语句。它将值“传递”到无处,然后将其递增。$i此时没有被任何地方使用。稍后执行下一个语句(print($i);)时,$i的值已经增加了。
// add 1, then do nothing with $i
for ($i = 0; $i < 9; ++$i) {}

// do nothing with $i, then add 1
for ($i = 0; $i < 9; $i++) {}

不管你采用哪种方式,$i 在循环内部始终保持不变。


如果有帮助的话,你可以将它们看作是小的例程,大致执行以下操作:

// ++$i
{
    $i = $i + 1;
    return $i;
}

// $i++
{
    return $i;
    $i = $i + 1;
}
当我重新阅读您的问题时,我认为困惑更多地与循环如何工作有关,而不是增量运算符如何工作。请记住,增量是一种简单明了的一次性操作,以下是循环中第三个表达式的工作方式。
// here's a basic loop
for ($i = 0; $i < 9; $i++) {
    // do loop stuff
    print($i);
}

// this is exactly what happens
for ($i = 0; $i < 9; ) {
    // do loop stuff
    print($i);

    $i++;
}

仅仅因为最后一行可以放在循环声明中,并不意味着它有特殊的功能。背后没有使用任何引用或其他东西。同一个$i变量在循环内外都可见。循环内外的每个语句在必要时直接查找$i的值。就是这样,没有什么奇怪的事情。


基本上是因为它是用于返回值而不是接收到的值吗? - Wolfpack'08
@Fohsap 我认为你的困惑更多地与循环有关,而不是增量。请看我的最新更新。希望能对你有所帮助。 - Wiseguy

1

当执行$x++时,你是在后置递增...这意味着增加操作只会发生在语句被评估之后。

因此,考虑以下代码:

$x = 10; $y = 0; $z = 5;

$y = $z * $x++;

PHP可以这样做:

$x = 10; $y = 0; $z = 5;

$y = $z * $x++;

// Ignore Post-Increment, Evalutate
$y = $z * $x;
$y = 5 * 10;

// Now Increment x - POST-INCREMENT
$x = $x + 1;
$x = 10 + 1;
$x = 11;

// Continue evaluating statement
$y = 5 * 10;
$y = 50;

当执行++$x时,你是在进行前缀递增...这意味着递增将在语句被评估之前发生:

$x = 10; $y = 0; $z = 5;

$y = $z * ++$x;

// Do Pre-Increment
$x = $x + 1;
$x = 10 + 1;
$x = 11;

// Evaluate
$y = $z * $x;
$y = 5 * 11;
$y = 55;

在 PHP 中,对于 for 循环,PHP 的评估方式如下:
for($i = 0; $i < 30; $i++) {
  doSomething();
}

// Is evaluated EXACTLY as such by PHP

$i = 0;
while($i < 30) {
  doSomething();

  $i++;
}

第一个表达式($i = 0)在循环开始时无条件执行一次。

在每次迭代的开始,将评估$i < 30。如果它评估为TRUE,则继续循环并执行嵌套语句。如果它评估为FALSE,则循环的执行结束。

在每次迭代的结尾,$i++作为独立表达式进行评估(执行)。

因此,在循环中将变量作为第三个表达式后缀递增或前缀递增对其行为没有影响。 在这种简单情况下,两个表达式将完全相同

然而,在复杂的循环中,例如以下循环:

for($i = $j = 0; $i < 30; $i += ++$j) {
  $j = getResult($j);
}

$j 进行后增或前增操作会直接影响到上述示例中的 $i 值。在这种情况下,您需要准确选择您想要执行的操作。


-1
$i = 0;
echo $i++;
echo $i;
$j=0;
echo ++$j;
echo $j;

预增量显示增加后的值。但后增量显示值,然后增加。关于代码将输出01和11


请更加详细地描述。 - Sajidur Rahman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接