Boole operatörlerinde farklılıklar: & vs && ve | vs ||


Yanıtlar:


134

Bunlar bitsel AND ve bitsel OR operatörleridir.

int a = 6; // 110
int b = 4; // 100

// Bitwise AND    

int c = a & b;
//   110
// & 100
// -----
//   100

// Bitwise OR

int d = a | b;
//   110
// | 100
// -----
//   110

System.out.println(c); // 4
System.out.println(d); // 6

Carlos'a, Java Dil Spesifikasyonunda ( 15.22.1 , 15.22.2 ) operatörün girişlerine göre farklı davranışlarıyla ilgili uygun bölümü işaret ettiği için teşekkür ederiz .

Aslında, her iki giriş de boole olduğunda, operatörler Boolean Mantıksal Operatörler olarak kabul edilir ve kısa devre yapmamaları dışında Koşullu-Ve ( &&) ve Koşullu-Veya ( ||) operatörlerine benzer davranırlar, bu nedenle aşağıdakiler güvenliyken :

if((a != null) && (a.something == 3)){
}

Bu değil:

if((a != null) & (a.something == 3)){
}

"Kısa devre", operatörün tüm koşulları incelemesine gerek olmadığı anlamına gelir. Yukarıdaki örneklerde, &&ikinci koşulu yalnızca aolmadığında inceleyecektir null(aksi takdirde tüm ifade yanlış döndürür ve aşağıdaki koşulları incelemek yine de tartışılır), bu nedenle ifadesi a.somethingbir istisna oluşturmaz veya "güvenli" olarak kabul edilir . "

&Operatör her zaman yukarıdaki örneklerde, madde, her durum inceler a.somethingzaman değerlendirilebilir aaslında olan nullbir özel durum, bir değer.


1
açıklığa kavuşturmak istedim .. & sadece HER İKİSİ 1 ise 1 döndürecektir? Yani 101 & 001, 001 mi olur? Sağ?
gideon

@giddy @Jonathon - Bu durumu daha iyi göstermek için değerlerimi güncelledim.
Justin Niessner

eksik: bunlar aynı zamanda LOGICAL operatörleridir (boole'lar için).
user85421

1
@ Carlos- Hayır. Hala bitsel operatörler. Kısa devre yapmayan mantıksal operatörlerle aynı şekilde davranırlar. Bir fark var.
Justin Niessner

4
ve kısa devre yapmayan mantıksal operatörler nelerdir? Operatörleri & ve | (OP tarafından sorulan) "Tamsayı Bitsel Operatörler" (JLS 15.22.1) ve "Boolean Mantıksal Operatörler" (JLS 15.22.2) 'dir. Veya Java Dil Belirtimi bu konuda yanlış mı?
user85421

108

Sanırım her iki operatörün mantıksal anlamından bahsediyorsunuz, burada bir özgeçmişiniz var:

boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE

Kısa devre değerlendirmesi , minimal değerlendirme veya McCarthy değerlendirmesi (John McCarthy'den sonra), ikinci argümanın yalnızca ilk argümanın değerini belirlemek için yeterli olmaması durumunda çalıştırıldığı veya değerlendirildiği bazı programlama dillerinde bazı Boole operatörlerinin anlambilimidir. ifade: AND işlevinin ilk bağımsız değişkeni yanlış olarak değerlendirildiğinde, genel değer yanlış olmalıdır; VEYA işlevinin ilk bağımsız değişkeni doğru olarak değerlendirildiğinde, genel değer doğru olmalıdır.

Güvenli Değil , operatörün her zaman cümledeki her koşulu incelediği anlamına gelir, bu nedenle yukarıdaki örneklerde, 1 / x, x, aslında, bir 0 değeri olduğunda, bir istisna oluşturduğunda değerlendirilebilir.


1
@Torres - Lütfen "kısa devre" ve "güvenli" i açıklayarak yanıtınızı genişletin. Ayrıca "dışlayıcı" veya "mantıksal değil" aynı zamanda "kısa devre yapmayan" mı? Ve neden "mantıksal mantıksal değil" yerine "mantıksal değil" deniyor? Ve "mantıksal DEĞİL" neden "mantıksal VE" ve "mantıksal VEYA" ile gruplandırılmıyor? İyi cevap ama çalışılması gerekiyor.
tfmontague

@tfmontague, kısa devrenin ne anlama geldiğini açıkladım (bu cevabı düzenleyerek) .. Düzenlememin "hakem tarafından incelenmesi" için bekliyorum.
Taslim Oseni

kısa devre yapmamanın "güvensiz" olanı nedir? kısa devre kullanmaktan daha güvenli olması gerekmez mi? btw: "Kısa devre" terimini gerçekten açıklamıyorsunuz. Bu, "kısa devre değil" durumunda tüm bölümlerin önce değerlendirildiği, ardından boole işleminin uygulandığı, kısa devrede ise değerlendirme durdurulduğu, ilk ifade koşulu sağladığında (a || b) gibi olmayacağı anlamına gelir. b'yi değerlendirin, eğer a doğruysa ve b ne olursa olsun veya işlemi doğru döndürür.
SCI

26

Burada pek çok cevap olduğunu biliyorum, ama hepsi biraz kafa karıştırıcı görünüyor. Java oracle çalışma kılavuzundan biraz araştırma yaptıktan sonra, ne zaman && veya & kullanacağıma dair üç farklı senaryo buldum. Üç senaryo mantıksal AND , bitsel AND ve boolean AND'dir .

Mantıksal AND: Mantıksal AND (diğer adıyla Koşullu AND) && operatörünü kullanır . Kısa devreli anlamı: eğer sol işlenen yanlışsa, o zaman sağ işlenen değerlendirilmeyecektir.
Misal:

int x = 0;
if (false && (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); // "0"

Yukarıdaki örnekte, x'in konsoluna yazdırılan değer 0 olacaktır, çünkü if ifadesindeki ilk işlenen yanlıştır, dolayısıyla java'nın hesaplamaya ihtiyacı yoktur (1 == ++ x) bu nedenle x hesaplanmayacaktır.

Bitsel AND: Bitsel AND & operatörünü kullanır . Değer üzerinde bit düzeyinde bir işlem yapmak için kullanılır. İkili sayılar üzerindeki işleme bakarak neler olup bittiğini görmek çok daha kolaydır, örn:

int a = 5;     //                    5 in binary is 0101
int b = 12;    //                   12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4

Örnekte görebileceğiniz gibi, 5 ve 12 sayılarının ikili gösterimleri sıralandığında, bitsel VE önceden oluşturulmuş bir ikili sayı yalnızca her iki sayıdaki aynı rakamın 1 olduğu bir ikili sayı üretecektir. Dolayısıyla 0101 & 1100 == 0100. Ondalık sayı 5 & 12 == 4'tür.

Boolean AND: Artık boole AND operatörü hem bitsel AND hem de mantıksal AND'ye benzer ve farklı davranır. Bunu, iki boole değeri (veya bit) arasında bit düzeyinde VE önceden oluşturduğunu düşünmek hoşuma gidiyor, bu nedenle & operatörünü kullanıyor . Boole değerleri, mantıksal bir ifadenin sonucu da olabilir.

Mantıksal AND'ye çok benzer şekilde doğru veya yanlış bir değer döndürür, ancak mantıksal AND'den farklı olarak kısa devre değildir. Bunun nedeni, bitsel AND'yi önceden oluşturması için hem sol hem de sağ işlenenlerin değerini bilmesi gerektiğidir. İşte bir eski:

int x = 0;
if (false & (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); //"1"

Şimdi, eğer ifade çalıştırıldığında, sol işlenen yanlış olsa bile ifade (1 == ++ x) çalıştırılacaktır. Dolayısıyla x için yazdırılan değer 1 olacaktır çünkü artmıştır.

Bu aynı zamanda Mantıksal VEYA (||), bitsel OR (|) ve boole OR (|) için de geçerlidir. Umarım bu bazı karışıklıkları giderir.


to preform that bitwise AND, it must know the value of both left and right operandsBu bana doğru gelmiyor. Bir yapmak için BITWISE AND, sol operand ise sonucu bulabilmek için sağ operandı bilmenize gerek yoktur FALSE. Açıkladığınız doğru ama en azından bana
Koray Tugay

7

&& ve || operatörleri kısa devre yapıyorlar, yani sol el ifadesinin değeri sonucu belirlemek için yeterliyse sağ el ifadelerini değerlendirmeyecekler.


7
- OP'ye zaten bildiklerini söylediği ve gerçekten sorduğu soruyu cevaplamadığı için.
Alnitak

5

& ve | && ve || ile aynı sonucu sağlar operatörler. Aradaki fark, her zaman ifadenin her iki tarafını da && ve || olarak değerlendirmeleridir. İlk koşulun sonucu belirlemek için yeterli olup olmadığını değerlendirmeyi bırakın.


1
Yanlış .... Çünkü &&her iki sonucu da değerlendirirken ||, sadece ilk koşul doğruysa geri döner.
Buhake Sindi

1
Huh? Sol taraf zaten doğru olarak değerlendirilirse, && yalnızca ifadenin sağ tarafını değerlendirir. Aksi takdirde, dolaylı olarak ilk yanlış olarak değerlendirmeyi bırakır, sonucun doğru olamayacağı anlamına gelir. Bkz. Jguru.com/faq/view.jsp?EID=16530
Brian Scott

1
( 2 & 4 )olarak değerlendirilirken false, olarak ( 2 && 4 )değerlendirilir true. Tam olarak nasıl aynı sonuç oluyor?
Piskvor

1
@Piskvor - Java'da değil! 2 & 4bir tamsayı ile sonuçlanır, boole değil (bu durumda sıfır). 2 && 4derlenmeyecek, && yalnızca boole'leri kabul edecek. Java, falsefalse
boolean ve ints'in

1
@BuhakeSindi Wrong. Çünkü &&sadece ikinci işleneni, birinci işlenen ise değerlendirir true.
Marquis of Lorne

2

Java'da, tek operatörler &, |, ^,! işlenenlere bağlıdır. Her iki işlenen de tamsa, bitsel işlem gerçekleştirilir. Her ikisi de boole ise, "mantıksal" bir işlem gerçekleştirilir.

Her iki işlenen de uyuşmazsa, bir derleme zamanı hatası atılır.

Çift operatörler &&, || tekil emsallerine benzer şekilde davranır, ancak her iki işlenen de koşullu ifadeler olmalıdır, örneğin:

eğer ((a <0) && (b <0)) {...} veya benzer şekilde, if ((a <0) || (b <0)) {...}

kaynak: java programlama dili 4th ed



1

Belki de bitsel AND ve bitsel OR operatörlerinin her zaman koşullu AND'den önce değerlendirildiğini ve aynı ifadede koşullu OR operatörlerinin kullanıldığını bilmek yararlı olabilir.

if ( (1>2) && (2>1) | true) // false!

1
değerlendirme sırası yerine operatör önceliğini mi kastediyorsunuz? Gerçek kodda kullanılan öncelik farkını görmemeyi tercih ederim. Bu amaçla bitsel operatörler yerine parantezler kullanın.
John Dvorak

1

&&; || mantıksal operatörler .... kısa devre

&; | mantıksal operatörlerdir .... Kısa devre olmayan

İfadelerde uygulama farklılıklarına geçme. Bitsel operatörler, sol tarafın sonucundan bağımsız olarak her iki tarafı da değerlendirir. Ancak, mantıksal operatörlerle ifadelerin değerlendirilmesi durumunda, sağ el ifadesinin değerlendirilmesi sol el durumuna bağlıdır.

Örneğin:

int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

Bu i = 26; j = 25, İlk koşul yanlış olduğu için, sonuç sağ taraf durumuna bakılmaksızın yine de yanlış olduğu için sağ taraf atlanır. (kısa devre)

int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

Ancak, bu i = 26; j = 26,


0

Boolean & operatörünü içeren bir ifade değerlendirilirse, her iki işlenen de değerlendirilir. Daha sonra işlenene & operatörü uygulanır.

&& operatörünü içeren bir ifade değerlendirildiğinde, ilk işlenen değerlendirilir. İlk işlenen yanlış olarak değerlendirilirse, ikinci işlenenin değerlendirmesi atlanır.

İlk işlenen bir true değeri döndürürse, ikinci işlenen değerlendirilir. İkinci işlenen bir true değeri döndürürse, o zaman && operatörü birinci ve ikinci işlenenlere uygulanır.

Benzer | ve ||.


0

Temel fark, olsa &çoğunlukla üzerinde ikilik işlemleri için kullanılır long, intya da bytenerede bir maske türü için kullanılabilir Eğer mantıksal yerine kullanırsanız, sonuçları bile farklılık gösterebilir&& .

Bazı senaryolarda fark daha belirgindir:

  1. Bazı ifadeleri değerlendirmek zaman alıcıdır
  2. İfadelerden birinin değerlendirilmesi, ancak bir önceki doğru ise yapılabilir.
  3. İfadelerin bazı yan etkileri var (kasıtlı olsun veya olmasın)

İlk nokta oldukça basittir, hataya neden olmaz, ancak daha fazla zaman alır. Bir koşullu ifadede birkaç farklı kontrolünüz varsa, daha ucuz olanları veya başarısız olma olasılığı daha yüksek olanları sola koyun.

İkinci nokta için şu örneğe bakın:

if ((a != null) & (a.isEmpty()))

Bu başarısız nullikinci ifade değerlendirmek bir üretir, NullPointerException. Mantıksal operatör &&tembeldir, eğer sol işlenen yanlışsa, sağ işlenen ne olursa olsun sonuç yanlıştır.

Üçüncü nokta için örnek - diyelim ki herhangi bir tetikleyici veya basamaksız DB kullanan bir uygulamamız var. Bir Bina nesnesini kaldırmadan önce, bir Departman nesnesinin binasını başka bir bina ile değiştirmeliyiz. Ayrıca işlem durumunun bir mantıksal değer olarak döndürüldüğünü de varsayalım (doğru = başarılı). Sonra:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))

Bu, her iki ifadeyi de değerlendirir ve böylelikle departman güncellemesi herhangi bir nedenle başarısız olsa bile bina kaldırmayı gerçekleştirir. İle &&amaçlandığı gibi çalışır ve ilk arızadan sonra durur.

Gelince a || b, eşdeğerdir , doğruysa !(!a && !b)durur a, daha fazla açıklamaya gerek yoktur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.