Qual è la differenza tra | e || o operatori?


300

Ho sempre usato ||(due pipe) in espressioni OR, sia in C # che in PHP. Di tanto in tanto vedo un unico tubo utilizzato: |. Qual è la differenza tra questi due usi? Ci sono avvertenze quando si usano l'una sull'altra o sono intercambiabili?

Risposte:


488

Proprio come l' operatore &e &&, il doppio operatore è un operatore "in cortocircuito".

Per esempio:

if(condition1 || condition2 || condition3)

Se la condizione 1 è vera, le condizioni 2 e 3 NON verranno verificate.

if(condition1 | condition2 | condition3)

Questo verificherà le condizioni 2 e 3, anche se 1 è già vero. Poiché le tue condizioni possono essere funzioni piuttosto costose, puoi ottenere un buon incremento delle prestazioni utilizzandole.

C'è un grande avvertimento, NullReferences o problemi simili. Per esempio:

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

Se la classe è nulla, l'istruzione if si fermerà dopo class != nullsarà falsa. Se usi solo &, proverà a controllare class.someVare otterrai un risultato piacevole NullReferenceException. Con l'operatore-operatore potrebbe non essere una tale trappola perché è improbabile che tu attivi qualcosa di brutto, ma è qualcosa da tenere a mente.

Nessuno usa mai il singolo &o gli |operatori, a meno che tu non abbia una progettazione in cui ogni condizione è una funzione che DEVE essere eseguita. Sembra un odore di design, ma a volte (raramente) è un modo pulito per fare cose. L' &operatore "esegue queste 3 funzioni e se una di esse restituisce false, esegue il blocco else", mentre |"esegue solo il blocco else se nessuna restituisce false" - può essere utile, ma come detto, spesso è un progetto odore.

Esiste un secondo uso dell'operatore |e &: Operazioni bit a bit .


9
Sì, non ci credevo fino a quando non ho creato un'app console - ma buon dio! Perché ti darebbero la corda per impiccarti! Lo odiavo di VB.NET - le parole chiave OrElse e AndAlso!
Jarrod Dixon

24
Insegnare alle persone come usare &e |come operatori condizionali è un hack e li metterà nei guai se mai avranno bisogno di usare C / C ++: 1 && 2è vero mentre 1 & 2è falso.
BlueRaja - Danny Pflughoeft il

47
Non è un hack, è ufficialmente specificato per C # nella Sezione 7.10.3 Operatori logici booleani: "Il risultato di x | y è vero se x o y è vero. Altrimenti, il risultato è falso." Vedi anche Sezione 7.11 Operatori logici condizionali: "L'operazione x || y corrisponde all'operazione x | y, tranne per il fatto che y viene valutato solo se x è falso." che "legalizza" ulteriormente come operatore condizionale. E le persone che useranno il C / C ++ saranno comunque nei guai se pensano semplicemente che le cose funzionino allo stesso modo. Come detto: utilizzando | in una dichiarazione if è un odore di design, ma un'operazione perfettamente legale.
Michael Stum

9
Non ho mai detto che non fosse legale, solo che è un trucco, e lo è (stai usando &per trasmettere un significato diverso da quello che quasi sempre significa: bit a bit) .
BlueRaja - Danny Pflughoeft

15
@ BlueRaja-DannyPflughoeft Chiamare una caratteristica documentata come un hack quando la documentazione dice che doveva essere usata, è come dire usando un'istruzione switch "un altro hack". È uno strumento nella cassetta degli attrezzi, forse uno strumento speciale usato raramente, ma uno strumento non meno.
Gent,

80

|| è l'operatore logico OR. Sembra che tu sostanzialmente sappia di cosa si tratta. È usato in istruzioni condizionali come if, while, ecc.

condition1 || condition2

Valuta vero se o condizione1 O condizione2 è vera.

| è l'operatore OR bit a bit. È usato per operare su due numeri. Osserva singolarmente ciascun bit di ciascun numero e, se uno dei bit è 1 in almeno uno dei numeri, anche il bit risultante sarà 1. Ecco alcuni esempi:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Spero che abbia senso.

Quindi, per rispondere alle ultime due domande, non direi che ci sono avvertimenti oltre a "conoscere la differenza tra i due operatori". Non sono intercambiabili perché fanno due cose completamente diverse.


Questo mi ha aiutato a capire come qualcuno stava usando un operatore OR bit a bit per unire i filtri nel driver Mongodb C #. gist.github.com/a3dho3yn/…
Donny V.

30

Uno è un "bit per bit o".

10011b | 01000b => 11011b

L'altro è una logica o.

true o false => true


2
|può essere utilizzato anche su booltipi senza corto circuito.
juharr

14

Buona domanda. Questi due operatori funzionano allo stesso modo in PHP e C #.

|è un OR bit a bit. Confronterà due valori con i loro bit. Ad esempio 1101 | 0010 = 1111. Ciò è estremamente utile quando si utilizzano le opzioni bit. Ad esempio Lettura = 01 (0X01) Scrittura = 10 (0X02) Lettura-Scrittura = 11 (0X03). Un esempio utile potrebbe essere l'apertura di file. Un semplice esempio potrebbe essere:

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

||è un OR logico. Questo è il modo in cui la maggior parte delle persone pensa all'OR e confronta due valori in base alla propria verità. Ad esempio, vado al negozio o andrò al centro commerciale. Questo è quello usato più spesso nel codice. Per esempio:

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

Risorsa PHP: http://us3.php.net/language.operators.bitwise

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

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


4
FWIW, tecnicamente, in C # |è logico o se applicato ai booleani . Come afferma il tuo riferimento collegato. In pratica, il risultato finale è lo stesso di se fosse un operatore bit a bit, perché i valori bit a bit di truee falsesono tali che un bit a bit o dei loro valori produce esattamente lo stesso risultato di un logico o no. Questo è (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve

4

Semplice esempio 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;
  }
}

produzione :

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

2
Perché dovresti dare un esempio di Java per una domanda che non menziona nemmeno Java?
juharr

4

& - (Condizione 1 e Condizione 2): controlla entrambi i casi anche se il primo è falso

&& - (Condizione 1 && Condizione 2): non preoccuparti di controllare il secondo caso se il caso uno è falso

&& - L'operatore renderà il tuo codice più veloce, professionale e raramente utilizzato

| - (Condizione 1 | Condizione 2): controlla entrambi i casi anche se il caso 1 è vero

|| - (Condizione 1 || Condizione 2): non preoccuparti di controllare il secondo caso se il primo è vero

|| - operatore renderà il tuo codice più veloce, professionalmente | viene usato raramente


2
rarely used? Tutto dipende da cosa vuoi o devi fare.
Emaborsa,

1
Grande! Breve e dolce, rimuoverei "| è usato raramente" e "è usato raramente" perché, come diceva Emaborsa, dipende davvero da cosa vuoi o devi fare.
Iannick,

0

Il singolo pipe, |, è uno degli operatori bit a bit .

Da Wikipedia:

Nella famiglia di linguaggi di programmazione C, l'operatore OR bit a bit è "|" (tubo). Ancora una volta, questo operatore non deve essere confuso con la sua controparte "logica o" booleana, che tratta i suoi operandi come valori booleani ed è scritto "||" (due tubi).


0

Con la loro definizione matematica, OR ed AND sono operatori binari; verificano le condizioni LHS e RHS indipendentemente, analogamente a | e &.

|| e && alterano le proprietà degli operatori OR e AND interrompendoli quando la condizione LHS non è soddisfatta.


-1

Il | L'operatore esegue un OR bit a bit dei suoi due operandi (il che significa che entrambe le parti devono valutare false per restituire false) mentre || l'operatore valuterà il secondo operatore solo se necessario.

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

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


Se effettivamente leggessi quegli articoli, avresti visto che si stanno riferendo ad operatori bit per bit
johnc

Non è questo che significa bit a bit.
juharr

-1

The singe pipe "|" è il "bit per bit" o e dovrebbe essere usato solo quando sai cosa stai facendo. Il doppio tubo "||" è un logico o e può essere utilizzato in istruzioni logiche, come "x == 0 || x == 1".

Ecco un esempio di cosa bit per bit o fa: se a = 0101 e b = 0011, quindi a | b = 0111. Se hai a che fare con un sistema logico che considera qualsiasi zero diverso da vero, allora il bit a bit o agirà allo stesso modo del logico o, ma è controparte (a bit e e "&") NON. Anche bit a bit o non esegue la valutazione del corto circuito.


'|' può essere utilizzato anche su booltipi senza corto circuito.
juharr

-2

Un singolo tubo (|) è l' operatore OR bit a bit .

Due pipe (||) è l'operatore logico OR.

Non sono intercambiabili.


1
Se si ignora l'operazione bit a bit, la doppia pipe è una valutazione pigra e la singola pipe è avida, all'interno dell'area dell'operatore logico.
Alex
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.