问题:if ( conditionA && conditionB ) 和 if ( conditionA || conditionB ),是先判断conditionA还是conditionB ?跟编译器有没有关系?
答:是先判断条件A,再判断条件B。C语言是短路求值的,都是先判断第一个表达式,如果能预先求出表达式结果,后面的判断就不会执行了。
// //如此说来 (exp1 ¦ ¦ exp2 && exp3)和(exp2 && exp3 ¦ ¦exp1)会有不同的结果,这也不符合生活习惯呀。这难道是“++副作用” //=================================== //你举的两个运算的含义分别如下: //1) //(exp1 ¦¦ exp2 && exp3) //==> //(exp1 ¦¦ (exp2 && exp3)) //==> //exp1 ? 1 : (exp2 && exp3) // //2) //(exp2 && exp3 ¦ ¦exp1) //==> //((exp2 && exp3) ¦ ¦exp1) //==> //(exp2 && exp3) ? 1 : exp1 // //由此可以看出,这是不同的运算过程,当然很有可能产生不同结果 // //至于你说到的矛盾,并不存在,原因如下: //&& 的优先权高于 || ,指的是数学中的结合律 //比如: 2 * 3 + 4 * 5 = (2 * 3) + (4 * 5) = 6 + 20 = 26 //但是因为计算机中的计算是一步步来的,所以计算过程可能是 //2 * 3 + 4 * 5 = (2 * 3) + (4 * 5) = 6 + (4 * 5) = 6 + 20 = 26 //(方式1: 先计算运算符左边的表达式,这个比较符合我们的习惯) //但也有可能是 //2 * 3 + 4 * 5 = (2 * 3) + (4 * 5) = (2 * 3) + 20 = 6 + 20 = 26 //(方式2: 先计算运算符右边的表达式) // //但是我们的C语言中,具体采取的是哪种方式呢? //如果我没记错的话,很多运算的计算次序都没有规定死,是由编译器(比如VC++, tc是不同的编译器)的实现者自己选择的 //即先算左边,还是先算右边,并不确定 // //然后让我们回到 _逻辑短路原则_ 这个话题 //_逻辑短路原则_ 恰恰就是对 逻辑运算过程 计算次序的一个规定,规定:先计算运算符左边的表达式 //那么,假设有一个运算 //T && T || F && T //由运算优先级!,有 //(T && T) || (F && T) //这时面临一个选择,先计算 || 左边还是右边? //参考 _逻辑短路原则_,先计算左边 (T && T) => T //从而有 //T || (F && T) //再次参考 _逻辑短路原则_ //因为运算符是 || ,"或"运算,此时由左边的 T 即可确定整个运算式的值, //那么编译器判断计算可以结束,右边的(F && T)从而被掠过