1

我一直认为使用条件布尔运算符(也称为短路)而不是常规布尔运算符不会影响表达式的结果。

var result = true | false & false;

有相同的结果

var result = true || false && false

两个表达式都导致true.

但是,如果我将常规运算符和条件运算符混合使用会怎样?

var result1 = true || false & false;
var result2 = true | false && false;

你会期待什么?我希望这些仍然会返回true。但事实并非如此。结果2会false

我知道这是因为运算符优先级。优先顺序是& | && ||。这对我来说似乎违反直觉。我期望 的顺序& && | ||,在这种情况下,所有结果都是相同的(我认为)。

所以我想我真正的问题不是短路是否会改变结果。问题是为什么优先顺序是这样的,短路可以改变结果。

4

3 回答 3

2
var result2 = true | false && false;

计算为:

var result2 = (true | false) && false;

因为|来之前&&。现在(true | false)评估为true,并且true && false为假。

至于为什么,请看这个问题

&& 和 || 后来添加了运算符,因为它们的“短路”行为。Dennis Ritchie 回想起来承认,当添加逻辑运算符时,应该更改位运算符的优先级。但是当时存在数百 KB 的 C 源代码和安装了三台计算机的基础,Dennis 认为 C 语言的变化太大了……

于 2013-02-03T11:32:30.940 回答
1

有问题的运算符的优先级似乎直接从 C(和 C++)编程语言中的优先级复制而来。

现在在 C 中,它们不为整数和布尔值使用不同的类型。例如,他们可以写:

if (i | j && x > 0)      // cf. the result2 of your question

这应该意味着“整数ij按位或'ed给出非零并且数字x是正数”。因此|&当操作数被认为是整数(多位数字)时,应该主要使用 and ,并且应该在操作数被认为是布尔值时主要使用||and 。&&

因此,在 C 中|绑定比&&.

在 C# 中,我们有更高程度的类型安全,并且没有从Int32toBoolean或 from Booleanto的转换Int32。因此,不再可能“混合”事物,优先级不再是自然的。

我猜理论上在 C# 中,可以使运算符

public static bool operator |(bool b, bool c)

具有与运算符不同的优先级

public static int operator |(int i, int j)

但它真的不会让事情变得更好吗?

I think it's very rare that people use boolean non-short-circuit operators like | and short-circuit operators like && in the same expression, but when they do, they should either be very careful about precedence, or just put the parenthesis () there (it will also make the intention more clear).

于 2013-02-03T21:25:46.463 回答
0

& 和 | 运算符评估两个参数(可能涉及调用方法),然后返回与或或操作的结果。

&& 和 || 运算符仅将其参数评估到最终结果完全确定的程度。

例如: 调用 SomeMethod() 函数 而不 true | SomeMethod()调用 。false & SomeMethod()true || SomeMethod()false && SomeMethod()

true当然,false在这个例子中也可以是变量,我只是使用常量来使例子更容易理解。

于 2013-02-03T11:35:31.517 回答