Está mezclando muchas cosas diferentes: declaraciones de control, operadores y tipos booleanos. Cada uno tiene sus propias reglas.
Las declaraciones de control funcionan como, por ejemplo, la ifdeclaración, C11 6.4.8.1:
En ambas formas, la primera subenunciación se ejecuta si la expresión se compara con desigual a 0.
while, foretc. tienen la misma regla. Esto no tiene nada que ver con "verdadero" o "falso".
En cuanto a los operadores que supuestamente están produciendo un resultado booleano, en realidad están produciendo un intvalor de 1 o 0. Por ejemplo, los operadores de igualdad, C11 6.5.9:
Cada uno de los operadores produce 1 si la relación especificada es verdadera y 0 si es falsa
Todo lo anterior se debe a que C no tenía un tipo booleano hasta el año 1999, e incluso cuando obtuvo uno, las reglas anteriores no se cambiaron. Entonces, a diferencia de la mayoría de los otros lenguajes de programación donde las declaraciones y los operadores producen un tipo booleano (como C ++ y Java), solo producen un int, con un valor cero o no cero. Por ejemplo, sizeof(1==1)dará 4 en C pero 1 en C ++.
El tipo booleano real en C se nombra _Booly requiere un compilador moderno. Las cabeceras de las stdbool.hmacros Define bool, truey false, que se expanden para _Bool, 1y 0respectivamente (para la compatibilidad con C ++).
Sin embargo, se considera una buena práctica de programación tratar las declaraciones de control y los operadores como si realmente requirieran / produjeran un tipo booleano. Ciertos estándares de codificación como MISRA-C recomiendan esta práctica. Es decir:
if(ptr == NULL)en lugar de if(ptr).
if((data & mask) != 0)en lugar de if(data & mask).
El objetivo de dicho estilo es aumentar la seguridad de los tipos con la ayuda de herramientas de análisis estático, lo que a su vez reduce los errores. Podría decirse que este estilo solo es significativo si usa analizadores estáticos. Aunque en algunos casos conduce a un código autodocumentado más legible, por ejemplo
if(c == '\0')
Bien, la intención es clara, el código se autodocumenta.
versus
if(c)
Malo. Podría significar cualquier cosa, y tenemos que buscar el tipo de cpara entender el código. ¿Es un número entero, un puntero o un carácter?