1. 程式人生 > >JAVA中&&和&、||和|(短路與和邏輯與、短路或和邏輯或)的區別

JAVA中&&和&、||和|(短路與和邏輯與、短路或和邏輯或)的區別

問題一:

JAVA中&&和&、||和|(短路與和邏輯與、短路或和邏輯或)的區別?


首先名稱是不同的
&&邏輯與  ||邏輯或  它們都是邏輯運算子
& 按位與  | 按位或  它們都是位運算子
if(a==1&&b==2) 這是說既要滿足a=1也要滿足b=2
if(a==1||b==2) 這是說或者滿足a=1或者要滿足b=2
而a&b或者a|b則是二進位制的與或運算
&同為1時為1,否則為0
|同為0時為0,否則為1
3&5則
 0011
&0101
 0001
等於1

3|5則
 0011
|0101
 0111
等於7


&&邏輯與 也叫做短路與 因為只要當前項為假,它就不往後判斷了,直接認為表示式為假
||邏輯或 也叫做短路或 因為只要當前項為真,它也不往後判斷了,直接認為表示式為真




問題二:

關於Java 中邏輯運算與位運算的區別(具體到解一道題)

題目出自Java2實用教程(第三版)(卻沒有解釋)

程式如下圖:

執行結果如下:

為什麼? x,y,a,b 不是都在IF語句裡都重新賦值了嗎?按道理全為真了,y也該是20了吧?(用程式驗證過了,的確是這個結果)

回答:

邏輯運算子執行的是短路求值
所謂短路,就是當參與運算的一個運算元已經足以推斷出這個表示式的值的時候,另外一個運算元(有可能是表示式)就不會 執行

比如:
static boolean f1() { System.out.println( "function f1 called." ); return true; }
static boolean f2() { System.out.println( "function f2 called." ); return false; }
if ( false && f1() ) {} // f1不會被呼叫
if ( true || f2() ){} // f2不會被呼叫

由於&& 要求它的參與操作的兩個運算元都是布林值真,才得真,所以只要得出其中一個為假,那麼另一部分的表示式就不會被求值(在上面的例子中是f1()不會被調 用)
同理由於||要求它的參與操作的兩個運算元只要其中之一為真,就得真,所以只要得出其中一個為真,那麼另一部分也不會被求值(在上面的例子中 是f2()不會被呼叫)

這就是邏輯操作符所謂的“短路求值”



位操作沒有這一特性,所以不管那邊的值是如 何,任何參與運算的表示式都會被執行求值,因此也就產生了你程式碼之中的結果了。

三、Java中邏輯運算短路的理解:

短路” 主要用於邏輯運算子中,即 “ !   && || "這三種運算子
短路 就是知如果左側的表示式能確定運算後的結果,則不再計算右側的表示式。
如(1>2)&&(2<3)   明明左側已經為假 了   ,我 不用計算右側我一定知道 此表達是為假,這樣 就好似物理中的電流,當某處短路時,電流直接從一條路通過,而不再管另一條路。

看個例子:

public class Logic{
public static void main(String[] args){

int a = 1;
int b = 1;
if(a<b&&b<a++){
System.out.println(a>b&true);
System.out.println(a);
System.out.println("this's in my control");
}
else{
System.out.println("that's impossible");
System.out.println(a);
}

}
}

此處由於a<b為假 ,所以 後面的b<a++不會執行
此處的結果為
that's impossible
1
若假設a的初值為0,此時a<b成立,這時就要計算後面的值了
結果應該為和上面一樣。


網上看見有人對   && 與 & 有點混淆,順便說說我的理解
本來 & 是個 位運算子
也就是主要用來 做二進位制運算的,如 010101&101010 = 000000

但它的特別之處 在於 它可以 進行 boolean值的運算
就像我上面寫的   a>b&true

其實我想這追根究地 在於 boolean 在記憶體中是用一位二進位制來表示的,故可以進行位運算
我們不能被表象所迷惑 ,認為這是邏輯運算 ,這樣理解就根本不存在討論短路的必要了。