在这个美丽的东西(The Internet
这个美丽的东西的浩瀚和危险的飞机周围的无尽的旅程中,我遇到了一个神秘的,老的,白胡子的巫师,其名字不得提及。尽管死得很厉害,但很快就把他带走了。
在他最后一次呼吸之前的一瞬间,他向我传了一个卷轴,然后晕倒了,低声说道
Take this and spread the knowledge
在他去世后很快,他的身体转化为能量,纯净的能量,在宇宙中传播。
滚动包含了这段代码:
#include <iostream>
int main()
{
int x = 3;
while(2 <= x <= 5)
std::cout << x++;
}
这个谜至今仍然存在:
如何评估条件?
答案 0 :(得分:13)
始终为真,因为2<=x
评估为1
或0
,两者均为<=5
。
所以这实际上是一个无限循环:
while( (2 <= x) <= 5)
std::cout<<x++;
答案 1 :(得分:5)
嗯,这个卷轴的作曲家想要表达一个我们称之为链式算子符号的条件,这在数学上是众所周知的(也许巫师是数学家?):
Let x ∈ ℜ, 2 ≤ x ≤ 5. Then ...
通常,在C ++,C,Java和许多具有类似表达式评估逻辑的其他语言中,这是不可能的。有些库可以实现这样的功能,但另一方面会引入冗长,因为你必须首先包装其中一个参数。此外,它对程序员来说也不是很易读。
如果您使用向导在此滚动条上所用的语言编写表达式,则会从左到右对进行评估:
while ( (2 <= x) <= 5 )
...
始终为true
,因为2 <= x
为true
或false
,并隐式转换为1
或0
的整数值,分别总是小于或等于5
。
要表达数学家所希望的条件,你必须使用语法
while ( (2 <= x) && (x <= 5) )
...
或使用效用函数来表达:
template<class T>
bool between(const T& arg, const T& min, const T& max) {
return !(arg < min) && !(max < arg);
}
while ( between(x, 2, 5) )
...
请注意我是如何在between
中编写条件的:它只需要operator<(T, T)
的实现,从而简化了自定义类型的实现。