通过ms官网https://msdn.microsoft.com/zh-cn/library/ms173145.aspx得知&&优先级高于||,但是实际例子中因为存在“短路”计算,无法得知&&比||高,不仅如此,好像所有例子都可以看成&&和||优先级一样!
比如:true || true && false=true,如果没有“短路”计算,正好说明是true && false先结合,然后再和true进行||运算,但是有了“短路”计算,计算到第一个true后,就直接不计算后面了,所以不能说明&&优先级高,故有没有办法证明呢?
MSDN这文章看不出“&&优先级高于||”。
DOCIN的文章作者可能搞错了。
你主要是搞错了“短路计算”的意思。
两个公式你计算一下,理解短路计算的含义
true || true && false; result:true
false && true || true; result:true
@爱编程的大叔:
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:
true || true && false; result:true
false && true || true; result:true
我们先不管短路计算这事。
如果不分优先级
第一式应该是 true || true && false = true && flase =false
第二式应该是 false && true || true = false || true =true
你说是吗?
@爱编程的大叔: 如果不分等级,第二式是对的,第一式如果没有短路也是对的。
但第一式,如果有了短路,是否就不管||之后的部分了?
@风筝blog: 短路不是凭空出现的,是逻辑结果。
这么说吧,短路计算是在判断完优先级后才进行的,这是可以合理推断出来的。
短路计算仅用于两个结果的判断
A || B 如果A=true, B是啥都无所谓了。
A && B 如果A=false, B是啥都无所谓了。
只要多于两项,编译器先得判断优先级,然后进行短路逻辑。
如果是
A || B ++ C -- D 假设++, -- 的优先级大于或者小于||, 你理解的短路计算是错误的。
短路计算一定要先让优先级判断过后才能进行。
@爱编程的大叔:
谢谢你这么耐心,的确短路计算一定要先让优先级判断过后才能进行,否则短路会影响最后结果,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: Show(2) || GetValue(++i) > 2
这个顺序是这样的
==> Show(2) || (GetValue(++i)>2) 这步是优先级处理。
==> True || Something
==> True (short circut)
优先级处理并不代表运行,而是处理,你可以理解为加括号。
如果你知道LINQ,知道表达式树,知道Lazy loading,应该能够大致理解这个意思吧。
表示说你挺好学,并且会动手实践,这个不容易,好习惯要坚持。
@爱编程的大叔: 谢谢,我大概明白了,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。
再次谢谢@爱编程的大叔:耐心的解答!
你再仔细看看 MSDN,哪里说了“&&优先级高于||”?
你好,感谢你回复该问题。
我看其他的资料,比如:http://www.docin.com/p-428596985.html 中的运算符优先级都是说&& 比 || 高。你能否找出文献或者资料或者例子来说明他们俩的优先级相等?
@风筝blog: MSDN没有说&&比||优先级高。
不能因为有人造谣你杀人,然后要求你找证据说明你没杀人吧?
@爱编程的大叔: https://msdn.microsoft.com/zh-cn/library/6a71f45d 这里说了同组的是同优先级的,但是&& 在 || 之上。
@风筝blog: 你把你的表达式中的 true 和 false 都换成返回 true 或 false 的方法,然后观察方法的调用顺序。
@风筝blog: 你这么理解短路计算是错误的,如果"true || true && false"的结果是True说明是先&&再||,
如果"true || true && false"结果是false,则说明是先||再&&。
@Launcher:
换成函数调用:
var flag = Show(0) || Show(1) && Show(2);
static bool Show(int i)
{
Console.WriteLine(i.ToString());
return i % 2 == 0;
}
输出:0
@Launcher: 刚才写错了,调用为:var flag = Show(0) || Show(2) && Show(1);
不过输出也是:0
@风筝blog: Laucher不是要你看结果,是要你单步看先进哪个过程。埃。
@爱编程的大叔: 如果先执行了Show(2)和Show(1),会有输出的,而结果只输出0,所以说明没有执行||后面的部分。
@风筝blog: 你应该让短路计算去死。
var flag = Show(1) || Show(2) && Show(0);
这样看看就知道了。
@爱编程的大叔: 这样的话是false||true&&true,没有了短路,所有的都会执行,输出:
1
2
0
结果是true,可这没有说明&&和||的优先级。
@风筝blog: && 优先级确实高于 || ,这两个运算符源自于 & 和 |,是它俩的条件版本(& 优先级高于 |),你把 true || true && false 表达式改为这样:true | true & false,那么你应该就能理解了。你也可以比较这两个表达式的汇编代码,也能看出最终的执行逻辑。
我们再来看这个表达式:true || true && false,根据优先级定义,该表达式可以表示为:true || (true && false),我们将 (true && false) 定义为一个变量 y,那么原表达式简化下为 true || y,现在运用“短路计算”规则,因为左边的表达式值已经是 true,所以就不计算右边的表达式了。
@Launcher: 谢谢解答,是自己对短路计算理解不清,导致钻了牛角尖。
不知道用什么工具可以查看.exe的汇编代码?有相关的资料吗?
@风筝blog: 用 VS 调试时,转到汇编就行。
什么时候这2个逻辑运算符优先级不一样了?
https://msdn.microsoft.com/zh-cn/library/6a71f45d 这里说了同组的是同优先级的,但是&& 在 || 之上。
@风筝blog: 请问“true || true && false”这个的结果是?
@爱编程的大叔: 结果是true。
@风筝blog: 短路计算是说
Test1||Test2,如果Test1已经知道是True,则无需计算Test2。
所以true || true && false 结果是True已经可以证明&&优先于||了。
说明这个公式是这样的 true || (true && false)
如果你还是不信,还有一个公式可以验证
false && true || true
看看结果如何。
@爱编程的大叔: 不对,只能证明&&的优先级不低于||,但不能证明&&优先级高于||,总感觉这两个优先级其实相等,所有的表达式值都不会有所改变。
@风筝blog: 错,可以证明&&先运行了。
@爱编程的大叔: 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)是否相同?所以,这样无法证明&&比||优先级高。
@爱编程的大叔: true || true && false 假设&&与||优先级相等,是否结果也是true?而且不会运行后面的部分?
@风筝blog: 你得理解为啥短路。
我学C的时候,都说他俩优先级一样啊,没有谁高谁低啊
https://msdn.microsoft.com/zh-cn/library/6a71f45d
C++、C#、java里面都有的。
true || ( true && false) :true
(true || true) && false:false
这就已经证明了。如果 && 优先级不比 || 高,结果不同。
谢谢解答,你说的对,现在已经明白了。
一方面佩服你们 刨根问底的 精神,一方面 一个括号就可以 解决的问题。。。。