C Basics · beginner · ~8 min

if / else

Branch on boolean conditions.

Overview

if makes a decision based on a condition. The body runs when the condition is true; an optional else body runs when it's false. You can chain conditions with else if. Conditions are usually comparisons (x > 0, c == '\n') or boolean expressions built with && (and), || (or), ! (not).

Why it matters

Branching is one of the three building blocks of all algorithms (the others being sequence and iteration). Every non-trivial program has to make decisions: did the file open succeed? Is the user's input valid? Have we reached the end of the buffer? if/else is the syntax that turns those decisions into executable code.

Core concepts

Truthiness. In C, any non-zero value is true; zero is false. So if (ptr) and if (ptr != NULL) mean the same thing — pick the style your team prefers. Short-circuit evaluation. a && b does not evaluate b if a is false. This lets you write if (p && p->len > 0) safely. Ternary operator. cond ? a : b is a single expression form of if/else — useful but easy to overuse.

Syntax notes

if (cond) {
    /* runs when cond is non-zero */
} else if (other_cond) {
    /* runs when first cond was zero AND other_cond is non-zero */
} else {
    /* runs when nothing above matched */
}

Braces are optional for single statements but always use them — it prevents the famous Apple goto fail; SSL bug.

Lesson

if (cond) { ... } else if (cond2) { ... } else { ... } — the standard branching shape. The condition is any scalar expression: zero is false, anything else is true.

Use {} even for single-line branches. Style guides differ, but most security teams require it because adding a second statement under a brace-less if is a famous bug source (Apple's "goto fail" SSL bug from 2014).

Code examples

if (n < 0) {
    return -1;
} else if (n == 0) {
    return 0;
} else {
    return n * 2;
}

Common mistakes

  • Missing braces — if (cond) action1(); action2(); runs action2 unconditionally.
  • Assignment in a condition: if (x = 1) always runs. Write if (x == 1).

Debugging tips

If a branch never runs, print the condition's value: printf("cond = %d\n", x > 0); reveals whether your logic matches your assumptions. Beware = (assignment) vs == (comparison): if (x = 5) always runs and quietly sets x to 5. Modern compilers warn about this — enable -Wall.

Memory safety

When testing a pointer before using it, the test goes first: if (p && p->field) is safe; if (p->field && p) dereferences p even if it's NULL. Always null-check before dereference, never after.

Real-world uses

Input validation (if (!valid_username(name)) return -1;), error handling (if (fp == NULL) goto cleanup;), feature flags, permission checks, retry logic — every meaningful piece of business logic in any program is a chain of conditions.

Practice tasks

  1. Write a function int classify(int n) returning 1 for positive, 0 for zero, -1 for negative. 2. Combine two conditions with && to check a value is in a range. 3. Replace a 3-line if/else with the ternary operator and decide which version is clearer.

Summary

if/else lets you steer execution based on data. Always brace your branches, use == for comparison (not =), and put the null-check before the dereference. Master these three habits and most beginner branching bugs disappear.

Practice with these exercises