¿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?

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 .


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.


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


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


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

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


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)


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.


-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


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.


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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.