Pensa ai booleani, non ai bit
In sintesi, la soluzione del tuo professore è migliore (ma è ancora sbagliata, a rigor di termini, vedi più in basso) perché utilizza operatori booleani invece di operatori bit a bit e tratta i valori booleani come numeri interi. L'espressione c==1
per rappresentare "c è vera" non è corretta perché se c può essere un numero (secondo l'assegnazione dichiarata), qualsiasi valore diverso da zero di c deve essere considerato rappresentativo true
.
Vedi questa domanda sul perché è meglio non confrontare i valori booleani con 0 o 1, anche quando è sicuro farlo.
Un ottimo motivo per non usare xor
è che si tratta dell'esclusiva o dell'operazione bit-saggia . Succede nel tuo esempio perché sia il lato sinistro che il lato destro sono espressioni booleane che vengono convertite in 1 o 0 (vedi di nuovo 1 ).
L'esclusiva booleana, o in effetti lo è !=
.
Abbattere l'espressione
Per comprendere meglio la soluzione del tuo professore, è più semplice sostituire gli operatori booleani con i loro equivalenti "token alternativi", che lo trasformano in un codice C ++ redable (imho) e completamente equivalente: usando 'not' for '!' e 'e' per '&&' ottieni
(not a and not b) != c
Sfortunatamente, non esiste un exclusive_or
operatore logico diverso da quello not_eq
, il che non è utile in questo caso.
Se suddividiamo l'espressione del linguaggio naturale:
O aeb sono entrambi falsi oppure c è vero, ma non entrambi.
prima in una frase sulle proposizioni booleane A e B:
A o B, ma non entrambi.
questo si traduce in A != B
(solo per i booleani, non per qualsiasi tipo A e B).
Quindi la proposizione A fu
aeb sono entrambi falsi
che può essere dichiarato come
a è falso e b è falso
che si traduce in (not a and not b)
, e infine
c è vero
Che si traduce semplicemente in c
. Combinandoli si ottiene di nuovo (not a and not b) != c
.
Per ulteriori spiegazioni su come funziona questa espressione, rimando alle tabelle di verità che altri hanno fornito nelle loro risposte.
Sbagli entrambi
E se potessi puntualizzare: l'assegnazione originale affermava che a, bec possono essere numeri non negativi, ma non affermava in modo inequivocabile che se fossero numeri, dovrebbero essere limitati ai valori 0 e 1. Se qualsiasi numero che è non 0 rappresenta true
, come è consuetudine, quindi il seguente codice darebbe una risposta sorprendente :
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
anzichéa == b or a ==c
. Il problema è che il linguaggio parlato è impreciso e in realtà entrambe le interpretazioni potrebbero essere valide