if/else, for, while, and do-while use the syntax that essentially every later C-family language (C++, Java, JavaScript, Go, Rust) copied. C's truthiness is purely numeric: any condition evaluates to an int, where 0 means false and any nonzero value means true — the original C standard had no dedicated boolean type at all. C99 added _Bool and the bool alias via stdbool.h; C23 (2024) finally promoted bool, true, and false to genuine language keywords rather than macros.
if, for, while: the syntax nearly everyone copied
This exact shape — parenthesized condition, braced body — is the direct ancestor of the same syntax in C++, Java, JavaScript, and many other languages.
for (int i = 0; i < 5; i++) {
printf("%d\n", i);
}
int n = 0;
while (n < 3) {
n++;
}
do {
printf("runs at least once\n");
} while (0); // condition checked AFTER the body runs, unlike whileTruthiness before C99: purely numeric
Without a real boolean type, "true" and "false" were just conventions — any expression producing 0 was treated as false, anything else as true, including in places that might surprise a newcomer, like the result of an assignment.
int x = 5;
if (x) { // nonzero — treated as true
printf("truthy\n");
}
if (x - 5) { // 0 — treated as false
printf("never runs\n");
}bool: added in C99, finally a real keyword in C23
C99 introduced _Bool as an actual type, with stdbool.h providing bool/true/false as convenient macro aliases for it. C23 (2024) went further and made bool, true, and false genuine reserved keywords in the language itself — no header include required to use them.
#include <stdbool.h> // needed pre-C23; bool is a built-in keyword since C23
bool isValid = true;
if (isValid) {
printf("valid\n");
}