在 while 循环中使用 if 语句

using an if statement inside a while loop

我刚刚弄清楚如何测试特定条件并在循环内修改输出。但我注意到使用 && 运算符测试两个条件仅适用于 if/else if/else if/else 链,如果它是第一个测试的话。

谁能解释一下为什么会这样:

var number = 0;
var counter = 0;

while (counter < 100) {
  number ++;
  counter ++;
  if (number % 3 == 0 && number % 5 == 0)
    console.log ("FizzBuzz");
  else if (number % 3 == 0)
    console.log("Fizz");
  else if (number % 5 == 0)
    console.log("Buzz");
  else
    console.log(number);
}

但这不是吗?:

var number = 0;
var counter = 0;

while (counter < 100) {
  number ++;
  counter ++;
  if (number % 3 == 0)
    console.log("Fizz");
  else if (number % 5 == 0)
    console.log("Buzz");
  else if (number % 3 == 0 && number % 5 == 0)
    console.log ("FizzBuzz");
  else
    console.log(number);
}

您想测试数字是否可以被三和五整除,但在您这样做之前,您需要测试它是否只能被三整除。

是的,所以它遵循逻辑分支并且从不尝试测试它是否可以被 3 和 5 整除。

因为在您的测试中,如果数字是 3 或 5 的倍数,那么相应的 if statemetn 将在到达 number % 3 == 0 && number % 5 == 0 语句之前执行,因此它永远不会被执行。

让我们假设数字是 33,第一个测试将成功,这是正确的,但如果数字是 15,那么第一个 if 再次成功,因为 15 是 3 的倍数,所以偶数虽然它是 5 的倍数,但第三个条件也不会有机会执行

为了让它正确,您可能需要类似下面的内容,如果数字是两个版本的倍数,我们将跳过前 2 个条件

var number = 0;
var counter = 0;

while (counter < 100) {
    number++;
    counter++;
    if (number % 3 == 0 && number % 5 != 0) {
        console.log("Fizz");
    } else if (number % 5 == 0 && number % 3 != 0) {
        console.log("Buzz");
    } else if (number % 3 == 0 && number % 5 == 0) {
        console.log("FizzBuzz");
    } else {
        console.log(number);
    }
}

在第二个版本中,所有能被 3 整除或能被 5 整除的都被删除了。当它检查一个数字是否可以被 3 整除 是否可以被 5 整除时,它不可能为真,因为前两个子句之一已经被评估为真。

考虑这个伪代码

if( A || B  ) return;
if( A && B ) //this code will never execute

然后认为A是number % 3 == 0,B是number % 5 == 0。这基本上就是正在发生的事情,以及为什么最后一个 if 语句永远不会执行。

你真正想测试的是

if      (number % 3 == 0 && number % 5 == 0) …
else if (number % 3 == 0 && number % 5 != 0) …
else if (number % 3 != 0 && number % 5 == 0) …
else if (number % 3 != 0 && number % 5 != 0) …

如果你写出这四种情况。

只是你不需要那么明确,因为当之前的条件已经不匹配了(而你在else分支),那么那些 != 0 隐含的 ,您可以省略它们。但是,顺序很重要,因为条件是连续测试的。

所以如果你完全符合条件,你可以随意乱序:

if      (number % 3 == 0 && number % 5 != 0) … // move to front
else if (number % 3 != 0 && number % 5 == 0) …
else if (number % 3 == 0 && number % 5 == 0) …
else if (number % 3 != 0 && number % 5 != 0) …

然后继续简化条件,省略其父案例已经隐含的部分:

if (number % 3 == 0 && number % 5 != 0)
    console.log("Fizz");
else if (number % 3 != 0 && number % 5 == 0) // (an == instead of the && would suffice)
    console.log("Buzz");
else if (number % 3 == 0) // as it didn't match the first condition, we know that % 5 == 0
    console.log("FizzBuzz");
else // here we know that % 3 != 0 && % 5 != 0
    console.log(numer);

条件的其他排列让我们使用尽可能少的原始示例,例如

if (number % 3 == 0 && number % 5 != 0)
    console.log("Fizz");
else if (number % 3 == 0) // as it didn't match the first condition, we know that % 5 == 0
    console.log("FizzBuzz");
else if (number % 5 == 0) // as it didn't match the first condition, we know that % 3 != 0
    console.log("Buzz");
else // here we know that % 3 != 0 && % 5 != 0
    console.log(numer);

并且通过嵌套它们可以实现最少的测试次数:

if (number % 3 == 0)
    if (number % 5 == 0)
        console.log("FizzBuzz");
    else
        console.log("Fizz");
else
    if (number % 5 == 0)
        console.log("Buzz");
    else
        console.log(numer);

一个else if,顾名思义,只会在前一个if失败时执行。所以语句 else if (number % 3 == 0 && number % 5 == 0) 只会在 if (number % 3 == 0)else if (number % 5 == 0) 失败时执行。如果一个数字是 3 和 5 的倍数,那么第一个 if 被成功执行,其余的 ifselse-ifs 被忽略。

但是,在代码 1 中,ifselse-ifs 的顺序是这样的,如果一个数字可以同时被 3 和 5 整除,那么首先执行 if,如果只能被3整除,那么先if不执行,只执行else if (number % 3 == 0)

让我们用数字 61015 做一个例子。

数字 6 将执行 - 在您的第一个示例(工作示例)中 - 第二个 if 块,因为在第一个块中,条件将不满足,而第三个和第四个块将被忽略,并且 - 在您的第二个示例(无效示例)中 - 将执行第一个 if 块并忽略后面的其他块。

数字 10 将执行 - 在您的第一个示例中 - 第三个块,因为第一个和第二个的条件不满足,而第四个块将被忽略,并且 - 在您的第二个示例中 - 将执行第二个块,因为第一个块中的条件不满足,而后面的块将被忽略。

数字 15 将执行 - 在您的第一个示例中 - 第一个块并忽略后面的块,并且 - 在您的第二个示例中 - 还将执行第一个块,因为在随后的块将被忽略。

所以,回顾一下,在你的第二个例子中,第三个 if 块永远不会被执行,因为它的执行条件由第一个和第二个 [=] 的 and 组成14=] 块的条件。为了执行第三个块,您需要第一个 if 块的条件(比方说 c1)和第二个 if 块的条件(比方说 c2) 是 falsec1 && c2true,但是为了让 c1 && c2true 你需要 c1c2true,这将导致执行第一个块并跳过其余块。