¿Cuál es la diferencia entre el | y || u operadores?

300

Siempre he usado ||(dos tubos) en expresiones OR, tanto en C # como en PHP. De vez en cuando veo un solo tubo utilizado: |. ¿Cuál es la diferencia entre esos dos usos? ¿Hay alguna advertencia al usar una sobre la otra o son intercambiables?

GloryFish
fuente

Respuestas:

488

Al igual que el operador &y &&, el operador doble es un operador de "cortocircuito".

Por ejemplo:

if(condition1 || condition2 || condition3)

Si la condición 1 es verdadera, las condiciones 2 y 3 NO serán verificadas.

if(condition1 | condition2 | condition3)

Esto verificará las condiciones 2 y 3, incluso si 1 ya es cierto. Como sus condiciones pueden ser funciones bastante caras, puede obtener un buen aumento de rendimiento al usarlas.

Hay una gran advertencia, NullReferences o problemas similares. Por ejemplo:

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

Si la clase es nula, la instrucción if se detendrá después de que class != nullsea ​​falsa. Si solo usa &, intentará verificar class.someVary obtendrá un buen NullReferenceException. Con el O-Operator puede que no sea una gran trampa, ya que es poco probable que desencadenes algo malo, pero es algo a tener en cuenta.

Sin embargo, nadie usa el single &o los |operadores, a menos que tenga un diseño en el que cada condición sea una función que DEBE ejecutarse. Suena como un olor de diseño, pero a veces (rara vez) es una forma limpia de hacer cosas. El &operador "ejecuta estas 3 funciones, y si una de ellas devuelve falso, ejecute el bloque else", mientras que el |"solo ejecuta el bloque else si ninguno devuelve falso" - puede ser útil, pero como se dijo, a menudo es un diseño oler.

Sin embargo, hay un segundo uso del operador |y &: Operaciones bit a bit .

Michael Stum
fuente
99
Sí, no lo creí hasta que creé una aplicación de consola, ¡pero buen señor! ¿Por qué te darían la cuerda para ahorcarte? Odiaba eso de VB.NET: ¡las palabras clave OrElse y AndAlso!
Jarrod Dixon
24
Enseñar a las personas a usar &y |como operadores condicionales es un truco, y los meterá en problemas si alguna vez necesitan usar C / C ++: 1 && 2es cierto mientras que 1 & 2es falso.
BlueRaja - Danny Pflughoeft
47
No es un truco, se especifica oficialmente para C # en la Sección 7.10.3 Operadores lógicos booleanos: "El resultado de x | y es verdadero si x o y es verdadero. De lo contrario, el resultado es falso". Consulte también la Sección 7.11 Operadores lógicos condicionales: "La operación x || y corresponde a la operación x | y, excepto que y solo se evalúa si x es falso". que además "legaliza" | como operador condicional. Y las personas que usarán C / C ++ estarán en problemas de todos modos si simplemente asumen ciegamente que las cosas funcionan igual. Como se dijo: Usando | en una declaración if es un olor de diseño, pero una operación perfectamente legal.
Michael Stum
99
Nunca dije que no era legal, solo que es un truco, lo que es (lo estás usando &para transmitir un significado diferente al que casi siempre significa: bit a bit) .
BlueRaja - Danny Pflughoeft
15
@ BlueRaja-DannyPflughoeft Llamar a una característica documentada un hackeo cuando la documentación dice que estaba destinada a ser utilizada, es como decir usando una declaración de cambio "un hack de elseif". Es una herramienta en la caja de herramientas, una herramienta especializada que rara vez se usa, pero no obstante, es una herramienta.
Gent
80

|| es el operador lógico OR. Parece que básicamente sabes lo que es eso. Se usa en declaraciones condicionales como if, while, etc.

condition1 || condition2

Evalúa a verdadero si alguna condición1 O condición2 es verdadera.

El | es el operador OR a nivel de bit. Se utiliza para operar en dos números. Observa cada bit de cada número individualmente y, si uno de los bits es 1 en al menos uno de los números, entonces el bit resultante será 1 también. Aquí están algunos ejemplos:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Esperemos que tenga sentido.

Entonces, para responder las dos últimas preguntas, no diría que hay otras advertencias además de "conocer la diferencia entre los dos operadores". No son intercambiables porque hacen dos cosas completamente diferentes.

Evan Shaw
fuente
Esto me ayudó a comprender cómo alguien estaba usando el operador OR bit a bit para fusionar filtros en el controlador Mongodb C #. gist.github.com/a3dho3yn/…
Donny V.
30

Uno es un "bit a bit o".

10011b | 01000b => 11011b

El otro es una lógica o.

verdadero o falso => ​​verdadero

nsanders
fuente
2
|puede usarse también en booltipos sin cortocircuito.
juharr
14

Buena pregunta. Estos dos operadores funcionan igual en PHP y C #.

|es un OR bit a bit. Comparará dos valores por sus bits. Por ejemplo, 1101 | 0010 = 1111. Esto es extremadamente útil cuando se utilizan opciones de bit. Por ejemplo, lectura = 01 (0X01) escritura = 10 (0X02) lectura-escritura = 11 (0X03). Un ejemplo útil sería abrir archivos. Un ejemplo simple sería:

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

||es un OR lógico. Esta es la forma en que la mayoría de las personas piensa en OR y compara dos valores basados ​​en su verdad. Por ejemplo, voy a la tienda o iré al centro comercial. Este es el que se usa con más frecuencia en el código. Por ejemplo:

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

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

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

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

Trevor Abell
fuente
44
FWIW, técnicamente, en C # |es lógico o cuando se aplica a booleanos . Como dice su referencia vinculada. En la práctica, el resultado final es el mismo que si se tratara de un operador bit a bit, porque los valores bit a bit de truey falseson tales que un bit a bit o de sus valores produce exactamente el mismo resultado que un lógico o lo hace. Eso es (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve
4

Ejemplo simple en 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;
  }
}

salida:

using double pipe
x = 5
y = 0
using single pipe
x = 5
y = 5
vishesh
fuente
2
¿Por qué darías un ejemplo de Java para una pregunta que ni siquiera menciona Java?
juharr
4

& - (Condición 1 y Condición 2): comprueba ambos casos incluso si el primero es falso

&& - (Condición 1 && Condición 2): no se moleste en verificar el segundo caso si el caso uno es falso

&&: el operador hará que su código se ejecute más rápido, profesionalmente y rara vez se usa

El | - (Condición 1 | Condición 2): comprueba ambos casos incluso si el caso 1 es verdadero

|| - (Condición 1 || Condición 2): no se moleste en verificar el segundo caso si el primero es verdadero

|| - el operador hará que su código se ejecute más rápido, profesionalmente | rara vez se usa

Bhai Saab
fuente
2
rarely used? Todo depende de lo que quieras o necesites hacer.
Emaborsa
1
¡Excelente! Breve y dulce, eliminaría "| rara vez se usa" y "y rara vez se usa" porque, como dijo Emaborsa, realmente depende de lo que quieras o necesites hacer.
Iannick
0

La tubería única, |, es uno de los operadores bit a bit .

De Wikipedia:

En la familia del lenguaje de programación C, el operador OR a nivel de bit es "|" (tubo). Nuevamente, este operador no debe confundirse con su contraparte "lógica o" booleana, que trata sus operandos como valores booleanos y se escribe "||" (dos tubos)

codeLes
fuente
0

Por su definición matemática, OR y AND son operadores binarios; ellos verifican las condiciones de LHS y RHS independientemente, de manera similar a | y &.

|| y && alteran las propiedades de los operadores OR y AND deteniéndolos cuando no se cumple la condición LHS.

Dragos Bandur
fuente
-1

El | el operador realiza un OR bit a bit de sus dos operandos (lo que significa que ambos lados deben evaluar como falso para que devuelva falso) mientras que el || El operador solo evaluará al segundo operador si es necesario.

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

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

casa de vacaciones
fuente
Si realmente leyera esos artículos, habría visto que se refieren a operadores bit a bit
Johnc
Eso no es lo que significa bit a bit.
juharr
-1

La pipa de chamuscado "|" es "bit a bit" o y solo debe usarse cuando sabes lo que estás haciendo. El tubo doble "||" es un lógico o, y puede usarse en declaraciones lógicas, como "x == 0 || x == 1".

Aquí hay un ejemplo de lo que hace el bit a bit: si a = 0101 yb = 0011, entonces a | b = 0111. Si se trata de un sistema lógico que trata cualquier valor distinto de cero como verdadero, entonces el bit o actuará de la misma manera que el lógico o, pero su contraparte (bit a bit y "&") NO. También el bit a bit o no realiza la evaluación de cortocircuito.

Kyle Cronin
fuente
'|' También se puede utilizar en booltipos sin cortocircuito.
juharr
-2

Una sola tubería (|) es el operador OR bit a bit .

Dos canalizaciones (||) es el operador lógico OR.

No son intercambiables.

danés
fuente
1
Si ignora la operación bit a bit, la tubería doble es una evaluación diferida y la tubería simple es codiciosa, dentro del área del operador lógico.
Alex