In C, 0 is false and everything else is true. A simple rule with plenty of pitfalls. This page walks through the safe way, including C99's bool type.
int done = 0; // 0 = false while (!done) { if (condition) done = 1; // 1 = true }
#include <stdbool.h> // provides bool, true, false bool done = false; while (!done) { if (condition) done = true; }
bool is a macro for _Bool, and true/false are just 1/0. _Bool is a special type that only ever stores 0 or 1 β assigning any non-zero value gives you 1._Bool b = 42; // becomes 1 (not 42) printf("%d\n", b); // β 1 int i = 42; printf("%d\n", i); // β 42
if, while, for, ternary ?: β the rule is:if (0) { // not taken } if (-1) { // taken (non-zero is true) } if (42) { // taken } if (0.0) { // not taken } char *p = NULL; if (p) { // not taken (NULL is 0) }
==, !=, <, >, <=, and >= is always an int β either 0 or 1, not true/false.int a = 5, b = 3; int r = (a > b); // r == 1 (int) printf("%d\n", r); // 1 // Handy trick: sum the boolean results directly. int count = 0; for (int i = 0; i < n; i++) { count += (a[i] > 0); // count the positive elements }
char *p = malloc(100); if (p) { // not NULL β allocation succeeded free(p); } // equivalent if (p) { /* ... */ } if (p != NULL) { /* ... */ }
if (p); readability-first codebases prefer if (p != NULL). It's mostly a team-style choice.double x = 0.1 + 0.2; if (x == 0.3) { // false! // actual x β 0.30000000000000004 }
#include <math.h> double x = 0.1 + 0.2; if (fabs(x - 0.3) < 1e-9) { // equal within tolerance }
if (x == true) is dangerousint x = 2; // 2 is truthy but not 1 if (x == true) { // NG: true is 1 β 2 == 1 is false printf("not taken\n"); } if (x) { // OK: non-zero is true printf("taken\n"); }
if (x) or if (!x). Never compare to true. If you really need a clean 0/1, use the !!x idiom below.= vs ==if (x = 5) { // "assign 5 to x, then test 5" // always true }
if (x == 5) { // test equality }
-Wall warns on if (x = 5). Some teams use "Yoda conditions" (if (5 == x)) so a typo becomes a compile error.! precedenceif (!x && y) // (!x) && y β "x is false AND y is true" if (!(x && y)) // "at least one of x or y is false" // Different meanings β use parentheses when in doubt.
if (a & b) // bitwise AND: any common set bit if (a && b) // logical AND: both a and b are truthy // a = 4 (100), b = 3 (011) // a & b β 0 (no common bit) β falsy // a && b β true (both non-zero)
!!x to normalize to 0/1! twice collapses any value down to exactly 0 or 1.int x = 42; int normalized = !!x; // 42 β !42=0 β !0=1 β 1 int y = 0; int n2 = !!y; // 0 β !0=1 β !1=0 β 0
bool ready = !!(flags & FLAG_READY);bool b = (x != 0); reads better. Assigning to _Bool also normalizes automatically, so _Bool b = x; works the same way.&& and || evaluate left to right and stop as soon as the result is determined.if (p != NULL && p->value > 0) { // if p is NULL, p->value is not evaluated (no crash) }
if (x == 0 || y / x > 10) { // if x is 0, y/x is not evaluated (no division by zero) }
x == 0 || y / x > 10 is safe, but y / x > 10 || x == 0 can still divide by zero. Always put the guard first.// Call a function only when a flag is set. if (mode_debug && log_debug(msg)) { // log_debug runs only when mode_debug is truthy }
|| returns 0 or 1 β not the operand value. So x = get_value() || 10; does not give you a "default value"; it gives you 0 or 1.printf("%d %d %d %d\n", !0, !1, !!5, !!-3);if (x == true) trapint x = 2;, write a program that shows if (x == true) and if (x) going down different branches.0.1 + 0.2 == 0.3 evaluates to false, then fix it with an epsilon comparison.char *s and returns 1 when s is non-NULL and its first character is 'A'. Use && in the right order to avoid a NULL dereference.if β just add up the boolean-valued comparison expression inside a loop.Check your understanding of this lesson!
Only 0 is false. Any non-zero value, including negative numbers, counts as true.
stdbool.h?Since C99, including <stdbool.h> gives you bool, true, and false.
if (x) evaluate x as true?true constantIn C, 0 is false and anything non-zero β including negative numbers and non-NULL pointers β is true.