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 (||) 优先级的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别