【问题标题】:What is the point of the logical operators in C?C中的逻辑运算符有什么意义?
【发布时间】:2011-02-15 22:07:36
【问题描述】:

我只是想知道 C 中是否有 XOR 逻辑运算符(类似于 && 用于 AND 但用于 XOR)。我知道我可以将 XOR 拆分为 AND、NOT 和 OR,但简单的 XOR 会好得多。然后我想到,如果我在两个条件之间使用普通的 XOR 位运算符,它可能会起作用。对于我的测试,它确实如此。

考虑:

int i = 3;
int j = 7;
int k = 8;

只是为了这个相当愚蠢的例子,如果我需要 k 大于 i 或大于 j 但不是两者,XOR 会很方便。

if ((k > i) XOR (k > j))
   printf("Valid");
else
   printf("Invalid");

printf("%s",((k > i) XOR (k > j)) ? "Valid" : "Invalid");

我把按位异或 ^ 并产生“无效”。将两次比较的结果放入两个整数中,导致这两个整数包含 1,因此 XOR 产生了错误。然后我用 & 和 | 进行了尝试位运算符,两者都给出了预期的结果。知道真实条件具有非零值,而虚假条件具有零值,所有这些都是有道理的。

我想知道,是否有理由使用逻辑 && 和 ||当位运算符 &, |和 ^ 工作一样吗?

【问题讨论】:

标签: c xor bitwise-operators logical-operators


【解决方案1】:

如果你想要 C 中的逻辑异或运算符,那么你可以使用这个:

#define xor != 0 ^ !!

它的工作原理是将表达式的两边都转换为布尔值并对它们进行异或运算。 您可以像使用 && 或 || 一样使用它,如下所示:

if (a xor b)

AFAICT,没有任何问题。

【讨论】:

    【解决方案2】:

    在 C 语言中,逻辑运算符的参数被视为布尔值——任何零都被视为“假”,其他任何东西(是的,负值也是)都是“真”。位运算作用于单个位,正如 Neil 已经指出的那样,它们像逻辑运算那样受到短路评估。

    在您的示例中,结果完全有效且符合预期,因为两个 1 之间的按位 xor 为零。

    【讨论】:

      【解决方案3】:

      当操作数是整数值时,按位 XOR 的工作方式与逻辑 XOR 不同:

      2^4 ? "Valid" : "Invalid"
      

      给出“有效”但应该给出“无效”

      【讨论】:

      • 我的意思是 XOR 用于条件
      • 在 C 中,2 是表达 TRUE 的有效方式。许多人使用它来检查 NULL 指针:if (!p) ...
      【解决方案4】:

      你不需要逻辑异或,我忘记了SO问题,但是和你想的差不多,基本上我们不需要异或,反正相当于!=

      FALSE XOR FALSE == FALSE
      FALSE XOR TRUE == TRUE
      TRUE XOR FALSE == TRUE
      TRUE XOR TRUE == FALSE
      
      
      FALSE != FALSE == FALSE
      FALSE != TRUE == TRUE
      TRUE != FALSE == TRUE
      TRUE != TRUE == FALSE
      

      我会搜索我的收藏夹,稍后将链接粘贴到这里...

      【讨论】:

      • &|^ 在用于 boolean 值时可能与 ||&& 相同,但通常你不会不要在布尔值上使用&|^——你可以使用它们来处理位(因此它们是按位 运算符)。如果使用得当,位运算符与逻辑运算符不同。
      • 从历史上看,位运算符和逻辑运算符共享一个共同的标记(即&|),没有&&||stackoverflow.com/questions/3930042/… 检查新生儿C:@987654322 @ 不幸的是,当他们将 &&|| 添加到 C 时,他们保留了 &| 的旧运算符优先级。因此,这个关于掩蔽习语的不幸括号(原文如此):if ( (input & alt) == alt )。否则,它可能会更简洁:if ( input & alt == alt )
      • 这不是真的。 != 不是逻辑异或。请参阅:2 LOGICAL_XOR 4 给出 false(这是真的),但 2 != 4 产生 true(这是不正确的)。正确答案如下(Joe D answer
      • 由于询问者询问了逻辑运算符,因此需要先将两个数字适当地减少为布尔值,然后再将任何运算符/宏应用于两个布尔值。只需在表达式的每一侧应用双不。 !!2 != !!4 产生错误。即 true != true 产生 false
      • !!是将数字减少为布尔值的最惯用的方法。如果有任何其他技术,我会很高兴知道:-)
      【解决方案5】:

      按位运算符的工作方式与 && 和 || 不同。操作员。首先,&& 和 ||执行短路评估,而按位运算符不执行。换句话说,你不能用位运算符做这样的事情:

      int * p = 0;
      (p != 0) && (*p = 1);
      

      因为如果你说:

      (p != 0) & (*p = 1);
      

      这两个子表达式都将被计算,并且您将取消对空指针的引用。

      【讨论】:

      • 内部没有,但我仍然得到相同的结果
      • @reubensammut:如果您依赖短路,您将不会得到相同的结果。 if(returnsTrue() || explodesWorld()) 不会毁灭世界,而if(returnsTrue() | explodesWorld()) 会。
      猜你喜欢
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 2010-10-29
      • 2020-04-07
      相关资源
      最近更新 更多