Was ist der Unterschied zwischen dem | und || oder Betreiber?


300

Ich habe immer ||(zwei Pipes) in OR-Ausdrücken verwendet, sowohl in C # als auch in PHP. Gelegentlich sehe ich ein einzelnes Rohr verwendet : |. Was ist der Unterschied zwischen diesen beiden Verwendungen? Gibt es irgendwelche Einschränkungen bei der Verwendung übereinander oder sind sie austauschbar?

Antworten:


488

Genau wie die &und &&Betreiber ist der Doppel Operator ein „Kurzschluss“ Operator.

Zum Beispiel:

if(condition1 || condition2 || condition3)

Wenn Bedingung1 erfüllt ist, werden Bedingung 2 und 3 NICHT überprüft.

if(condition1 | condition2 | condition3)

Dadurch werden die Bedingungen 2 und 3 überprüft, auch wenn 1 bereits wahr ist. Da Ihre Bedingungen sehr teure Funktionen sein können, können Sie mit ihnen einen guten Leistungsschub erzielen.

Es gibt eine große Einschränkung, NullReferences oder ähnliche Probleme. Zum Beispiel:

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

Wenn class null ist, stoppt die if-Anweisung, nachdem class != nullfalse festgelegt wurde. Wenn Sie nur & verwenden, wird es versuchen zu überprüfen class.someVarund Sie erhalten eine schöne NullReferenceException. Mit dem Or-Operator ist das vielleicht keine so große Falle, da es unwahrscheinlich ist, dass Sie etwas Schlechtes auslösen, aber es ist etwas, das Sie beachten sollten.

Niemand verwendet jedoch jemals die Einzel- &oder |Operatoren, es sei denn, Sie haben ein Design, bei dem jede Bedingung eine Funktion ist, die ausgeführt werden muss. Klingt nach einem Designgeruch, ist aber manchmal (selten) eine saubere Art, Dinge zu tun. Der &Operator führt "diese 3 Funktionen aus, und wenn eine von ihnen false zurückgibt, führen Sie den else-Block aus", während der Operator "den else-Block |nur ausführt, wenn keiner false zurückgibt " - nützlich sein kann, aber wie gesagt, oft handelt es sich um ein Design Geruch.

Es gibt jedoch eine zweite Verwendung des Operators |und &: Bitweise Operationen .


9
Ja, ich habe es nicht geglaubt, bis ich eine Konsolen-App erstellt habe - aber mein Gott! Warum sollten sie dir das Seil geben, um dich aufzuhängen? Ich hasste das an VB.NET - den Schlüsselwörtern OrElse und AndAlso!
Jarrod Dixon

24
Das Erlernen der Verwendung &und |als bedingte Operatoren ist ein Hack und bringt sie in Schwierigkeiten, wenn sie jemals C / C ++ verwenden müssen: 1 && 2ist wahr, während 1 & 2es falsch ist.
BlueRaja - Danny Pflughoeft

47
Es ist kein Hack, es ist offiziell für C # in Abschnitt 7.10.3 angegeben. Boolesche logische Operatoren: "Das Ergebnis von x | y ist wahr, wenn entweder x oder y wahr ist. Andernfalls ist das Ergebnis falsch." Siehe auch Abschnitt 7.11 Bedingte logische Operatoren: "Die Operation x || y entspricht der Operation x | y, außer dass y nur ausgewertet wird, wenn x falsch ist." die weiter "legalisiert" | als bedingter Operator. Und Leute, die C / C ++ verwenden, werden sowieso in Schwierigkeiten geraten, wenn sie einfach blind davon ausgehen, dass das Zeug gleich funktioniert. Wie gesagt: Mit | in einer if-Anweisung ist ein Designgeruch, aber eine vollkommen legale Operation.
Michael Stum

9
Ich habe nie gesagt, dass es nicht legal ist, nur, dass es ein Hack ist, was es ist (Sie verwenden &, um eine andere Bedeutung zu vermitteln als die, die es fast immer bedeutet: bitweise und) .
BlueRaja - Danny Pflughoeft

15
@ BlueRaja-DannyPflughoeft Wenn Sie eine dokumentierte Funktion als Hack bezeichnen, wenn in der Dokumentation angegeben ist, dass sie verwendet werden soll, ist dies wie die Verwendung einer switch-Anweisung "ein elseif-Hack". Es ist ein Werkzeug in der Werkzeugkiste, vielleicht ein selten verwendetes Spezialwerkzeug, aber dennoch ein Werkzeug.
Gent

80

|| ist der logische ODER-Operator. Es hört sich so an, als ob Sie im Grunde wissen, was das ist. Es wird in bedingten Anweisungen wie if, while usw. verwendet.

condition1 || condition2

Wird als wahr ausgewertet, wenn entweder Bedingung1 oder Bedingung2 wahr ist.

| ist der bitweise ODER-Operator. Es wird verwendet, um mit zwei Zahlen zu arbeiten. Sie betrachten jedes Bit jeder Zahl einzeln und wenn eines der Bits in mindestens einer der Zahlen 1 ist, ist das resultierende Bit ebenfalls 1. Hier einige Beispiele:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Hoffentlich macht das Sinn.

Um die letzten beiden Fragen zu beantworten, würde ich nicht sagen, dass es neben "den Unterschied zwischen den beiden Operatoren kennen" keine Einschränkungen gibt. Sie sind nicht austauschbar, weil sie zwei völlig verschiedene Dinge tun.


Dies half mir zu verstehen, wie jemand den bitweisen ODER-Operator verwendete, um Filter im Mongodb C # -Treiber zusammenzuführen. gist.github.com/a3dho3yn/…
Donny V.

30

Einer ist ein "bitweises oder".

10011b | 01000b => 11011b

Der andere ist eine Logik oder.

wahr oder falsch => wahr


2
|kann auch bei boolTypen ohne Kurzschluss verwendet werden.
Juharr

14

Gute Frage. Diese beiden Operatoren arbeiten in PHP und C # gleich.

|ist ein bitweises ODER. Es werden zwei Werte anhand ihrer Bits verglichen. ZB 1101 | 0010 = 1111. Dies ist äußerst nützlich, wenn Bitoptionen verwendet werden. ZB Lesen = 01 (0X01) Schreiben = 10 (0X02) Lesen-Schreiben = 11 (0X03). Ein nützliches Beispiel wäre das Öffnen von Dateien. Ein einfaches Beispiel wäre:

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

||ist ein logisches ODER. Auf diese Weise denken die meisten Menschen über OP und vergleichen zwei Werte anhand ihrer Wahrheit. ZB gehe ich in den Laden oder ich gehe ins Einkaufszentrum. Dies ist diejenige, die am häufigsten im Code verwendet wird. Zum Beispiel:

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

PHP-Ressource: http://us3.php.net/language.operators.bitwise

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

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


4
FWIW, technisch gesehen , in C # |ist eine logische oder , wenn angewendet booleans . Wie Ihre verknüpfte Referenz angibt. In der Praxis ist das Endergebnis dasselbe, als wäre es ein bitweiser Operator, da die bitweisen Werte von trueund so falsesind, dass ein bitweises oder eines ihrer Werte genau das gleiche Ergebnis wie ein logisches oder ein logisches Ergebnis liefert. Das ist (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve

4

Einfaches Beispiel in 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;
  }
}

Ausgabe :

using double pipe
x = 5
y = 0
using single pipe
x = 5
y = 5

2
Warum würden Sie ein Java-Beispiel für eine Frage geben, in der Java nicht einmal erwähnt wird?
Juharr

4

& - (Bedingung 1 & Bedingung 2): Überprüft beide Fälle, auch wenn der erste falsch ist

&& - (Bedingung 1 && Bedingung 2): Machen Sie sich nicht die Mühe, den zweiten Fall zu überprüfen, wenn der erste Fall falsch ist

&& - Operator lässt Ihren Code schneller und professioneller laufen und wird selten verwendet

| - (Bedingung 1 | Bedingung 2): Überprüft beide Fälle, auch wenn Fall 1 wahr ist

|| - (Bedingung 1 || Bedingung 2): Machen Sie sich nicht die Mühe, den zweiten Fall zu überprüfen, wenn der erste wahr ist

|| - Der Operator sorgt dafür, dass Ihr Code schneller und professioneller ausgeführt wird wird selten verwendet


2
rarely used? Alles hängt davon ab, was Sie tun möchten oder müssen.
Emaborsa

1
Großartig! Kurz und bündig, ich würde das "| wird selten verwendet" und "& wird selten verwendet" entfernen, da es, wie Emaborsa sagte, wirklich davon abhängt, was Sie tun möchten oder müssen.
Iannick

0

Das einzelne Rohr | ist eines der bitweisen Operatoren.

Aus Wikipedia:

In der Programmiersprachenfamilie C lautet der bitweise ODER-Operator "|" (Rohr). Auch dieser Operator darf nicht mit seinem booleschen "logischen oder" Gegenstück verwechselt werden, das seine Operanden als boolesche Werte behandelt und mit "||" geschrieben ist. (zwei Rohre).


0

Nach ihrer mathematischen Definition sind OR und AND binäre Operatoren. Sie überprüfen die LHS- und RHS-Bedingungen unabhängig davon, ähnlich wie | und &.

|| und && ändern Sie die Eigenschaften der Operatoren OR und AND, indem Sie sie stoppen, wenn die LHS-Bedingung nicht erfüllt ist.


-1

Die | Der Operator führt ein bitweises ODER seiner beiden Operanden aus (dh beide Seiten müssen als falsch ausgewertet werden, damit er false zurückgibt), während der || Der Operator wertet den zweiten Operator nur aus, wenn dies erforderlich ist.

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

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


Wenn Sie diese Artikel tatsächlich gelesen hätten, hätten Sie gesehen, dass sie sich auf bitweise Operatoren
beziehen

Das ist nicht das, was bitweise bedeutet.
Juharr

-1

Das Einzelrohr "|" ist das "bitweise" oder und sollte nur verwendet werden, wenn Sie wissen, was Sie tun. Die Doppelpfeife "||" ist ein logisches oder und kann in logischen Anweisungen wie "x == 0 || x == 1" verwendet werden.

Hier ist ein Beispiel dafür, was das bitweise oder tut: Wenn a = 0101 und b = 0011, dann ist a | b = 0111. Wenn Sie es mit einem Logiksystem zu tun haben, das eine Nicht-Null als wahr behandelt, verhält sich das bitweise oder genauso wie das logische oder, aber das Gegenstück (bitweise und "&") NICHT. Auch die bitweise oder führt keine Kurzschlussauswertung durch.


'|' kann auch bei boolTypen ohne Kurzschluss verwendet werden.
Juharr

-2

Eine einzelne Pipe (|) ist der bitweise ODER-Operator .

Zwei Pipes (||) sind der logische ODER-Operator.

Sie sind nicht austauschbar.


1
Wenn Sie die bitweise Operation ignorieren, ist Double Pipe eine verzögerte Auswertung und Single Pipe ist innerhalb des logischen Operatorbereichs gierig.
Alex
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.