非常混乱的 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 循环会产生两个不同的结果。
我们有一项学校任务是从 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 循环会产生两个不同的结果。