(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 &amp; 0 || !0 &amp; 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)的前世今生

优秀的程序员更重视阅读源码,不看源码那是假的

这五年的工作经验是假的吧?怎么连这些HashMap问题都回答不出来

黄仁勋骗过了全世界,三个多月都没人发觉!皮衣是假的厨房是假的,连他自己都是假的...