W języku C i niektórych podobnych językach porównywanie wyrażeń boolowskich w celu zapewnienia równości falselub trueniebezpiecznego nawyku.
W języku C dowolne wyrażenie skalarne (numeryczne lub wskaźnikowe) może być użyte w kontekście logicznym, na przykład jako warunek ifinstrukcji. Reguła C if (cond)jest równoważna if (cond != 0)- tzn. Zero jest fałszem, a każda wartość niezerowa jest prawdą. Jeśli condjest typu wskaźnika, 0jest traktowane jako stała wskaźnika zerowego; if (ptr)oznacza if (ptr != NULL).
To znaczy że
if (cond)
i
if (cond == true)
nie oznaczają tego samego . Pierwszy jest prawdziwy, jeśli condjest niezerowy; druga jest prawdziwa tylko wtedy, gdy jest równa true, która w C (jeśli masz #include <stdbool.h>) jest po prostu 1.
Na przykład isdigit()funkcja zadeklarowana w <ctype.h>zwraca intwartość, 0jeśli argument jest cyfrą, niezerową, jeśli nie jest. Może powrócić, 42aby wskazać, że warunek jest spełniony. Porównywanie 42 == truezakończy się niepowodzeniem.
Zdarza się, że 0jest to jedyna wartość uważana za fałszywą, więc porównanie równości falsezadziała; if (!cond)i if (cond == false)rób to samo. Ale jeśli zamierzasz to wykorzystać, musisz pamiętać, że porównywanie falsejest w porządku, a porównywanie truenie. Co gorsza, w porównaniu do truebędzie działać przez większość czasu (na przykład operatory równości i relacyjne zawsze dają albo 0albo 1). Oznacza to, że wszelkie błędy, które wprowadzisz, używając tego nadal mogą być trudne do wyśledzenia. (Nie martw się, pojawią się, gdy tylko zadasz kod ważnemu klientowi).
C ++ ma nieco inne reguły; na przykład jego booltyp jest nieco ściślej zintegrowany z językiem i if (cond)konwertuje się condna typ bool. Ale efekt jest (przeważnie) taki sam.
Niektóre inne języki mają coś, co można by nazwać lepiej zachowującymi się wartościami logicznymi, na przykład cond == truei cond == false(lub jakakolwiek inna składnia się zdarzy) jest bezpieczne. Mimo to każdy język, który widziałem, ma operatora notlub !; jest tam, więc równie dobrze możesz go użyć. Używanie cond == falsezamiast !condlub not cond, moim zdaniem, nie poprawia czytelności. (Prawdą jest, że !postać może być trudna do zobaczenia na pierwszy rzut oka; czasem dodaję spację, !aby tego uniknąć).
Często można uniknąć tego problemu i poprawić przejrzystość, zmieniając nieco kod. Na przykład zamiast:
if (!cond) {
do_this();
}
else {
do_that();
}
możesz napisać:
if (cond) {
do_that();
}
else {
do_this();
}
Nie zawsze jest to lepsze, ale nie zaszkodzi szukać okazji tam, gdzie jest.
Podsumowanie: W C i C ++ porównania równości truei falsesą niebezpieczne, zbyt szczegółowe i kiepskie. W wielu innych językach takie porównania mogą nie być niebezpieczne, ale wciąż są zbyt szczegółowe i kiepskie.