PHP 循环增量怪癖 - (一行中的 FizzBu​​zz)

PHP loop increment quirk - (FizzBuzz in one line)

我在学习PHP。我决定将著名的 FizzBu​​zz 问题的解决方案从 Javascript 修改为 PHP,只是为了看看 JS 和 PHP 的比较。

对于那些忘记了 FizzBu​​zz 问题是什么的人:

Write a short program that prints each number from 1 to 100 on a new line. For each multiple of 3, print "Fizz" instead of the number. For each multiple of 5, print "Buzz" instead of the number. For numbers which are multiples of both 3 and 5, print "FizzBuzz" instead of the number.

我在以下示例中使用了很多短路评估。 这是我改编的聪明的解决方案(不是我写的) PHP:

效果很好!

然后,为了挑战,我决定尝试在一行中重写它。 我是这样开始的:

似乎是一个好的开始。我在 while 循环中的条件:如果 $i 没有设置,那么我将它设置为零,但如果它已经设置,我跳过第一部分并检查它是否低于 100。 正如您在这张图片上看到的,我的循环有效。 由于我的目标是将其写成一行,因此我需要在条件语句中递增 $i,就像我之前的多行解决方案一样。但是当我像以前一样写 $i++ < 100 时,会发生一些奇怪的事情。我的循环只运行一次就停止了。

确实很奇怪。 更奇怪的是,如果我同时使用两个增量(一个在条件中,一个在循环中),那么循环就可以正常工作,并应用两个增量。

我很困惑。是因为某处有无限循环的保护措施吗?有了所有这些短路评估,甚至我的 IDE PHP Storm 也说 'variable $i is probably undefined'。但是它被定义了,我的循环在某些条件下工作正常。我错过了什么?

编辑: 这是代码: 多行工作 FizzBu​​zz:

$i = 0;
while ($i++ < 100) {
    $msg = '';
    ($i % 3) || ($msg = $msg . 'Fizz');
    ($i % 5) || ($msg = $msg . 'Buzz');
    echo $msg . "\n";
}

奇怪的循环迭代(你可以删除循环或条件中的增量,或者两者都保留以查看不同的效果):

while ( (!isset($i) && ($i=0 || true) ) || ($i++ < 100) ) {
    echo $i . "\n";
    $i = $i +1;
}

$i=0 || true 导致 $itrue
true++ 实际上什么也没做。
true < 100false.
echo true 输出 1。
显式 true + 1 创建 2.

if $i is not set set, then I set it to zero

这不太对。这是正在发生的事情。

  1. 您的语句 ($i=0 || true)$i 设置为 TRUE
  2. PHP 的类型为 "$i" 打印“1”。考虑 $v = TRUE; echo "$v"; 以查看效果。
  3. 在下一次迭代中,您的第二个条件被评估为 TRUE < 100,其评估为 FALSE,从而退出循环。

因此,为了解决您的问题,只需放下 || true 并开始您的快乐之旅。

过时的评论:我找到了怪癖的起源。不知道为什么会这样。 如果我将 $i++ 重写为 ($i = $i + 1),它工作正常。

while ( (!isset($i) && ($i=0 || true) ) || (($i = $i + 1) < 100) ) {
    echo $i . "\n";
}

天哪,是的!我以为我需要 || true 部分是因为 ( !isset($i) && ( $i = 0 ) ) 要么做 && 的两边,要么都不做。我从没想过 ( $i = 0 ) 会评估为“真”。但看起来确实如此:)