C# 条件 AND (&&) OR (||) 优先级
Posted
技术标签:
【中文标题】C# 条件 AND (&&) OR (||) 优先级【英文标题】:C# conditional AND (&&) OR (||) precedence 【发布时间】:2010-11-14 20:46:33 【问题描述】:在我的工作中,我们总是会遇到不必要的编码争论。今天我问条件 AND (&&) 或 OR (||) 是否具有更高的优先级。我的一位同事坚持说他们有相同的优先级,我有疑问,所以我查了一下。
根据 MSDN,AND (&&) 的优先级高于 OR (||)。但是,您能向持怀疑态度的同事证明这一点吗?
http://msdn.microsoft.com/en-us/library/aa691323(VS.71).aspx
bool result = false || true && false; // --> false
// is the same result as
bool result = (false || true) && false; // --> false
// even though I know that the first statement is evaluated as
bool result = false || (true && false); // --> false
所以我的问题是你如何用代码证明 AND (&&) 比 OR (||) 具有更高的优先级?如果你的回答是没关系,那为什么要在语言中这样构建呢?
【问题讨论】:
语言是这样的,因为他们必须做出决定。就个人而言,我不在乎哪个优先;我会用括号来确保我得到了我期望的结果。这与它为什么做它所做的事情无关。这是关于当您在数周、数月或数年后返回代码时能够弄清楚代码在做什么。 @Jeff:这不正确。这个决定有一个数学基础 - 它被称为 布尔代数。 @TheSteve:短路不影响表达式结果。它只会影响副作用。 你甚至必须考虑它的事实意味着你不应该依赖下一个知道的人,如果有一个问题,办公室里的任何人可能需要花 3 秒时间思考它,然后投入 0.5 秒来添加一个 ( 和一个 ) 让我看看我是否明白这一点。你的同事对语言有信心。这种信念与规范和实现相矛盾。您的声明与规范和实施一致。那么为什么你是那个试图构建证明的人呢?举证责任在于有疯狂信念的人,而不是有理智信念的人。我不会再在这上面浪费时间了;如果他们想花时间试图证明什么是错误的,那就让他们吧。 【参考方案1】:将第一个 false 更改为 true。我知道拥有 (true || true) 似乎很愚蠢,但它证明了你的观点。
bool result = true || true && false; // --> true
result = (true || true) && false; // --> false
result = true || (true && false); // --> true
【讨论】:
只有当布尔表达式的结果已知时才会发生短路;短路不能改变布尔表达式的结果。 @James,不,不会。如果 ||具有更高的优先级,则表达式将等价于 (true || true) && false => False,而不是 true,因为在评估 true || true) 为 true,剩下的是 true && false,不会造成短路 @James,不,如果 ||具有更高的优先级,clr 会将其评估为(真或真)&& 假。所以首先它会评估(真||真)。在这个表达式中,是的,会发生短路,因为对于 OR 表达式,如果第一部分为真,则无需计算第二部分。所以这评估为真。现在我们有了真 && 假。对于 && 操作,只有当第一部分为 FALSE 时才会发生短路,在这种情况下它不是,因此两个部分都必须为 true,A && B 才能评估为 true。所以它评估两个部分并提出错误 我们能不能停止所有这些废话,这似乎在重复自己令人作呕的事情?!跟我重复一遍:短路不会改变结果。短路仅适用于结果已知的情况。短路只会影响副作用 @comecme 这不是短路的结果,而是更改操作顺序的结果。 & 运算符的优先级高于 |运算符,因此第一个表达式的行为类似于true | (false & false)
。这将评估为真,因为false & false = false
,然后是false | true = true
。然而,|运算符的优先级高于 && 运算符,因此第二个表达式的行为类似于 (true | false) && false
。这将评估为 false,因为 true | false = true
,然后是 true && false = false
。【参考方案2】:
如果你真的想吓到他试试:
bool result = True() | False() && False();
Console.WriteLine("-----");
Console.WriteLine(result);
static bool True()
Console.WriteLine(true);
return true;
static bool False()
Console.WriteLine(false);
return false;
这将打印:
True
False
False
-----
False
编辑:
回应评论:
在 C# 中,|
是一个逻辑运算符,它执行与 ||
相同的布尔逻辑,但不会短路。同样在 C# 中,|
运算符的优先级高于||
和&&
。
通过打印出这些值,您可以看到,如果我使用典型的 ||
运算符,则只会打印第一个 True
- 随后是表达式的结果,也就是 True
。
但是由于|
的优先级更高,首先评估true | false
(导致true
),然后然后结果是&&
ed 和false
以产生false
.
我并没有试图显示评估顺序,只是|
的右半部分被评估的时间段通常不会:)
【讨论】:
一个。为什么要混合布尔运算符和位运算符?湾。为什么要坚持打印?评估顺序与它有什么关系? 回应回应:|仍然是二进制的。只是对于 bool 它执行所需的操作 - 就像在 C++ 中一样。为了澄清它,MS 将它记录为 bool 的逻辑。但恕我直言,它只会使水浑浊。 这将是一个有趣的恶作剧。 :) 那么,如果把||
改成|
,留下&&
,表达式的结果会从真变假?因此,您通常要么将|
与&
一起使用,要么将||
与&&
一起使用。【参考方案3】:
这不会让你得到你所追求的吗?或者也许我错过了什么......
bool result = true || false && false;
【讨论】:
这区分了具有更高优先级的 && 和 ||具有更高的优先级,但不区分 ||具有更高的优先级和 && 和 ||具有同等优先权。请记住,如果运算符的优先级相等,则它们只是从左到右计算。 我应该说,这确实可以作为 C# 的证明(或者实际上是任何普通语言),因为您得到的实际结果是明确的。如果您遇到故意与布尔代数相矛盾的深奥语言,这不是一种计算相对优先级的通用方法。【参考方案4】:你不用代码而是用逻辑来证明它。 AND 是布尔乘法,而 OR 是布尔加法。现在哪个优先级更高?
【讨论】:
在某些语言中,两者都没有(例如 Smalltalk)。类比可能具有欺骗性。 我不知道其他反对者,但 我 反对,因为这与问题无关。它恰好匹配......但任何人都可以设计一种语言 Foo# ,但这是不正确的;那么你的“proof with logic”将如何工作呢?它可能解释了为什么选择这种优先级,但它无助于确定我安装的编译器实际上是这样运行的。 @romkyns:这与语言有关。 C 和 C++ 的规则源自代数定律。这就是为什么 + 的优先级比 * 小。你可以随心所欲地争论,但你既错误又令人讨厌。您的编译器根据语言规范运行,并且语言规范以代数 Q.E.D. 为基础 QED?你知道证明某事是什么意思吗?该语言可能打算遵循代数定律,但是您如何证明在该意图和大量工程工作之间,没有人搞砸并意外违反它或在实施优先规则时误读规范? (不太可能,但并非不可能) 我认为你提出的观点是有效的,只是它不符合“证明”的条件,证明比仅仅解释语言设计者如何以及为什么决定要严格得多做事。 “他们基于代数,因此它确实像代数一样工作”不是一个严格的证明(实际上这样说在逻辑上是无效的)。【参考方案5】:假 ||真&&真
产量:真实
假 && 真 ||真的
产量:真实
【讨论】:
无论您以什么顺序执行操作,第一个语句都将返回 true。第二个语句仅在 || 时返回 false。首先被评估。因为它确实返回 true,所以要么首先评估 &&,要么它们具有相同的优先级并从左到右进行评估。第三条语句true || true && false
(也返回 true)只有在 && 被首先评估时才能为 true。【参考方案6】:
当您的布尔表达式被短路时,您不能只显示最终结果。这是一个解决您案件的sn-p。
它依赖于实现 & 和 | && 和 || 使用的运算符,如 MSDN 7.11 Conditional logical operators 中所述
public static void Test()
B t = new B(true);
B f = new B(false);
B result = f || t && f;
Console.WriteLine("-----");
Console.WriteLine(result);
public class B
bool val;
public B(bool val) this.val = val;
public static bool operator true(B b) return b.val;
public static bool operator false(B b) return !b.val;
public static B operator &(B lhs, B rhs)
Console.WriteLine(lhs.ToString() + " & " + rhs.ToString());
return new B(lhs.val & rhs.val);
public static B operator |(B lhs, B rhs)
Console.WriteLine(lhs.ToString() + " | " + rhs.ToString());
return new B(lhs.val | rhs.val);
public override string ToString()
return val.ToString();
输出应该显示 && 在 || 之前首先被评估。
True & False
False | False
-----
False
为了更有趣,试试 result = t || t && f 看看短路会发生什么。
【讨论】:
短路与表达式结果无关。我们能克服它吗?以上是关于C# 条件 AND (&&) OR (||) 优先级的主要内容,如果未能解决你的问题,请参考以下文章