将短路运算符与常规运算符组合是否会更改表达式的结果

本文关键字:运算符 表达式 结果 是否 短路 常规 组合 | 更新日期: 2023-09-27 17:57:07

我一直

认为使用条件布尔运算符(又名短路)代替常规布尔运算符不会影响表达式的结果。

var result = true | false & false;

具有与

var result = true || false && false

这两个表达式都会导致true

但是,如果我混合使用常规运算符和条件运算符呢?

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

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

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

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

将短路运算符与常规运算符组合是否会更改表达式的结果

var result2 = true | false && false;

计算公式为:

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

因为|先于&&.现在(true | false)计算结果为 truetrue && false为假。

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

&&

&和||运算符是后来添加的,因为它们的"短路"行为。Dennis Ritchie回想起来承认,在添加逻辑运算符时,应该改变按位运算符的优先级。但是,当时有几百千字节的C源代码,并且安装了三台计算机,Dennis认为C语言的变化太大了。

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

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

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

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

因此,在 C 语言中,|&& 绑定更严格似乎是很自然的。

在 C# 中,我们具有更高程度的类型安全性,并且没有从 Int32Boolean 或从 BooleanInt32 的转换。因此,不再可能"混合"事物,并且优先级不再自然。

我想在 C# 的理论上,可以使运算符

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

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

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

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

我认为人们很少在同一表达式中使用布尔非短路运算符(如|)和短路运算符(如&&),但是当他们这样做时,他们应该非常小心优先级,或者只是将括号()放在那里(这也会使意图更加清晰)。

&and

| 运算符计算这两个参数(可能涉及调用方法),然后返回 and- 或 or 操作的结果。

&&

&和||运算符只评估他们的参数,直到最终结果完全确定。

例如: true | SomeMethod()false & SomeMethod()调用 SomeMethod() 函数 true || SomeMethod()false && SomeMethod()没有。

当然,这个例子中的truefalse也可以是变量,我只是使用常量使示例更易于理解。