In C e in alcuni linguaggi simili, confrontare espressioni booleane per l'uguaglianza falseo trueè un'abitudine pericolosa.
In C qualsiasi espressione scalare (numerica o puntatore) può essere utilizzata in un contesto booleano, ad esempio come condizione di ifun'istruzione. La regola C if (cond)è equivalente a if (cond != 0)- cioè, zero è falso e qualsiasi valore diverso da zero è vero. Se condè di tipo puntatore, 0viene trattato come una costante puntatore null; if (ptr)significa if (ptr != NULL).
Ciò significa che
if (cond)
e
if (cond == true)
non significa la stessa cosa . Il primo è vero se condè diverso da zero; il secondo è vero solo se è uguale a true, che in C (se hai #include <stdbool.h>) è semplicemente 1.
Ad esempio, la isdigit()funzione dichiarata in <ctype.h>restituisce un intvalore, 0se l'argomento è una cifra, diverso da zero se non lo è. Può tornare 42per indicare che la condizione è vera. Il confronto 42 == truefallirà.
Succede che 0è l'unico valore considerato falso, quindi il confronto per l'uguaglianza falsefunzionerà; if (!cond)e if (cond == false)fare la stessa cosa. Ma se ne trarrai vantaggio, devi ricordare che il confronto con falseè ok e il confronto con truenon lo è. Peggio ancora, il confronto con truefunzionerà per la maggior parte del tempo (ad esempio, l'uguaglianza e gli operatori relazionali producono sempre 0o 1). Ciò significa che qualsiasi bug che introduci usando questo potrebbe essere difficile da rintracciare. (Non preoccuparti, verranno visualizzati non appena avrai demo del codice su un client importante.)
C ++ ha regole leggermente diverse; ad esempio, il suo booltipo è un po 'più strettamente integrato nel linguaggio e si if (cond)converte condin tipo bool. Ma l'effetto è (principalmente) lo stesso.
Alcune altre lingue hanno ciò che si potrebbe definire booleani meglio educati, in modo tale che cond == truee cond == false(o qualunque sia la sintassi) è sicuro. Anche così, ogni lingua che ho visto ha un operatore noto !; è lì, quindi potresti anche usarlo. L'utilizzo cond == falsepiuttosto che !condo not condnon migliora, secondo me, la leggibilità. (È vero che il !personaggio può essere difficile da vedere a colpo d'occhio; a volte aggiungo uno spazio dopo !per evitarlo.)
E spesso puoi evitare il problema e migliorare la chiarezza riorganizzando leggermente il codice. Ad esempio, anziché:
if (!cond) {
do_this();
}
else {
do_that();
}
potresti scrivere:
if (cond) {
do_that();
}
else {
do_this();
}
Non è sempre meglio, ma non fa male cercare opportunità dove si trova.
Riepilogo: in C e C ++, i confronti tra uguaglianza truee stile falsepericoloso, eccessivamente prolisso e scadente. In molte altre lingue, tali confronti potrebbero non essere pericolosi, ma sono ancora troppo prolissi e di scarsa qualità.