59

可能重复:
| 之间有什么区别?和 || 还是运营商?

逻辑 AND 和 OR:

(x & y)
(x | y)

条件 AND 和 OR:

(x && y)
(x || y)

到目前为止,我只知道条件操作数。我知道它的作用以及如何在 if 语句中应用它。但是逻辑操作数的目的是什么?

4

3 回答 3

85

我更愿意将其视为“按位与条件”而不是“逻辑与条件”,因为“逻辑”的一般概念适用于这两种情况。

x & y    // bitwise AND, 0101 & 0011 = 0001
x | y    // bitwise OR,  0101 | 0011 = 0111

x && y   // true if both x and y are true
x || y   // true if either x or y are true

编辑

根据大众的要求,我还应该提到,这些论点的评估方式不同。在条件版本中,如果整个运算的结果可以由第一个参数确定,则不计算第二个参数。这称为短路评估。按位运算必须评估双方才能计算最终值。

例如:

x.foo() && y.bar()

这只会y.bar()x.foo()评估为时调用true。反过来,

x.foo() || y.bar()

y.bar()只有在x.foo()评估为时才会调用false

于 2010-06-30T23:28:45.353 回答
35
(x && y) 

是懒惰的。如果 x 为真,它只会评估 y。

(x & y)

并不懒惰。y 将始终被评估。

于 2010-06-30T23:25:37.520 回答
11

更新的答案- 我的原件具有误导性且不完整。

首先,我应该为我对这个问题的许多评论和回答道歉。

阅读规范后,按位运算符和条件运算符之间的区别就不那么明确了。

根据ECMA-334 第 14.10节:

&、^ 和 | 运算符称为逻辑运算符。

对于整数运算:

1 & 运算符计算两个操作数的按位逻辑与,| 运算符计算两个操作数的按位逻辑或,^ 运算符计算两个操作数的按位逻辑异或。2 这些操作不可能发生溢出。

根据第14.11 节:

&& 和 || 运算符称为条件逻辑运算符。2 它们也被称为“短路”逻辑运算符。

14.11.1

1 当 && 或 || 的操作数 是 bool 类型,或者当操作数的类型没有定义适用的运算符 & 或运算符 |,但确实定义了到 bool 的隐式转换时,操作按如下方式处理: 2 操作 x && y 被评估为 x ? 是:错误。3 换句话说,首先计算 x 并将其转换为 bool 类型。4 然后,如果 x 为真,则计算 y 并将其转换为 bool 类型,这成为运算的结果。5 否则,运算结果为假。6 操作 x || y 被评估为 x ? 真的:是的。7 换句话说,首先计算 x 并将其转换为 bool 类型。8 然后,如果 x 为真,则运算结果为真。9 否则,计算 y 并将其转换为 bool 类型,这将成为操作的结果。

14.11.2

1 当 && 或 || 的操作数 是声明适用的用户定义运算符 & 或运算符 | 的类型,以下都必须为真,其中 T 是声明所选运算符的类型: 2 返回类型和所选运算符的每个参数的类型运算符必须是 T。 3 换句话说,运算符必须计算 T 类型的两个操作数的逻辑 AND 或逻辑 OR,并且必须返回 T 类型的结果。 4 T 必须包含 operator true 和 operator false 的声明。第 2 段 1 如果不满足这些要求中的任何一个,则会发生编译时错误。2 否则,&& 或 || 通过将用户定义的运算符 true 或 operator false 与选定的用户定义的运算符组合来评估操作: 3 操作 x && y 被评估为 T.false(x) ?x : T.&(x, y),其中 T.false(x) 是对 T 中声明的运算符 false 的调用,而 T.&(x, y) 是对选定运算符 & 的调用。4 换句话说,首先对 x 求值,然后在结果上调用运算符 false 以确定 x 是否肯定为假。5 然后,如果 x 肯定为假,则运算结果是先前为 x 计算的值。6 否则,对 y 求值,并根据先前为 x 计算的值和为 y 计算的值调用选定的运算符 & 以产生运算结果。7 操作 x || y 被评估为 T.true(x) ?x : T.|(x, y),其中 T.true(x) 是对 T 中声明的运算符 true 的调用,而 T.|(x, y) 是对选定运算符 | 的调用。8 换句话说,首先对 x 求值,然后在结果上调用运算符 true 以确定 x 是否绝对为真。9 然后,如果 x 肯定为真,则运算结果是先前为 x 计算的值。10 否则,评估 y,并选择运算符 | 对先前为 x 计算的值和为 y 计算的值调用以产生操作结果。第 3 段 1 在上述任一操作中,x 给出的表达式只计算一次,y 给出的表达式要么不计算,要么只计算一次。第 4 段 1 有关实现 operator true 和 operator false 的类型的示例,请参阅第 18.4.2 节。运算的结果是先前为 x 计算的值。10 否则,评估 y,并选择运算符 | 对先前为 x 计算的值和为 y 计算的值调用以产生操作结果。第 3 段 1 在上述任一操作中,x 给出的表达式只计算一次,y 给出的表达式要么不计算,要么只计算一次。第 4 段 1 有关实现 operator true 和 operator false 的类型的示例,请参阅第 18.4.2 节。运算的结果是先前为 x 计算的值。10 否则,评估 y,并选择运算符 | 对先前为 x 计算的值和为 y 计算的值调用以产生操作结果。第 3 段 1 在上述任一操作中,x 给出的表达式只计算一次,y 给出的表达式要么不计算,要么只计算一次。第 4 段 1 有关实现 operator true 和 operator false 的类型的示例,请参阅第 18.4.2 节。x 给出的表达式只计算一次,而 y 给出的表达式要么不计算,要么只计算一次。第 4 段 1 有关实现 operator true 和 operator false 的类型的示例,请参阅第 18.4.2 节。x 给出的表达式只计算一次,而 y 给出的表达式要么不计算,要么只计算一次。第 4 段 1 有关实现 operator true 和 operator false 的类型的示例,请参阅第 18.4.2 节。

于 2010-06-30T23:26:02.987 回答