W języku C i niektórych podobnych językach porównywanie wyrażeń boolowskich w celu zapewnienia równości false
lub true
niebezpiecznego 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 if
instrukcji. 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 cond
jest typu wskaźnika, 0
jest 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 cond
jest 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 int
wartość, 0
jeśli argument jest cyfrą, niezerową, jeśli nie jest. Może powrócić, 42
aby wskazać, że warunek jest spełniony. Porównywanie 42 == true
zakończy się niepowodzeniem.
Zdarza się, że 0
jest to jedyna wartość uważana za fałszywą, więc porównanie równości false
zadziała; if (!cond)
i if (cond == false)
rób to samo. Ale jeśli zamierzasz to wykorzystać, musisz pamiętać, że porównywanie false
jest w porządku, a porównywanie true
nie. Co gorsza, w porównaniu do true
będzie działać przez większość czasu (na przykład operatory równości i relacyjne zawsze dają albo 0
albo 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 bool
typ jest nieco ściślej zintegrowany z językiem i if (cond)
konwertuje się cond
na 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 == true
i cond == false
(lub jakakolwiek inna składnia się zdarzy) jest bezpieczne. Mimo to każdy język, który widziałem, ma operatora not
lub !
; jest tam, więc równie dobrze możesz go użyć. Używanie cond == false
zamiast !cond
lub 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 true
i false
są 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.