Pense booleanos, não bits
Em resumo, a solução do professor é melhor (mas ainda está errada, a rigor, veja mais adiante) porque ela usa operadores booleanos em vez de operadores bit a bit e trata os booleanos como números inteiros. A expressão c==1
para representar "c é verdadeira" está incorreta porque se c pode ser um número (de acordo com a atribuição declarada), qualquer valor diferente de zero de c deve ser considerado como representando true
.
Veja esta pergunta sobre por que é melhor não comparar booleanos com 0 ou 1, mesmo quando é seguro fazê-lo.
Uma boa razão para não usar xor
é que esta é a operação ou exclusiva em termos de bits . Isso funciona no seu exemplo, porque o lado esquerdo e o lado direito são expressões booleanas que se convertem em 1 ou 0 (consulte novamente 1 ).
O booleano exclusivo - ou é de fato !=
.
Quebrando a expressão
Para entender melhor a solução do professor, é mais fácil substituir os operadores booleanos por seus equivalentes "token alternativo", que o transformam em código C ++ melhor redable (imho) e completamente equivalente: Usando 'not' for '!' e 'e' para '&&' você obtém
(not a and not b) != c
Infelizmente, não há exclusive_or
outro operador lógico not_eq
que não seja útil nesse caso.
Se quebrarmos a expressão da linguagem natural:
A e b são ambos falsos ou c é verdadeiro, mas não ambos.
primeiro em uma frase sobre as proposições booleanas A e B:
A ou B, mas não ambos.
isso se traduz em A != B
(apenas para booleanos, não para qualquer tipo A e B).
Então a proposição A foi
aeb são ambos falsos
que pode ser indicado como
a é falso eb é falso
que se traduz em (not a and not b)
, e finalmente
c é verdade
O que simplesmente se traduz em c
. Combinando eles, você obtém novamente (not a and not b) != c
.
Para mais explicações sobre como essa expressão funciona, eu refiro às tabelas da verdade que outros deram em suas respostas.
Vocês dois estão errados
E se eu puder nitpick: A atribuição original afirmou que a, bec podem ser números não negativos, mas não declarou inequivocamente que, se fossem números, deveriam ser limitados aos valores 0 e 1. Se houver um número que seja not 0 representa true
, como é habitual, o código a seguir produziria uma resposta surpreendente :
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
a == b or c
vez dea == b or a ==c
. O problema é que lanuage falada é impreciso e, na verdade, ambas as interpretações poderiam ser válido