非常混乱的 while 循环条件

Very confusing while-loop condition

我们有一项学校任务是从 C 代码文件中删除 C 注释。

这个任务有一种方法可以遍历输入文件并循环直到块注释结束

*/

来了。

为什么这段代码有效,

while(!(input[i] == '*' && input[i+1] == '/'))
{
  i++;
}

但这不是吗?

while(input[i] != '*' && input[i+1] != '/')
{
  i++;
}

由于某种原因,第二个变体甚至从未进入循环。我试着想一想,但找不到为什么它们不能以相同方式工作的原因。

!(something AND something)NAND门,可以表示为!something OR !something

所以在你的情况下

while (!(input[i] == '*' && input[i+1] == '/')) {

相同
//Pick your syntax from these 2 options
while (input[i] != '*' || input[i+1] != '/')
while (!(input[i] == '*') || !(input[i+1] == '/'))

从 AND 到 OR 的转换 如何工作。

考虑现在你有与非门,它是输入 X 和 Y 的非门之后的与门。结果是两个输入的非与。要将 OR 的两个输入分开,您必须执行以下步骤:

     ____      __
x --|    \    |  \
    | AND |---|NOT|--- (NAND)
y --|____/    |__/
  • 将 AND 更改为 OR
  • 通过删除门或再次否定输出来删除 NOT
  • 分别取反每个输入

然后你得到:

x --- NOT GATE --- \ 
                      -- OR GATE -- NOT (from NAND) -- NOT (negate output)
y --- NOT GATE --- /
  • 如果你想做相反的事情,你可以这样做(NOR 和 AND),只需交换 OR 和 AND 以及所有其他步骤。

循环测试条件有一个 AND 表达式,其中 首先计算表达式的第一侧或左侧 以查看我们是否需要还要检查第二个(如果为假,则意味着我们不需要检查第二个 False && anything = False)。

这里,第一个条件是input[i] != '*'。 这就是为什么当字符不在行首时,循环会在第一次执行时退出。

应该是OR而不是AND,

while (input[i] != '*' || input[i+1] != '/')

如果我不是star * 则不能是块评论。 如果 i 是星号 * 那么如果 i+1 不是斜杠 '/' 那么它就不能是块注释。

在您测试的第一个语句...

(input[i] == '*' && input[i+1] == '/')

当计算结果为 !true 时,您将进入循环。要使其成为 !true,您的表达式之一需要失败。

在你测试的第二个语句中...

input[i] != '*' && input[i+1] != '/'

当此计算结果为真时,您将进入循环。要做到这一点,您需要同时表达成功。

你的问题可以通过真实回答table

while(!(input[i] == '*' && input[i+1] == '/'))
{
  i++;
}

产生与非门的真值table

input[i]  input[i+1] Output
    0          0       1  
    0          1       1  
    1          0       1
    1          1       0

鉴于

while(input[i] != '*' && input[i+1] != '/')
{
  i++;
}

产生或非门的真值table

input[i]  input[i+1] Output
    0          0       1  
    0          1       0  
    1          0       0
    1          1       0

现在您可以很容易地看出为什么两个 while 循环会产生两个不同的结果。