Jaka jest różnica między | i || lub operatorzy?

300

Zawsze używałem ||(dwóch potoków) w wyrażeniach OR, zarówno w języku C #, jak i PHP. Sporadycznie widzę pojedynczą rurę używany: |. Jaka jest różnica między tymi dwoma zastosowaniami? Czy są jakieś zastrzeżenia przy stosowaniu jednego nad drugim, czy są one wymienne?

GloryFish
źródło

Odpowiedzi:

488

Podobnie jak operator &i &&podwójny operator jest operatorem zwarciowym.

Na przykład:

if(condition1 || condition2 || condition3)

Jeśli warunek 1 jest prawdziwy, warunek 2 i 3 NIE zostaną sprawdzone.

if(condition1 | condition2 | condition3)

Spowoduje to sprawdzenie warunków 2 i 3, nawet jeśli 1 jest już prawdą. Ponieważ twoje warunki mogą być dość drogimi funkcjami, możesz uzyskać dobry wzrost wydajności, korzystając z nich.

Istnieje jedno duże zastrzeżenie, NullReferences lub podobne problemy. Na przykład:

if(class != null && class.someVar < 20)

Jeśli klasa ma wartość NULL, instrukcja if zatrzyma się po wartości class != nullfalse. Jeśli użyjesz tylko &, spróbuje to sprawdzić, class.someVara otrzymasz fajny NullReferenceException. Z Or-Operatorem może to nie być pułapka, ponieważ jest mało prawdopodobne, aby wyzwolić coś złego, ale należy o tym pamiętać.

Nikt jednak nigdy nie korzysta z pojedynczego operatora &ani |operatorów, chyba że masz projekt, w którym każdy warunek jest funkcją, którą MUSI wykonać. Brzmi jak zapach designerski, ale czasami (rzadko) jest to czysty sposób na robienie różnych rzeczy. &Operator ma „uruchomić te 3 funkcje, a jeśli jeden z nich zwraca false, należy wykonać jeszcze blok”, a |nie „tylko uruchomić innego bloku, jeśli fałszywe żaden powrót” - mogą być przydatne, ale jak mówi, często jest to projekt zapach.

Istnieje jednak drugie użycie operatora |i &: Operacje bitowe .

Michael Stum
źródło
9
Tak, nie wierzyłem, dopóki nie stworzyłem aplikacji na konsolę - ale dobry Boże! Dlaczego mieliby dać ci linę do powieszenia się! Nienawidziłem tego w VB.NET - słowach kluczowych OrElse i AndAlso!
Jarrod Dixon
24
Nauczenie ludzi używania &i |jako operatorów warunkowych jest włamaniem i wpędzi ich w kłopoty, jeśli kiedykolwiek będą potrzebować używać C / C ++: 1 && 2prawda jest prawdą, a 1 & 2fałsz.
BlueRaja - Danny Pflughoeft
47
To nie jest hack, jest oficjalnie określony dla C # w rozdziale 7.10.3 Logiczne operatory logiczne: „Wynik x | y jest prawdziwy, jeśli x lub y jest prawdziwy. W przeciwnym razie wynik jest fałszywy.” Zobacz także Sekcja 7.11 Warunkowe operatory logiczne: „Operacja x || y odpowiada operacji x | y, z tym że y jest obliczane tylko wtedy, gdy x jest fałszem.” co dodatkowo „legalizuje” | jako operator warunkowy. A ludzie, którzy używają C / C ++ i tak będą mieli kłopoty, jeśli tylko na ślepo założą, że rzeczy działają równo. Jak powiedziano: za pomocą | w instrukcji if jest zapachem projektu, ale operacja jest całkowicie legalna.
Michael Stum
9
Nigdy nie powiedziałem, że to nie jest legalne, po prostu to hack, którym jest (używasz, &aby przekazać znaczenie inne niż to, co prawie zawsze oznacza: bitowe-i) .
BlueRaja - Danny Pflughoeft
15
@ BlueRaja-DannyPflughoeft Nazywanie udokumentowanej funkcji włamaniem, gdy dokumentacja mówi, że była przeznaczona do użycia, jest jak powiedzenie użycia przełącznika „włamanie na inny sposób”. Jest to narzędzie w skrzynce narzędziowej, być może rzadko używane narzędzie specjalne, ale mimo to narzędzie.
Gent
80

|| jest logicznym operatorem OR. Wygląda na to, że właściwie wiesz, co to jest. Jest używany w instrukcjach warunkowych, takich jak if, while itp.

condition1 || condition2

Sprawdza się, czy spełniony jest warunek 1 LUB warunek 2.

| jest bitowym operatorem OR. Służy do obsługi dwóch liczb. Patrzysz na każdy bit każdej liczby osobno, a jeśli jeden z bitów ma wartość 1 w co najmniej jednej z liczb, to bit wynikowy również będzie równy 1. Oto kilka przykładów:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Mam nadzieję, że to ma sens.

Tak więc, aby odpowiedzieć na dwa ostatnie pytania, nie powiedziałbym, że istnieją jakieś zastrzeżenia oprócz „znać różnicę między dwoma operatorami”. Nie są wymienne, ponieważ robią dwie zupełnie różne rzeczy.

Evan Shaw
źródło
Pomogło mi to zrozumieć, w jaki sposób ktoś używał bitowego operatora OR do scalania filtrów w sterowniku Mongodb C #. gist.github.com/a3dho3yn/…
Donny V.
30

Jeden jest „bitowy lub”.

10011b | 01000b => 11011b

Drugi to logika lub.

prawda lub fałsz => prawda

nsanders
źródło
2
|może być stosowany również na booltypach bez zwarć.
juharr
14

Dobre pytanie. Te dwa operatory działają tak samo w PHP i C #.

|jest nieco bitowe LUB. Porówna dwie wartości według ich bitów. Np. 1101 | 0010 = 1111. Jest to niezwykle przydatne podczas korzystania z opcji bitów. Np. Odczyt = 01 (0X01) Zapis = 10 (0X02) Odczyt-zapis = 11 (0X03). Jednym przydatnym przykładem może być otwieranie plików. Prostym przykładem byłoby:

File.Open(FileAccess.Read | FileAccess.Write);  //Gives read/write access to the file

||jest logicznym OR. W ten sposób większość ludzi myśli o OR i porównuje dwie wartości na podstawie ich prawdy. Np. Idę do sklepu lub pójdę do centrum handlowego. Ten jest najczęściej używany w kodzie. Na przykład:

if(Name == "Admin" || Name == "Developer") { //allow access } //checks if name equals Admin OR Name equals Developer

Zasób PHP: http://us3.php.net/language.operators.bitwise

C # Resources: http://msdn.microsoft.com/en-us/library/kxszd0kx(VS.71).aspx

http://msdn.microsoft.com/en-us/library/6373h346(VS.71).aspx

Trevor Abell
źródło
4
FWIW, technicznie rzecz biorąc, w języku C # |jest logiczne lub stosowane w przypadku wartości logicznych . Jak podaje linkowane odniesienie. W praktyce wynik końcowy jest taki sam, jakby był operatorem bitowym, ponieważ wartości bitowe truei falsesą takie, że bitowa lub ich wartość daje dokładnie taki sam wynik, jak logiczny lub robi. To jest (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve,
4

Prosty przykład w java

public class Driver {

  static int x;
  static int y;

public static void main(String[] args) 
throws Exception {

System.out.println("using double pipe");
    if(setX() || setY())
        {System.out.println("x = "+x);
        System.out.println("y = "+y);
        }



System.out.println("using single pipe");
if(setX() | setY())
    {System.out.println("x = "+x);
    System.out.println("y = "+y);
    }

}

 static boolean setX(){
      x=5;
     return true;
  }
 static boolean setY(){
      y=5;
      return true;
  }
}

wynik :

using double pipe
x = 5
y = 0
using single pipe
x = 5
y = 5
vishesh
źródło
2
Dlaczego podajesz przykład w języku Java dla pytania, które nawet nie wspomina o języku Java?
juharr
4

& - (Warunek 1 i Warunek 2): sprawdza oba przypadki, nawet jeśli pierwszy jest fałszywy

&& - (Warunek 1 i& Warunek 2): nie zawracaj sobie głowy sprawdzaniem drugiego przypadku, jeśli pierwszy jest fałszywy

&& - operator sprawi, że Twój kod będzie działał szybciej, profesjonalnie i jest rzadko używany

| - (Warunek 1 | Warunek 2): sprawdza oba przypadki, nawet jeśli przypadek 1 jest prawdziwy

|| - (Warunek 1 || Warunek 2): nie zawracaj sobie głowy sprawdzaniem drugiego przypadku, jeśli pierwszy jest prawdziwy

|| - operator sprawi, że Twój kod będzie działał szybciej, profesjonalnie | jest rzadko używany

Bhai Saab
źródło
2
rarely used? Wszystko zależy od tego, co chcesz lub musisz zrobić.
Emaborsa
1
Świetny! Krótko i słodko, usunęłbym „| jest rzadko używane” i „& jest rzadko używane”, ponieważ, jak powiedziała Emaborsa, to naprawdę zależy od tego, co chcesz lub musisz zrobić.
Iannick
0

Pojedyncza rura | jest jednym z operatorów bitowych .

Z Wikipedii:

W rodzinie języków programowania C bitowym operatorem OR jest „|” (rura). Ponownie, tego operatora nie należy mylić z jego logicznym „logicznym” lub „odpowiednikiem”, który traktuje swoje operandy jako wartości logiczne i jest napisany „||” (dwie rury).

codeLes
źródło
0

Z ich matematycznej definicji, OR i AND są operatorami binarnymi; weryfikują warunki LHS i RHS niezależnie, podobnie jak | i &.

|| i && zmieniają właściwości operatorów OR i AND, zatrzymując je, gdy warunek LHS nie jest spełniony.

Dragos Bandur
źródło
-1

The | operator wykonuje bitową operację OR swoich dwóch operandów (co oznacza, że ​​obie strony muszą ocenić na false, aby zwrócił false), podczas gdy || operator oceni drugiego operatora tylko w razie potrzeby.

http://msdn.microsoft.com/en-us/library/kxszd0kx(VS.71).aspx

http://msdn.microsoft.com/en-us/library/6373h346(VS.71).aspx

kaczka domowa
źródło
Jeśli faktycznie czytasz te artykuły, zobaczyłbyś, że odnoszą się one do operatorów bitowych
johnc
Nie to oznacza bitowe.
juharr
-1

Singe pipe „|” jest „bitowy” lub i powinien być używany tylko wtedy, gdy wiesz, co robisz. Podwójna rura „||” jest logicznym lub i może być użyte w instrukcjach logicznych, takich jak „x == 0 || x == 1”.

Oto przykład tego, co bitowe lub robi: jeśli a = 0101 ib = 0011, to a | b = 0111. Jeśli masz do czynienia z układem logicznym, który traktuje dowolne niezerowe jako prawdziwe, wówczas bitowe lub będzie działało w taki sam sposób, jak logiczne lub, ale jego odpowiednik (bitowe i „&”) NIE. Również bitowa lub nie wykonuje oceny zwarcia.

Kyle Cronin
źródło
„|” może być również stosowany do booltypów bez zwarć.
juharr
-2

Pojedyncza rura (|) jest bitowym operatorem LUB .

Dwie rury (||) to logiczny operator OR.

Nie są wymienne.

Duńczyk
źródło
1
Jeśli zignorujesz operację bitową, podwójna rura jest leniwa, a pojedyncza rura jest zachłanna, w obszarze operatora logicznego.
Alex