&& e || não são operadores lógicos, mas condicionais?

62

Estou um pouco confuso com a documentação MSDN C #, que afirma que &e |são operadores lógicos e que &&e ||são operadores condicionais.

Eu continuo ligando &&, ||e !operadores lógicos, então estou errado?

João V
fonte
4
Parece ilógico, mas há uma diferença importante entre as duas classes, e é fundamental que você não assuma que, digamos, |seja intercambiável ||, mesmo que em muitos casos eles possam ser trocados sem nenhuma mudança aparente no comportamento do programa.
Daniel R Hicks

Respostas:

120

Estou um pouco confuso com a documentação MSDN C #, que afirma que &e |são operadores lógicos e que &&e ||são operadores condicionais. Eu continuo ligando &&, ||e !operadores lógicos, então estou errado?

Não; você está certo.

Existem inúmeros erros de nomenclatura pequenos, principalmente sem importância, na documentação do MSDN; Tentei divulgar o maior número possível deles, mas nos casos em que não é flagrantemente errado e enganoso, nem sempre é um uso sábio do tempo. Vá para a especificação se desejar uma declaração definitiva sobre o nome de um recurso C #.

Portanto: a autoridade relevante é a especificação C #, que afirma na seção 7.11:

A &, ^, e |os operadores são chamados os operadores lógicos.

Em seguida, ele divide ainda mais os operadores lógicos internos em operadores lógicos inteiro, enumeração, booleano e booleano anulável. Também existem operadores lógicos definidos pelo usuário; veja a especificação para detalhes.

Na seção 7.12, temos

Os operadores &&e ||são chamados de operadores lógicos condicionais. Eles também são chamados de operadores lógicos de "curto-circuito".

Então, todos eles são operadores lógicos . Alguns deles são operadores lógicos condicionais .

O que torna os operadores lógicos condicionais condicionais ? Pode-se fazer um palpite ilusório de que isso ocorre porque eles geralmente são usados ​​em declarações condicionais ( if) ou expressões condicionais ( ? :). A verdadeira razão é dada pela especificação:

Os operadores &&e ||são versões condicionais dos operadores &e |: A operação x && ycorresponde à operação x & y, exceto que yé avaliada apenas se xnão for falsa. A operação x || ycorresponde à operação x | y, exceto que yé avaliada apenas se xnão for verdadeira.

Os operadores lógicos condicionais são assim nomeados porque o operando do lado direito é avaliado condicionalmente, dependendo do valor do operando do lado esquerdo.

Podemos ver isso mais claramente observando que os operadores lógicos condicionais são apenas "açúcares sintáticos" para expressões condicionais . x && yé simplesmente uma maneira mais agradável de escrever x ? y : falsee x || yé simplesmente uma maneira mais agradável de escrever x ? true : y. As expressões lógicas condicionais são realmente expressões condicionais.

Há também uma forma definida pelo usuário do operador lógico condicional, e é um pouco complicado. Veja a especificação para detalhes.

Leitura adicional, se este assunto lhe interessar:

Eric Lippert
fonte
3
@RobertHarvey: Certo, o fato de o & poder operar em bools, tipos inteiros ou enum, mas o && opera apenas em bools não tem nada a ver com a escolha de nomear um deles como a forma "condicional" do operador. O operador condicional é condicional porque possui uma ramificação condicional em sua semântica de avaliação.
precisa
16
Tenho a impressão de que o termo "operador de curto-circuito" é muito mais popular (e provavelmente menos ambíguo) do que "operador condicional" no sentido descrito.
Doc Brown
15
@DocBrown: Certamente é popular, mas sempre achei esse nome enganoso; parece ter sido cunhado por alguém que pensava que um "curto-circuito" e um "atalho" para obter um resultado são a mesma coisa. Um curto-circuito é uma falha perigosa que pode destruir rapidamente um sistema elétrico. Nomeamos blocos "inseguros" no C # "inseguros" porque eles são perigosos se usados ​​incorretamente ; não vamos dar nomes fofos, mas enganosos e carregados de valores. Nem me inicie no operador Elvis. :-)
Eric Lippert
26
@ Ericricipper: Embora o "curto-circuito" possa parecer assustador para o público em geral, não acho que a K&R tenha se confundido com a definição real. Na engenharia elétrica, curto-circuito nem sempre é uma falha perigosa; na verdade, fazemos isso intencionalmente o tempo todo. Significa apenas cortar uma parte indesejada do circuito, dando à eletricidade um caminho mais curto a seguir.
hackerb9
1
@CortAmmon: Você deve ler o parágrafo a seguir, onde apelo que a semântica do operador definida pelo usuário é um pouco diferente e que você deve ver a especificação para obter detalhes.
precisa
27

Em C #, todos esses são operadores lógicos.

int x = 0xABCD & 0xFF // x == 0xCD

&&e ||são chamados de " operadores lógicos condicionais " porque estão em curto-circuito.

bool someOtherCondition = true;
if (x == 0xEF && someOtherCondition) // someOtherCondition is not evaluated, 
                                     // because x == 0xEF is false

Observe que essa terminologia difere de idioma para idioma. Em C e C ++ &&e ||são apenas operadores lógicos. Em Java, &e |são chamados de Operadores bit a bit , enquanto C e C ++ classifica-los como operadores aritméticos .

Robert Harvey
fonte
3
Sim, a Microsoft é a autoridade, mas o documento oficial é a especificação. Consulte a seção 7.12, Operadores lógicos condicionais .
precisa
8
A moral da história é: é mais importante entender exatamente o que esses operadores fazem do que ser preciso sobre seus nomes.
Robert Harvey
21
Concentre-se no que os operadores fazem e pare de ficar obcecado com o vocabulário. Veja também Nomeação considerada prejudicial .
Robert Harvey
4
+1. Tudo listado na pergunta são apenas operadores que pegam uma ou duas expressões e avaliam um valor. Os adjetivos são rachaduras desnecessárias.
Blrfl
3
@RobertHarvey Ensaios “considerados prejudiciais” considerados prejudiciais
user11153 23/11
-2

O ponto é que &e |são operadores bit a bit , o que significa que eles são aplicados e produzem valores de cadeia de bits. E bit a bit é um termo muito usado entre programadores.

Por exemplo 0xff & 0x00 == 0x00, enquanto 0xff | 0x00 == 0xff.

E &&e ||são aplicados a condições, e deu os valores habituais de condições; ie truee false.

Por exemplo true && false == false, enquanto true || false == true.

Por isso &&e ||poderia ser chamado condicionais operadores, apesar de que não é um termo usual entre os programadores.

Obviamente, todo programador de C, C ++, Java e C # sabe tudo isso. Mas acho que o mal-entendido acontece porque "operador condicional" não é um termo usado com freqüência por nós programadores.

Hilton Fernandes
fonte
5
Obviamente, todo programador de C, C ++, Java e C # sabe tudo isso. É uma coisa muito rude de se escrever, sugerindo que o OP é estúpido. Mesmo nos escrevendo programadores , você exclui o OP. Por favor, não faça isso.
DarkDust
1
Eu não acho que sua resposta posterior traga algum valor agregado após a resposta aceita de Eric Lippert e, além disso, está incorreta no sentido de não entender o objetivo da pergunta.
Honza Zidek
@DDarkDust Todo programador em C, C ++, Java e C # deve entender esses operadores. Isso não está sendo rude, mas um fato .
Phil1970
1
@ Phil1970: O OP parece entender esses operadores, trata-se de esclarecer os nomes . Sob essa luz, e tendo enfatizado os termos relevantes na resposta de Hilton, essa frase pode ser interpretada como significando que todo programador conhece esses detalhes de nomenclatura, mas você não . Isso está errado (como pode ser visto nas discussões das outras respostas) e seu fraseado é rude.
DarkDust
4
Queridos, desculpe se minha resposta pareceu rude. Inglês não é a 1ª língua. De qualquer forma, nunca pretendi sugerir que o OP não era um programador. Au contrire, eu quis dizer que ele ou ela estava confuso com uma nomeação incomum no texto que ele ou ela lia. Tudo o que tentei fazer foi esclarecer a nomeação incomum por fragmentos de programa.
Hilton Fernandes