Você está misturando muitas coisas diferentes: instruções de controle, operadores e tipos booleanos. Cada um tem suas próprias regras.
As declarações de controle funcionam como, por exemplo, a ifdeclaração C11 6.4.8.1:
Em ambas as formas, a primeira subinstrução é executada se a expressão for diferente de 0.
while, for etc. têm a mesma regra. Isso não tem nada a ver com "verdadeiro" ou "falso".
Quanto aos operadores que supostamente estão gerando um resultado booleano, eles estão gerando um intcom valor 1 ou 0. Por exemplo, os operadores de igualdade, C11 6.5.9:
Cada um dos operadores resulta em 1 se a relação especificada for verdadeira e 0 se for falsa
Tudo isso ocorre porque C não tinha um tipo booleano até o ano de 1999 e, mesmo quando tinha um, as regras acima não foram alteradas. Portanto, ao contrário da maioria das outras linguagens de programação em que instruções e operadores geram um tipo booleano (como C ++ e Java), eles apenas geram um int, com valor zero ou diferente de zero. Por exemplo,sizeof(1==1) fornecerá 4 em C, mas 1 em C ++.
O tipo booleano real em C é nomeado _Boole requer um compilador moderno. O cabeçalho stdbool.hmacros define bool, truee false, que se expandem para _Bool, 1e 0respectivamente (para compatibilidade com C ++).
No entanto, é considerada uma boa prática de programação tratar instruções de controle e operadores como se eles realmente exigissem / gerassem um tipo booleano. Certos padrões de codificação, como MISRA-C, recomendam essa prática. Isso é:
if(ptr == NULL)em vez de if(ptr).
if((data & mask) != 0)em vez de if(data & mask).
O objetivo desse estilo é aumentar a segurança de tipo com o auxílio de ferramentas de análise estática, que por sua vez reduzem os bugs. Indiscutivelmente, esse estilo só é significativo se você usar analisadores estáticos. Embora em alguns casos isso leve a um código mais legível e autodocumentado, por exemplo
if(c == '\0')
Ótimo, a intenção é clara, o código é autodocumentado.
versus
if(c)
Mau. Pode significar qualquer coisa, e temos que procurar o tipo de cpara entender o código. É um número inteiro, um ponteiro ou um caractere?