C#条件AND(&&)或(||)优先


77

我们一直在工作中遇到不必要的编码参数。今天,我问条件AND(&&)或OR(||)是否具有更高的优先级。我的一位同事坚持认为他们的优先级相同,我对此表示怀疑,因此我进行了查找。

根据MSDN,AND(&&)的优先级高于OR(||)。但是,您可以向一个持怀疑态度的同事证明吗?

http://msdn.microsoft.com/zh-CN/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(||)?如果您的答案无关紧要,那么为什么要用这种语言来构建它呢?


18
语言中就是这样,因为他们必须做出决定。就我个人而言,我不在乎哪个优先。我会使用括号确保获得期望的结果。这与为什么要做什么无关。这是关于在数周,数月或数年后返回代码时能够弄清楚代码在做什么。
杰夫·西弗

25
@杰夫:那是不正确的。这个决定有数学基础-称为布尔代数
EFraim

4
@TheSteve:短路不影响表达式结果。它仅影响副作用。
EFraim

8
您甚至必须考虑这一事实,这意味着您不应该依赖下一个知道的人,如果存在一个问题,办公室中的任何人都可能需要花3秒钟来思考,然后花费0.5秒钟来添加a(and a)
Bill K

34
让我看看我是否已经明白了。您的同事对语言有一种信念。该信念与规范和实现都矛盾。您的主张与规范和实施一致。那么,为什么您要尝试构造一个证明呢?举证责任在于拥有疯狂信念的人,而不是拥有明智信念的人。我不会再为此浪费时间了;如果他们想花时间尝试证明错误,那就让他们吧。
埃里克·利珀特

Answers:


116

将第一个false更改为true。我知道拥有(true || true)似乎很愚蠢,但这证明了您的意思。

bool result = true || true && false;   // --> true 
     result = (true || true) && false; // --> false
     result = true || (true && false); // --> true

13
仅当知道布尔表达式的结果时,才发生短路。短路不能更改布尔表达式的结果。
Segfault上尉,09年

5
@James,不,不会。.如果|| 具有更高的优先级,则该表达式将等效于(true || true)&& false => False,不是true,因为在计算{true ||之后 true),则剩下的将是true && false,这不会造成短路
Charles Bretana 09年

6
@James,不,如果|| 具有更高优先级的clr会将其评估为(true或true)&& false。所以首先要评估(true || true)。在该表达式内,是的,发生短路是因为对于OR表达式,如果第一部分为true,则无需评估第二部分。因此,这是正确的。现在我们有对与错。对于&&操作,仅当第一部分为FALSE时才发生短路,而在这种情况下则不会,因此A和&B的两个部分都必须为真,才能使A && B评估为真。因此,它对两个部分都进行了评估,并
得出

14
我们能停止所有这些废话吗,似乎在重复自己的恶作剧?!与我重复:短路不会改变结果。短路仅在结果已知时适用。简短说明副作用
EFraim

9
@comecme这不是短路的结果,而是改变操作顺序的结果。&运算符的优先级高于|运算符。运算符,因此第一个表达式的行为类似于true | (false & false)。这将评估为真,因为false & false = false,然后false | true = true。但是,| 运算符的优先级高于&&运算符,因此第二个表达式的行为类似于(true | false) && false。这将评估为false,因为true | false = true,然后true && false = false
Abion47年

11

如果您真的想吓到他,请尝试:

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)和然后该结果被&&编有false到产量false

我并不是要显示评估的顺序,只是事实是|,通常在正常情况下不是评估时间的正确的一半:)


1
一种。为什么混合使用布尔运算符和按位运算符?b。您为什么坚持要打印它?评估顺序与它有什么关系?
EFraim

2
回复:仍然是二进制。只是对于bool而言,它可以执行所需的操作-就像在C ++中一样。为澄清起见,MS将其记录为bool的逻辑。但是恕我直言,它只是使水变得浑浊。
EFraim

1
这将是一个有趣的恶作剧。:)
詹姆斯

1
因此,如果更改|||并保留&&,则表达式的结果从true变为false?因此,您通常可以|与一起使用&,或||与一起使用&&
comecme

6

这不会为您带来追寻吗?也许我想念一些东西...

bool result = true || false && false;

这区分了优先级较高的&&和||。具有较高的优先级,但不区分|| 具有较高的优先级,并且&&和|| 具有相同的优先级。请记住,如果运算符的优先级相等,则它们只是从左到右求值。
Tyler McHenry,2009年

1
我应该说,尽管这确实可以作为C#的证明(或实际上是任何普通语言),因为您得到的实际结果是明确的。这不是算出相对优先级的通用方法,以防万一您遇到了与布尔代数有目的矛盾的深奥语言。
泰勒·麦克亨利

5

您不是用代码而是逻辑来证明这一点。AND是布尔乘法,而OR是布尔加法。现在,哪个优先级更高?


10
在某些语言中,没有人会这样做(例如Smalltalk)。类比可能是骗人的。
帕维尔·米纳夫

11
我不了解另一个拒绝投票的人,但拒绝投票,因为这与问题无关。碰巧是匹配的……但是任何人都可以设计一种Foo#语言,而事实并非如此。您的“逻辑证明”将如何工作?它可能解释了为什么选择此优先级的原因,但是它并不能帮助确定我已安装的编译器实际上就是这种方式。
Roman Starkov 2011年

2
@romkyns:它与语言有关。C和C ++的规则源自代数定律。这就是为什么+的优先级小于*的原因。您可以争辩所有您想要的,但您既错又令人讨厌。您的编译器根据语言规范运行,并且该语言规范基于代数,QED
EFraim

3
QED?您知道证明某事意味着什么吗?该语言可能旨在遵循代数定律,但是您如何证明在实现此意图与大量工程工作之间,没有人搞砸,偶然违反它或在实施优先规则时误读了规范?(不太可能,但并非不可能)
Roman Starkov

3
我认为您提出的观点是正确的,只是它不符合“证明”的条件,其中证明比仅解释语言设计师决定做事的方式和原因更为严格。“他们基于代数,因此它的确像代数一样工作”并不是严格的证明(实际上说这种方式在逻辑上是无效的)。
Dave Cousineau

1

假|| 真实&&真实

收益率:是

假&&真|| 真正

收益率:是


无论您以何种顺序执行操作,第一条语句都将返回true。第二条语句仅在||时返回false。首先评估。因为它确实返回true,所以首先对&&求值,或者优先级相同,并且从左到右求值。true || true && false仅在首先对&&求值的情况下,第三个语句(也返回true)才可以为true。
CodeHxr

-5

当布尔表达式短路时,您不能仅显示最终结果。这是解决您问题的摘要。

它依赖于实现&和| 如MSDN 7.11中所述,&&和||使用的运算符

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,看看短路会发生什么。


6
短路与表达式结果无关。我们可以克服吗?
EFraim
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.