Qual é a diferença entre o | e || ou operadores?

300

Eu sempre usei ||(dois pipes) em expressões OR, tanto em C # quanto em PHP. Ocasionalmente eu vejo um único tubo utilizado: |. Qual é a diferença entre esses dois usos? Existem advertências ao usar um sobre o outro ou são intercambiáveis?

GloryFish
fonte

Respostas:

488

Assim como o operador &e &&, o operador duplo é um operador de "curto-circuito".

Por exemplo:

if(condition1 || condition2 || condition3)

Se a condição1 for verdadeira, as condições 2 e 3 NÃO serão verificadas.

if(condition1 | condition2 | condition3)

Isso verificará as condições 2 e 3, mesmo que 1 já seja verdadeiro. Como suas condições podem ter funções bastante caras, é possível obter um bom aumento de desempenho usando-as.

Há uma grande ressalva, NullReferences ou problemas semelhantes. Por exemplo:

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

Se a classe for nula, a instrução if será interrompida após class != nullfor falsa. Se você usar apenas o &, ele tentará verificar class.someVare você terá uma boa NullReferenceException. Com o Or-Operator, isso pode não ser uma armadilha, pois é improvável que você desencadeie algo ruim, mas é algo a ter em mente.

Ninguém nunca usa o único &ou |operadores que, a menos que você tem um projeto onde cada condição é uma função que tem de ser executado. Parece um cheiro de design, mas às vezes (raramente) é uma maneira limpa de fazer as coisas. O &operador "executa essas 3 funções e, se uma delas retornar falsa, execute o bloco else", enquanto o |"executa apenas o bloco else se nenhuma retornar false" - pode ser útil, mas, como dito, geralmente é um design cheiro.

Existe um segundo uso do operador |e &, porém: Operações Bitwise .

Michael Stum
fonte
9
Sim, eu não acreditei até criar um aplicativo de console - mas bom Deus! Por que eles te dariam a corda para se enforcar! Eu odiava isso no VB.NET - as palavras-chave OrElse e AndAlso!
Jarrod Dixon
24
Ensinar as pessoas a usar &e |como operadores condicionais é um hack e as colocará em problemas se eles precisarem usar C / C ++: 1 && 2é verdadeiro enquanto 1 & 2é falso.
precisa saber é o seguinte
47
Não é um hack, é oficialmente especificado para C # na Seção 7.10.3 Operadores lógicos booleanos: "O resultado de x | y é verdadeiro se x ou y for verdadeiro. Caso contrário, o resultado é falso." Consulte também a Seção 7.11 Operadores lógicos condicionais: "A operação x || y corresponde à operação x | y, exceto que y é avaliado apenas se x for falso." que "legaliza" ainda mais | como um operador condicional. E as pessoas que usarão C / C ++ estarão com problemas de qualquer maneira, se assumirem cegamente que as coisas funcionam da mesma forma. Como disse: Usando | em uma declaração if é um cheiro de design, mas uma operação perfeitamente legal.
Michael Stum
9
Eu nunca disse que não era legal, apenas que é um truque, o que é (você está usando &para transmitir um significado diferente do que quase sempre significa: bit a bit - e) .
BlueRaja - Danny Pflughoeft 7/12/12
15
@ BlueRaja-DannyPflughoeft Chamar um recurso documentado de hack quando a documentação diz que ele deveria ser usado é como dizer usando a instrução switch "um outro senão". É uma ferramenta na caixa de ferramentas, talvez seja uma ferramenta especializada raramente usada, mas não menos importante.
Gent
80

|| é o operador OR lógico. Parece que você basicamente sabe o que é isso. É usado em declarações condicionais, como se, enquanto, etc.

condition1 || condition2

Avalia como true se uma condição1 OU condição2 for verdadeira.

| é o operador OR bit a bit. É usado para operar em dois números. Você olha cada bit de cada número individualmente e, se um dos bits for 1 em pelo menos um dos números, o bit resultante será 1 também. Aqui estão alguns exemplos:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Espero que isso faça sentido.

Então, para responder às duas últimas perguntas, eu não diria que existem outras advertências além de "saber a diferença entre os dois operadores". Eles não são intercambiáveis ​​porque fazem duas coisas completamente diferentes.

Evan Shaw
fonte
Isso me ajudou a entender como alguém estava usando o operador OR bit a bit para mesclar filtros no driver Mongodb C #. gist.github.com/a3dho3yn/…
Donny V.
30

Um é um "bit a bit ou".

10011b 01000b => 11011b

O outro é uma lógica ou.

verdadeiro ou falso => ​​verdadeiro

nsanders
fonte
2
|também pode ser usado em booltipos sem curto-circuito.
precisa saber é o seguinte
14

Boa pergunta. Esses dois operadores funcionam da mesma maneira em PHP e C #.

|é um OR bit a bit. Ele irá comparar dois valores por seus bits. Por exemplo 1101 | 0010 = 1111. Isso é extremamente útil ao usar opções de bits. Por exemplo, Leitura = 01 (0X01) Gravação = 10 (0X02) Leitura-Gravação = 11 (0X03). Um exemplo útil seria abrir arquivos. Um exemplo simples seria:

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

||é um OR lógico. É assim que a maioria das pessoas pensa em OR e compara dois valores com base em sua verdade. Por exemplo, vou à loja ou irei ao shopping. Esse é o mais usado no código. Por exemplo:

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

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

Recursos 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
fonte
4
FWIW, tecnicamente, em C # |é lógico ou quando aplicado a booleanos . Como sua referência vinculada declara. Na prática, o resultado final é o mesmo que se fosse um operador bit a bit, porque os valores bit a bit de truee falsesão tais que um bit a bit ou seus valores produzem exatamente o mesmo resultado que um lógico ou faz. Isso é (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
Página
4

Exemplo simples em 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;
  }
}

resultado :

using double pipe
x = 5
y = 0
using single pipe
x = 5
y = 5
vishesh
fonte
2
Por que você daria um exemplo de java para uma pergunta que nem sequer menciona java?
precisa saber é o seguinte
4

& - (Condição 1 e Condição 2): verifica os dois casos, mesmo se o primeiro for falso

&& - (Condição 1 && Condição 2): não se preocupe em verificar o segundo caso, se o caso for falso

&& - o operador fará seu código rodar mais rápido, profissionalmente e raramente é usado

| - (Condição 1 | Condição 2): verifica os dois casos, mesmo se o caso 1 for verdadeiro

|| - (Condição 1 || Condição 2): não se preocupe em verificar o segundo caso, se o primeiro for verdadeiro

|| - operador fará seu código rodar mais rápido, profissionalmente | é raramente usado

Bhai Saab
fonte
2
rarely used? Tudo depende do que você quer ou precisa fazer.
Emaborsa
1
Ótimo! Curto e doce, eu removeria o "| raramente é usado" e "& é raramente usado" porque, como disse Emaborsa, depende realmente do que você deseja ou precisa fazer.
Iannick 28/08/19
0

O tubo único, |, é um dos operadores bit a bit .

Da Wikipedia:

Na família de linguagens de programação C, o operador OR bit a bit é "|" (tubo). Novamente, esse operador não deve ser confundido com sua contraparte "lógica ou" booleana, que trata seus operandos como valores booleanos e é escrita "||" (dois canos).

codeLes
fonte
0

Pela sua definição matemática, OR e AND são operadores binários; eles verificam as condições de LHS e RHS independentemente, da mesma forma que | e &.

|| e && alteram as propriedades dos operadores OR e AND parando-os quando a condição LHS não é atendida.

Dragos Bandur
fonte
-1

O | O operador executa um OR bit a bit de seus dois operandos (o que significa que ambos os lados devem avaliar como false para retornar false) enquanto o || O operador avaliará o segundo operador apenas se for necessário.

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

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

homeskillet
fonte
Se você realmente ler esses artigos, você teria visto que eles estão se referindo bit a bit operadores
JohnC
Não é isso que significa bit a bit.
precisa saber é o seguinte
-1

O tubo de chamuscado "|" é o "bit a bit" ou e só deve ser usado quando você souber o que está fazendo. O tubo duplo "||" é um lógico ou, e pode ser usado em instruções lógicas, como "x == 0 || x == 1".

Aqui está um exemplo do que o bit a bit ou faz: se a = 0101 eb = 0011, então a | b = 0111. Se você estiver lidando com um sistema lógico que trata qualquer diferente de zero como verdadeiro, então o bit a bit ou atuará da mesma maneira que o lógico ou, mas sua contrapartida (bit a bit e "&") NÃO. Também o bit a bit ou não realiza avaliação de curto-circuito.

Kyle Cronin
fonte
'|' também pode ser usado em booltipos sem curto-circuito.
precisa saber é o seguinte
-2

Um único pipe (|) é o operador OR bit a bit .

Dois pipes (||) é o operador OR lógico.

Eles não são intercambiáveis.

dinamarquês
fonte
1
Se você ignorar a operação bit a bit, o tubo duplo é uma avaliação lenta e o tubo único é ganancioso, dentro da área lógica do operador.
31413 Alex