C语言中逻辑运算符的作用是什么?

5

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

请考虑以下代码:

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

为了这个相当愚蠢的例子,如果我需要k要么大于i,要么大于j但不是两者都满足,那么异或运算会非常方便。

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

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

我使用按位异或符号^,结果显示"无效"。将两个比较的结果放入两个整数中,这两个整数都包含1,因此异或运算得到了一个假值。我尝试使用按位与符号&和按位或符号|,两者都得到了预期的结果。所有这些都有意义,因为真条件具有非零值,而假条件具有零值。
我想知道,当按位运算符&、|和^能够达到相同的效果时,使用逻辑运算符&&和||是否有理由?

可能是C++中的逻辑异或运算符?的重复问题。 - phuclv
5个回答

13

你不需要逻辑异或,我忘记了这个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

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


2
&、| 和 ^ 在处理布尔值时可能与 || 和 && 的作用相同,但通常不会使用 &、| 和 ^ 来处理布尔值 -- 它们用于位操作(因此被称为“按位”运算符)。当适当使用时,按位运算符与逻辑运算符并不相同。 - mipadi
历史上,按位运算符和逻辑运算符共享一个通用标记(即 &|),还没有 &&||。请查看新生 C 语言:http://cm.bell-labs.com/cm/cs/who/dmr/chist.html。不幸的是,当它们在 C 语言中添加了 &&|| 后,它们保留了旧的运算符优先级,即 &|。因此,在掩码惯用语中,这是一个不幸的括号表达式:if ((input & alt) == alt)。否则,它可能更简洁:if (input & alt == alt) - Michael Buen
这不是真的。!= 不是逻辑异或。看:2 LOGICAL_XOR 4 得到 false(这是正确的),但 2 != 4 得到 true(这是错误的)。正确答案在下面(Joe D answer)。 - Yury
1
由于提问者询问了逻辑运算符,因此在对两个数字应用任何运算符/宏之前,需要先将它们正确地缩减为布尔值。只需在表达式的每一侧应用双重否定即可。!!2 != !!4 会得出 false。即 true != true 得出 false。 - Michael Buen
!! 是将数字转换为布尔值的最惯用方式。如果还有其他技巧,我会非常乐意知道 :-) - Michael Buen

11

位运算符与&&和||运算符的工作方式并不完全相同。首先,&&和||执行短路评估,而位运算符则不执行。换句话说,您不能使用位运算符执行以下操作:

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

因为如果你说:

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

两个子表达式都会被计算,你将会解引用空指针。


内部上不是这样的,但我仍然得到了相同的结果。 - reubensammut
12
如果你依赖短路逻辑的话,你将无法获得相同的结果。当使用 if(returnsTrue() || explodesWorld()) 时,它不会毁灭世界。但是,当使用 if(returnsTrue() | explodesWorld()) 时,会毁灭世界。请注意不要改变原意。 - unwind

1
如果你想在C语言中使用逻辑异或运算符,可以使用以下代码:
#define xor != 0 ^ !!

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

if (a xor b)

据我所知,它没有任何问题。

1

当操作数是整数值时,按位异或运算符并不像逻辑异或那样工作:

2^4 ? "Valid" : "Invalid"

应该返回“无效”,但实际上返回了“有效”


我指的是在条件语句中使用的异或(XOR)。 - reubensammut
2
在C语言中,数字2是表示TRUE的有效方式。许多人使用它来检查空指针:if (!p) ... - mouviciel

1
在C语言中,逻辑运算符的参数被视为布尔值 - 任何零都被视为“假”,而其他任何值(包括负值)都被视为“真”。位运算操作在单个位上进行,并且正如Neil已经指出的那样,它们不像逻辑运算符那样受到短路评估的影响。
在你的例子中,结果是完全有效和预期的,因为两个1之间的按位异或操作结果为零。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接