首页 新闻 会员 周边

C#中如何证明&&比||优先级高?

0
悬赏园豆:50 [已解决问题] 解决于 2015-03-03 12:30

通过ms官网https://msdn.microsoft.com/zh-cn/library/ms173145.aspx得知&&优先级高于||,但是实际例子中因为存在“短路”计算,无法得知&&比||高,不仅如此,好像所有例子都可以看成&&和||优先级一样!

比如:true || true && false=true,如果没有“短路”计算,正好说明是true && false先结合,然后再和true进行||运算,但是有了“短路”计算,计算到第一个true后,就直接不计算后面了,所以不能说明&&优先级高,故有没有办法证明呢?

风筝blog的主页 风筝blog | 初学一级 | 园豆:76
提问于:2015-03-02 15:01
< >
分享
最佳答案
0

MSDN这文章看不出“&&优先级高于||”。

DOCIN的文章作者可能搞错了。

收获园豆:30
爱编程的大叔 | 高人七级 |园豆:30839 | 2015-03-02 15:44

你主要是搞错了“短路计算”的意思。

两个公式你计算一下,理解短路计算的含义

true || true && false;   result:true

false && true || true; result:true

爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:30

@爱编程的大叔: 

var flag = Show(0) || Show(2) && Show(1);

这句用IL反编译后是:

// Method begins at RVA 0x2050
    // Code size 101 (0x65)
    .maxstack 1
    .entrypoint
    .locals init (
        [0] bool flag,
        [1] bool flag2,
        [2] bool flag3
    )

    IL_0000: nop
    IL_0001: ldc.i4.0
    IL_0002: call bool ConsoleApplication5.Program::Show(int32)
    IL_0007: brtrue.s IL_001d

    IL_0009: ldc.i4.2
    IL_000a: call bool ConsoleApplication5.Program::Show(int32)
    IL_000f: brfalse.s IL_0019

    IL_0011: ldc.i4.1
    IL_0012: call bool ConsoleApplication5.Program::Show(int32)
    IL_0017: br.s IL_001a

    IL_0019: ldc.i4.0

    IL_001a: nop
    IL_001b: br.s IL_001e

    IL_001d: ldc.i4.1

看不出来&&有什么特殊的。

风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:45

@风筝blog: 

true || true && false;   result:true

false && true || true; result:true

我们先不管短路计算这事。

如果不分优先级

第一式应该是 true || true && false = true && flase =false

第二式应该是 false && true || true = false || true =true

你说是吗?

爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:51

@爱编程的大叔: 如果不分等级,第二式是对的,第一式如果没有短路也是对的。

但第一式,如果有了短路,是否就不管||之后的部分了?

风筝blog | 园豆:76 (初学一级) | 2015-03-02 17:09

@风筝blog: 短路不是凭空出现的,是逻辑结果。

 

这么说吧,短路计算是在判断完优先级后才进行的,这是可以合理推断出来的。

短路计算仅用于两个结果的判断

A || B   如果A=true, B是啥都无所谓了。

A && B 如果A=false, B是啥都无所谓了。

只要多于两项,编译器先得判断优先级,然后进行短路逻辑。

 

如果是

A || B ++ C -- D 假设++, -- 的优先级大于或者小于||, 你理解的短路计算是错误的。

短路计算一定要先让优先级判断过后才能进行。

爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 17:17

@爱编程的大叔: 

谢谢你这么耐心,的确短路计算一定要先让优先级判断过后才能进行,否则短路会影响最后结果,true || true && false=true,之所以会被短路,是把true && false作为了一个整体来看待,但true || true || true=true,是否后面两个true也被作为了一个整体看待?

关于”A || B ++ C -- D 假设++, -- 的优先级大于或者小于||, 你理解的短路计算是错误的。“

这个例子,我测试了下:

int i = 0;
var flag2 = Show(2) || GetValue(++i) > 2;
Console.WriteLine(i);
Console.ReadKey();

static bool Show(int i)
{
Console.WriteLine(i.ToString());
return i % 2 == 0;
}

static int GetValue(int i)
{
Console.WriteLine(string.Format("GetValue({0})", i));
return 3;
}

输出:

2

0

并没有执行:GetValue(++i) > 2; 而">"优先级比”||“要高的,所以”短路“和优先级没关系的。

风筝blog | 园豆:76 (初学一级) | 2015-03-02 18:18

@风筝blog: Show(2) || GetValue(++i) > 2

这个顺序是这样的

==> Show(2) || (GetValue(++i)>2)   这步是优先级处理。

==> True || Something

==> True (short circut) 

 

优先级处理并不代表运行,而是处理,你可以理解为加括号。

 

如果你知道LINQ,知道表达式树,知道Lazy loading,应该能够大致理解这个意思吧。

表示说你挺好学,并且会动手实践,这个不容易,好习惯要坚持。

爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 20:28

@爱编程的大叔: 谢谢,我大概明白了,var flag = true || true && false;,按照你说的的确应该是如下处理步骤,假设没有短路:

flag、true、true、false、&&、||、=

就像(var a = b + c * d; a、b、c、d、*、+、=,参见:https://msdn.microsoft.com/zh-cn/library/ms173145.aspx)一样。

而由于||的短路特点,实际应该是这样:

1、判断优先级

就像你说的,表达式可以看成:true || (true && false);

2、短路计算

看成:true || something

3、得到结果

true

而如果||的优先级大于或者等于&&,结果就会是false。

再次谢谢@爱编程的大叔:耐心的解答!

风筝blog | 园豆:76 (初学一级) | 2015-03-03 10:30
其他回答(5)
0

你再仔细看看 MSDN,哪里说了“&&优先级高于||”?

收获园豆:20
Launcher | 园豆:45045 (高人七级) | 2015-03-02 15:10

你好,感谢你回复该问题。

我看其他的资料,比如:http://www.docin.com/p-428596985.html 中的运算符优先级都是说&& 比 || 高。你能否找出文献或者资料或者例子来说明他们俩的优先级相等?

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 15:19

@风筝blog: MSDN没有说&&比||优先级高。

不能因为有人造谣你杀人,然后要求你找证据说明你没杀人吧?

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 15:58

@爱编程的大叔: https://msdn.microsoft.com/zh-cn/library/6a71f45d 这里说了同组的是同优先级的,但是&& 在 || 之上。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:04

@风筝blog: 你把你的表达式中的 true 和 false 都换成返回 true 或 false 的方法,然后观察方法的调用顺序。

支持(0) 反对(0) Launcher | 园豆:45045 (高人七级) | 2015-03-02 16:10

@风筝blog: 你这么理解短路计算是错误的,如果"true || true && false"的结果是True说明是先&&再||,

如果"true || true && false"结果是false,则说明是先||再&&。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:16

@Launcher: 

换成函数调用:

var flag = Show(0) || Show(1) && Show(2);

static bool Show(int i)
{
Console.WriteLine(i.ToString());
return i % 2 == 0;
}

输出:0

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:17

@Launcher: 刚才写错了,调用为:var flag = Show(0) || Show(2) && Show(1);

不过输出也是:0

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:18

@风筝blog: Laucher不是要你看结果,是要你单步看先进哪个过程。埃。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:35

@爱编程的大叔: 如果先执行了Show(2)和Show(1),会有输出的,而结果只输出0,所以说明没有执行||后面的部分。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:38

@风筝blog: 你应该让短路计算去死。

var flag = Show(1) || Show(2) && Show(0);

这样看看就知道了。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:39

@爱编程的大叔: 这样的话是false||true&&true,没有了短路,所有的都会执行,输出:

1

2

0

结果是true,可这没有说明&&和||的优先级。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:43

@风筝blog: && 优先级确实高于 || ,这两个运算符源自于 & 和 |,是它俩的条件版本(& 优先级高于 |),你把 true || true && false 表达式改为这样:true | true & false,那么你应该就能理解了。你也可以比较这两个表达式的汇编代码,也能看出最终的执行逻辑。

我们再来看这个表达式:true || true && false,根据优先级定义,该表达式可以表示为:true || (true && false),我们将 (true && false) 定义为一个变量 y,那么原表达式简化下为 true || y,现在运用“短路计算”规则,因为左边的表达式值已经是 true,所以就不计算右边的表达式了。

支持(0) 反对(0) Launcher | 园豆:45045 (高人七级) | 2015-03-03 09:44

@Launcher: 谢谢解答,是自己对短路计算理解不清,导致钻了牛角尖。

不知道用什么工具可以查看.exe的汇编代码?有相关的资料吗?

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-03 10:32

@风筝blog: 用 VS 调试时,转到汇编就行。

支持(0) 反对(0) Launcher | 园豆:45045 (高人七级) | 2015-03-03 11:50
0

什么时候这2个逻辑运算符优先级不一样了?

吴瑞祥 | 园豆:29449 (高人七级) | 2015-03-02 16:01

 https://msdn.microsoft.com/zh-cn/library/6a71f45d 这里说了同组的是同优先级的,但是&& 在 || 之上。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:04

@风筝blog: 请问“true || true && false”这个的结果是?

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:11

@爱编程的大叔: 结果是true。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:17

@风筝blog: 短路计算是说

Test1||Test2,如果Test1已经知道是True,则无需计算Test2。

所以true || true && false 结果是True已经可以证明&&优先于||了。

说明这个公式是这样的 true || (true && false)

如果你还是不信,还有一个公式可以验证

false && true || true 

看看结果如何。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:21

@爱编程的大叔: 不对,只能证明&&的优先级不低于||,但不能证明&&优先级高于||,总感觉这两个优先级其实相等,所有的表达式值都不会有所改变。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:25

@风筝blog: 错,可以证明&&先运行了。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 16:32

@爱编程的大叔: false && true || true 结果是true,我仔细想了下,

测试:var flag = Show(0) || Show(5) || Show(2) && Show(1);

结果还是输出:0,其实上面也可写成:Show(0) || (Show(5) || Show(2) && Show(1));,这样和你所有的true || (true && false)是否相同?所以,这样无法证明&&比||优先级高。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:33

@爱编程的大叔: true || true && false 假设&&与||优先级相等,是否结果也是true?而且不会运行后面的部分?

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 16:35

@风筝blog: 你得理解为啥短路。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2015-03-02 17:15
0

我学C的时候,都说他俩优先级一样啊,没有谁高谁低啊

代码小兵的成长 | 园豆:303 (菜鸟二级) | 2015-03-02 17:23

https://msdn.microsoft.com/zh-cn/library/6a71f45d

C++、C#、java里面都有的。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-02 18:22
0

true || ( true && false) :true

(true || true) && false:false

 

这就已经证明了。如果 && 优先级不比 || 高,结果不同。

巛熊猫人灬 | 园豆:225 (菜鸟二级) | 2015-03-03 00:10

谢谢解答,你说的对,现在已经明白了。

支持(0) 反对(0) 风筝blog | 园豆:76 (初学一级) | 2015-03-03 10:31
0

一方面佩服你们 刨根问底的 精神,一方面 一个括号就可以 解决的问题。。。。

数据之巅 | 园豆:309 (菜鸟二级) | 2015-03-04 10:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册