Pensez aux booléens, pas aux morceaux
En résumé, la solution de votre professeur est meilleure (mais toujours fausse, à proprement parler, voir plus loin) car elle utilise des opérateurs booléens au lieu d'opérateurs au niveau du bit et traite les booléens comme des entiers. L'expression c==1
pour représenter "c est vrai" est incorrecte car si c peut être un nombre (selon l'affectation indiquée), alors toute valeur non nulle de c doit être considérée comme représentative true
.
Consultez cette question pour savoir pourquoi il est préférable de ne pas comparer les booléens à 0 ou 1, même lorsque cela est sûr.
Une très bonne raison de ne pas l'utiliser xor
est qu'il s'agit de l' opération ou de l'exclusivité bit à bit . Il se trouve que cela fonctionne dans votre exemple, car le côté gauche et le côté droit sont des expressions booléennes qui se convertissent en 1 ou 0 (voir à nouveau 1 ).
Le booléen exclusif ou est en fait !=
.
Décomposer l'expression
Pour mieux comprendre la solution de votre professeur, il est plus facile de remplacer les opérateurs booléens par leurs équivalents de "jeton alternatif", ce qui en fait un code C ++ mieux réductible (à mon humble avis) et complètement équivalent: en utilisant 'not' for '!' et 'et' pour '&&' vous obtenez
(not a and not b) != c
Malheureusement, il n'y a aucun exclusive_or
opérateur logique autre que not_eq
, ce qui n'est pas utile dans ce cas.
Si nous décomposons l'expression du langage naturel:
Soit a et b sont faux ou c est vrai, mais pas les deux.
d'abord dans une phrase sur les propositions booléennes A et B:
Soit A ou B, mais pas les deux.
cela se traduit par A != B
(uniquement pour les booléens, pas pour les types A et B).
Alors la proposition A était
a et b sont tous deux faux
qui peut être déclaré comme
a est faux et b est faux
qui se traduit par (not a and not b)
, et enfin
c est vrai
Ce qui se traduit simplement par c
. En les combinant, vous obtenez à nouveau (not a and not b) != c
.
Pour plus d'explications sur le fonctionnement de cette expression, je m'en remets aux tables de vérité que d'autres ont données dans leurs réponses.
Vous vous trompez tous les deux
Et si je peux me moquer de moi: l'affectation d'origine a déclaré que a, b et c peuvent être des nombres non négatifs, mais n'a pas déclaré sans ambiguïté que s'il s'agissait de nombres, ils devraient être limités aux valeurs 0 et 1. Si un nombre quelconque est pas 0 représente true
, comme c'est la coutume, alors le code suivant donnerait une réponse surprenante :
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
lieu dea == b or a ==c
. Le problème est que le langage parlé est imprécis et que les deux interprétations pourraient être valides