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?

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 .


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.


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


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


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

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


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).


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.


-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


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.


„|” 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.


1
Jeśli zignorujesz operację bitową, podwójna rura jest leniwa, a pojedyncza rura jest zachłanna, w obszarze operatora logicznego.
Alex
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.