Myśl booleany, a nie bity
Podsumowując, rozwiązanie twojego profesora jest lepsze (ale nadal błędne, ściśle mówiąc, patrz dalej w dół), ponieważ używa operatorów logicznych zamiast operatorów bitowych i traktuje logiczne jako liczby całkowite. Wyrażenie c==1
reprezentujące „c jest prawdą” jest niepoprawne, ponieważ jeśli c może być liczbą (zgodnie z podanym przypisaniem), wówczas każdą niezerową wartość c należy traktować jako reprezentującą true
.
Zobacz pytanie, dlaczego lepiej nie porównywać boolanów z 0 lub 1, nawet jeśli jest to bezpieczne.
Jednym z bardzo dobrych powodów, aby nie używać, xor
jest to, że jest to nieco wykluczająca operacja. Zdarza się, że działa w twoim przykładzie, ponieważ zarówno lewa strona, jak i prawa strona są wyrażeniami logicznymi, które są konwertowane na 1 lub 0 (zobacz ponownie 1 ).
Wartość logiczna wyłączna - lub w rzeczywistości jest !=
.
Podział wyrazu
Aby lepiej zrozumieć rozwiązanie twojego profesora, najłatwiej jest zastąpić operatory logiczne ich ekwiwalentami „alternatywnego tokena”, co czyni go lepszym do redable (imho) i całkowicie równoważnym kodem C ++: Używanie „nie” dla ”!” oraz „i” za „&&”
(not a and not b) != c
Niestety nie ma innego exclusive_or
operatora logicznego niż not_eq
, co w tym przypadku nie jest pomocne.
Jeśli rozbimy naturalne wyrażenie językowe:
Albo a i b są fałszywe, lub c jest prawdą, ale nie jedno i drugie.
najpierw do zdania o zdaniach boolowskich A i B:
Albo A albo B, ale nie oba.
przekłada się to na A != B
(tylko dla booleanów, nie dla żadnego typu A i B).
Wtedy była twierdzenie A.
oba a i b są fałszywe
które można określić jako
a jest fałszem, a b jest fałszem
co przekłada się na (not a and not b)
i wreszcie
c jest prawdą
Co po prostu przekłada się na c
. Łącząc je otrzymujesz ponownie (not a and not b) != c
.
W celu dalszego wyjaśnienia, jak to wyrażenie działa, odsyłam do tabel prawdy, które inni podali w swoich odpowiedziach.
Oboje się mylicie
I jeśli mogę wytropić: Pierwotny przydział stwierdził, że a, b i c mogą być liczbami nieujemnymi, ale nie stwierdził jednoznacznie, że jeśli byłyby liczbami, powinny być ograniczone do wartości 0 i 1. Jeśli dowolna liczba, która jest nie 0 oznacza true
, jak zwykle, następujący kod dałby zaskakującą odpowiedź :
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
zamiasta == b or a ==c
. Problem polega na tym, że mówiony język jest nieprecyzyjny i faktycznie obie interpretacje mogą być poprawne