(x || !x) 啥时候是假的?
Posted
技术标签:
【中文标题】(x || !x) 啥时候是假的?【英文标题】:When is (x || !x) false?(x || !x) 什么时候是假的? 【发布时间】:2016-06-11 20:01:18 【问题描述】:我的一个朋友开玩笑地问了我这个问题。这本来是一种“不言而喻”的评论,但后来我真的考虑了一段时间,并开始想出一些聪明的“几乎解决方案”。
第一次尝试:
如果 C 曾经支持量子计算,那么可能会有答案。一个 q 位可以同时处于多个状态,因此它可能是假和真,并且此条件将返回
(BOOL)0.5
aka "Yes/no/maybe-so" - 但是一旦你观察到变量,整个事情就会崩溃并且再次失效。
第二次尝试:
如果 X 可以以某种方式定义为随机二进制生成器,并且您将其转换为 BOOL,则有时您可能会得到 false。我不确定您是否可以在 C 中执行此操作,除非您使用 CLANG。
#define x (BOOL)!!(rand()%2)
我们讨论这个问题的语言是C,但我也很好奇是否有人能找到任何任何语言的解决方案。
【问题讨论】:
答案:未定义的行为。 这是哈姆雷特几百年前提出的问题:bb || !bb
。
@nsilent22 我笑得有点硬了????
如果发生未定义的行为或未指定值,则表达式可能为假。
你可以忘记你的量子计算解释:如果x
是真假叠加,那么!x
将与x
纠缠,即。当测量x
产生假时,测量!x
将精确地产生真,反之亦然。在这两个纠缠的 qbit 上计算 or 将产生一个非常经典的 qbit。 (这就是量子计算机的美妙之处:它们允许一次计算具有所有可能输入的函数。但计算在逻辑上仍然是合理的。)
【参考方案1】:
当x
是volatile (volatile int x
)并且被外部线程/设备修改时,表达式可以为false。
【讨论】:
有趣的解决方案!我想知道是否有一种方法可以做到这一点,而无需直接在代码中的另一点修改变量 正如我所指出的,如果x
映射到外部修改的内存位置/寄存器,它可能会“自发”发生
哦,你是对的!真是太天才了!虽然它不会总是是假的,嗯
@AlbertRenshaw 你不是一直问的,你问的是什么时候。【参考方案2】:
这有点小技巧,但下面的解决方案也可以:
#define x 1 ? 0 : 1
(x || !x)
原因在于运算符优先级。预处理后(x || !x)
解析为以下内容(添加括号以显示优先级):
(1 ? 0 : (1 || !1) ? 0 : 1)
【讨论】:
这太棒了 - 到目前为止最喜欢的答案 你可以让它更简单:#define x 1&&0
甚至#define x 1,0
【参考方案3】:
宏在这里确实是在作弊,但您不需要与布尔类型或特殊编译器有任何关系。据我所知,以下是法律标准C。
#include <stdio.h>
int f(void)
static int y = 0;
if (y == 0)
y = 1;
return 0;
else
return 1;
#define x f()
int main(void)
if (x || !x)
puts("It was true");
else
puts("It was false");
return 0;
或者更简洁:
int y = 0;
#define x y++
(对于那些担心未定义行为的人,请注意||
的左右两侧之间有一个序列点。)
【讨论】:
我在 Obj-C 中使用 CLANG 进行类似的工作。在意识到我不能在 Objective-C 中的条件句中使用函数之前,我已经到了#define x (BOOL)[[NSUserDefaults standardUserDefaults] integerForKey:@"x"];[[NSUserDefaults standardUserDefaults] setInteger:(int)!(BOOL)[[NSUserDefaults standardUserDefaults] integerForKey:@"x"] forKey:@"x"];[[NSUserDefaults standardUserDefaults] synchronize];
(据我所知)
@AlbertRenshaw:我不知道那是做什么的,但看起来 waaaaaaaaaay 过于复杂了。
延迟回复,但它会将值存储到内存并在每次读取时翻转值【参考方案4】:
一个更简单的宏:
#define x 0&0
扩展(x || !x)
得到(0 & 0 || !0 & 0)
,这总是错误的。
同样:
#define x 0*0
#define x 1*0 // for binary buffs
#define x 4&2 // for HHGG fans.
我找不到 2 个字母的宏 :(
【讨论】:
【参考方案5】:在 JS 中试过:
var i = 0
i++ || !(i++)
注意:此解决方案仅适用于i = 0
【讨论】:
以上是关于(x || !x) 啥时候是假的?的主要内容,如果未能解决你的问题,请参考以下文章
与 react-redux-firebase 反应 isLoaded 是真的, isEmpty 似乎是假的,但 firebase.auth().currentUser 是 null - 可能是啥原因?
清华大学美女学霸“华智冰”是假的?--人工智能(AI)的前世今生