As versões escritas dos operadores lógicos

94

Este é o único lugar que eu já vi and, ore notlistado como operadores reais em C ++. Quando escrevi um programa de teste no NetBeans, recebi o sublinhado vermelho como se houvesse um erro de sintaxe e percebi que o site estava errado, mas é o NetBeans que está errado porque compilou e rodou conforme o esperado.

Posso ver que !estão sendo favorecidos, notmas a legibilidade de and&& orparece maior do que seus irmãos gramaticais. Por que essas versões dos operadores lógicos existem e por que aparentemente ninguém as usa? Isso é C ++ realmente válido ou algum tipo de compatibilidade com C que foi incluído com a linguagem?

defeituoso
fonte
4
\ me Reescreve todo o seu código
Expiação Limitada de
2
No espírito do "código limpo", eu pessoalmente recomendo acabar com o hábito de escrever ||e &&, talvez até !às vezes. Palavras são sempre melhores do que "ruído de linha", sem falar na possível confusão com os operadores de manipulação de bits.
Ichthyo
2
@Ichthyo Isso nem sempre é correto. É muito mais rápido ler muitos símbolos e saber o significado deles do que ler muitas palavras.
vallentin
o que é mais claro para um leitor humano depende da "Gestalt". Às vezes, um símbolo pode ser mais claro do que algum termo confuso, mas neste caso não é. E, palavras simples da língua inglesa são muito mais universais do que alguns símbolos especiais estranhos de uma linguagem de programação um tanto estranha ...
Ichthyo
3
A ironia de dizer que andé mais legível e depois escrever " and&& or" embora :)
Ivan Vergiliev

Respostas:

111

Eles se originaram em C no cabeçalho <iso646.h>. Na época, havia teclados que não podiam digitar os símbolos necessários para &&(por exemplo), então o cabeçalho continha #define's que os ajudaria a fazer isso, por (em nosso exemplo) definir andser &&. Claro, com o passar do tempo, isso foi se tornando menos usado.

Em C ++, eles se tornaram o que é conhecido como tokens alternativos . Você não precisa incluir nada para usar esses tokens em um compilador compatível (como tal, a versão C ++ ified do cabeçalho C,, <ciso646>está em branco). Os tokens alternativos são iguais aos tokens regulares, exceto pela ortografia. Portanto, durante a análise andé exatamente o mesmo que &&, é apenas uma maneira diferente de escrever a mesma coisa.

Quanto ao seu uso: como raramente são usados, usá-los costuma ser mais surpreendente e confuso do que útil. Tenho certeza de que se fosse normal, eles seriam muito mais fáceis de ler, mas as pessoas estão tão acostumadas &&e ||qualquer outra coisa se distrai.

EDIT: No entanto, vi um ligeiro aumento no uso deles desde que postei isso. Eu ainda os evito.

GManNickG
fonte
Portanto, a interpretação desses tokens alternativos é apenas um recurso do compilador ou está na especificação C ++?
defeituoso,
2
@Kavon: É especificado na seção 2.5 do padrão; é um recurso de linguagem.
GManNickG
15
Eu pessoalmente acho que eles são muito melhores ... mas eu sou preconceituoso sobre Python. Não sei por que algumas pessoas pensam que, se não estiver distorcido, não é um código ...
Matthieu M.
Então, eles não são válidos em C sem incluir aquele arquivo de cabeçalho? Estou surpreso que não sejam usados ​​por todos; eles tornam o Python muito mais legível.
endolith
1
Pelo menos o Visual Studio 2015 CTP 6 não gostou do meu orou notsem incluir o cabeçalho.
usr1234567
18

Eles existem para usabilidade (suporte a caracteres em tipos de teclado / tela) e legibilidade geral, mas há outra razão que é hoje em dia mais pronunciada. Quase nenhuma das respostas aqui , aqui , ou mesmo a resposta principal aquiexplique a razão principal pela qual muitos de nós preferimos as versões das palavras em vez das versões dos símbolos (e uma das principais razões pelas quais outras línguas as usam): bugs. As diferenças entre as versões das palavras são muito visíveis. As diferenças entre as versões dos símbolos são bem menores, a ponto de causar bugs em uma extensão comparativamente muito maior: "x | y" não é muito "x || y", mas quando embutido em uma expressão maior, muitos de nós perca a diferença. É semelhante à mistura acidental comum do operador de atribuição vs igualdade. Por esta razão, eu me desliguei das versões de símbolos (não foi fácil) em favor das versões de palavras. Prefiro que alguém os analise devido ao nosso amor pelas coisas antigas do que tentar insetos.

mr3
fonte
4
Infelizmente, no Visual Studio (a partir do VS2013), você deve definir uma opção de compilador específica ( /Za) para oferecer suporte às palavras-chave alternativas (consulte stackoverflow.com/a/555524/368896 ). Isso provavelmente também tem outros impactos. Portanto, no Visual Studio, não é necessariamente seguro seguir este conselho.
Dan Nissenbaum
FWIW / - à medida que coloco espaços ao redor dos operadores, x | yé suficientemente distinto visualmente (em fontes monoespaçadas) de x || y, mas acho o !in, por exemplo, if (!f(xyz) && ...mais fácil de perder do que if (not f(xyz) && ....
Tony Delroy de
@Tony D quando você coloca espaços ao redor dos operadores, essa é sua convenção particular e não é óbvia para o leitor. Mas usar palavras de linguagem natural como and, ore notem uma expressão booleana, na verdade melhora a legibilidade e destaca a distinção entre as manipulações de bits. Assim, IMHO, devemos considerar mudar nossos amados velhos hábitos para melhor ...
Ichthyo
@DanNissenbaum Encontrei esta opção com o nome C / C ++> Linguagem> Desativar extensões de linguagem , então é relativamente seguro esperar efeitos colaterais;)
Wolf
6
Você sabe quantos bugs do Python foram introduzidos porque as palavras ande orinfluenciam o pensamento das pessoas sobre como deveriam funcionar? Por exemplo, em if (a == b or c)vez de if (a == b || a == c)- algo como isso aparece quase todos os dias aqui no StackOverflow. Símbolos abstratos desconectados do idioma inglês reduzem esses erros.
Mark Ransom
10

Em C ++, são palavras-chave reais. Em C, são macros definidas em <iso646.h>. Consulte http://web.archive.org/web/20120123073126/http://www.dinkumware.com/manuals/?manual=compleat&page=iso646.html .

Chris Jester-Young
fonte
6
Tecnicamente, são tokens alternativos, não palavras-chave. :)
GManNickG
2
@GMan: +1 Boa chamada, entretanto, a página do Dinkumware os chama de palavras-chave, então, suponho que eles não se importaram muito com a distinção.
Chris Jester-Young,
Portanto, o MSVC oferece suporte para eles fora da caixa em C ++, mas não em C?
primeiro dia
1
@rwst Não posso comentar especificamente sobre o MSVC, mas se ele implementar os padrões C ++ e C fielmente, então esse será o caso. Veja também: stackoverflow.com/questions/2376448/…
Chris Jester-Young
2

ande &&são funcionalmente iguais em C ++. Os operadores ande orsão C ++ verdadeiramente válidos e fazem parte do padrão da linguagem.

Para elaborar outras respostas com um exemplo concreto, há uma outra razão além de apenas "legibilidade" a preferir andmais &&. Soletrar "e" explicitamente quando um AND lógico é o que você quer dizer elimina a possibilidade de bugs sutis.

Considere isto:

int x = 3;
int y = 4;

// Explicitly use "and"
if (x and y) {
    cout << "and: x and y are both non-zero values" << endl;
}

// Using "&&"
if (x && y) {
    cout << "&&: x and y are both non-zero values" << endl;
}

// Oops! I meant to type "&&"!
if (x & y) {
    cout << "&: x and y are both non-zero values" << endl;
}
else {
    cout << "How did I get here?" << endl;
}

Todas as três instruções if serão compiladas, mas a última significa algo totalmente diferente e não intencional!

Se você sempre usa andquando quer dizer AND lógico, nunca poderá digitar acidentalmente um único "&" e fazer com que seu código seja compilado com êxito e executado com resultados misteriosos.

Outro bom exercício: tente omitir o caractere "e" por acidente e veja o que acontece. ;)

tjwrona1992
fonte
1
Esta não é realmente uma resposta à pergunta. É só você declarar o que acha mais legível. O OP perguntou como as versões escritas funcionam, e não quais são melhores. E outra pessoa já disse o mesmo que você está tentando fazer.
Nicol Bolas
Não que isso realmente forneça mais informações úteis, mas acrescentarei " ande &&são funcionalmente idênticos" à resposta ... E se você ler minha resposta, verá que NÃO estou dizendo que é sobre legibilidade;)
tjwrona1992