TRT
Sign in

Foundations · Module 1 · Lesson 1 of 7

Making Decisions: if, else if, and else

Learn how to branch program flow with if, else if, and else, use comparison and logical operators, and trace conditional execution step by step.

FreeAbout 15 minutes

By the end you can

  • Write if, else if, and else statements to branch program flow
  • Use comparison operators (==, !=, <, >, <=, >=) in conditions
  • Combine conditions with logical operators (&&, ||, !)
  • Trace conditional execution through a trace

Builds on Reading User Input and Building Simple Programs.

01 · A question first

Your program asks the user for their age. If they are 18 or older, print "Adult". Otherwise print "Minor". But what if they are exactly 18? What if they are 65 or older and should get a senior discount? How does the computer choose which path to take, and what happens when two conditions could both be true?

Make a guess, then step through the trace below to check it.

02 · Watch it run

Tracing an if-else if-else chain with age categoriesstep 1 of 3
int age = 25;if (age >= 65) {    printf("Senior\n");} else if (age >= 18) {    printf("Adult\n");} else {    printf("Minor\n");}
  1. slot 0age: 25(looked at in this step)
  2. slot 1condition1: false
  3. slot 2condition2: unchecked
  4. slot 3output: none

Variable age is set to 25. The first condition (age >= 65) is checked.

Machine work: compare 25 >= 65 -> false

03 · The idea

Start with the problem

Every program you have written so far executes in a straight line from top to bottom: line 1 runs, then line 2, then line 3, until main returns 0. That works for a simple calculator formula, but real programs must react differently depending on the data they receive.

Suppose you are writing a grading program that reads a student's exam score (0 to 100) and prints a letter grade:

  • 90 or above prints "Grade: A"
  • 80 to 89 prints "Grade: B"
  • 70 to 79 prints "Grade: C"
  • Below 70 prints "Grade: F"

Without a way to choose between paths, your program would print all four grades every time it ran. Choosing which statements to execute and which to skip based on a runtime value is called branching or conditional control flow, and the fundamental tool for it in C is the if statement.

How the idea works

An if statement evaluates a condition inside parentheses (...). If the condition is true, the block of statements inside the curly braces \{...\} executes. If the condition is false, the CPU jumps right past the closing brace without running a single line inside the block.

In the trace above, age starts at 25. In step 1, the CPU evaluates the first condition age >= 65. Because 25 >= 65 is false, the program skips the "Senior " block completely and moves to the else if (age >= 18) test on line 3. In step 2, 25 >= 18 evaluates to true, so step 3 runs printf("Adult "); and then jumps past the trailing else block to finish the chain.

How C represents true and false

Unlike languages that were designed with a separate boolean type from day one, C represents truth values as plain integers:

  • 0 means false.
  • Any non-zero integer (1, 42, -7) means true.

When you write a comparison using one of C's six relational operators, the operator compares the two numbers and produces the integer 1 if the relationship holds, or 0 if it does not:

OperatorMeaningExample (a = 5, b = 3)Evaluated integer result
==Equal toa == b0 (false)
!=Not equal toa != b1 (true)
<Strictly less thana < b0 (false)
>Strictly greater thana > b1 (true)
<=Less than or equal toa <= b0 (false)
>=Greater than or equal toa >= b1 (true)

Modern C (since C99) also provides <stdbool.h>, which defines the type bool and the constants true (1) and false (0), but under the hood every if (...) test simply checks whether the expression inside the parentheses is non-zero.

Choosing between two paths with else

When you need one action if a condition holds and a fallback action whenever it does not, attach an else block:

c
if (age >= 18) {
    printf("Adult");
} else {
    printf("Minor");
}

The if branch and the else branch are mutually exclusive and exhaustive: for any value of age, the CPU is guaranteed to execute one branch and skip the other.

Chaining multiple conditions with else if

When a decision has three or more outcomes, chain tests together with else if:

c
#include <stdio.h>
 
int main(void) {
    int score = 84;
 
    if (score >= 90) {
        printf("Grade: A");
    } else if (score >= 80) {
        printf("Grade: B");
    } else if (score >= 70) {
        printf("Grade: C");
    } else {
        printf("Grade: F");
    }
    return 0;
}

Combining conditions with logical operators

Often a single decision depends on two or more facts at once—for example, checking that a score lies between 0 and 100. C provides three logical operators to combine conditions:

  • Logical AND (&&): cond1 && cond2 is true (1) only when both conditions are true.
  • Logical OR (||): cond1 || cond2 is true (1) when at least one condition is true.
  • Logical NOT (!): !cond flips truth: !0 becomes 1, and !non_zero becomes 0.
c
if (score >= 0 && score <= 100) {
    printf("Valid score");
}
 
if (day == 6 || day == 7) {
    printf("Weekend");
}

Why it is correct

Two rules make conditional chains predictable and safe:

  1. Top-down first-match execution: In an if / else if / else ladder, conditions are tested strictly from top to bottom. The moment one condition evaluates to true, its block runs and every remaining branch in the chain is skipped, even if a later condition (score >= 70 when score is 84) would also be true. That is why ordering matters: you must place the most restrictive condition (score >= 90, or age >= 65 in the trace above) first. If you wrote if (age >= 18) before else if (age >= 65), an age of 70 would match age >= 18 first and print "Adult", making the "Senior" branch dead code that can never run.
  2. Short-circuit evaluation: Both && and || evaluate their left operand first and stop early if the overall answer is already decided. In A && B, if A is false (0), the whole AND expression must be false, so C never evaluates B. In A || B, if A is true (1), the whole OR expression must be true, so C never evaluates B. Programmers rely on short-circuiting every day to guard dangerous operations, such as checking if (denom != 0 && numer / denom > 5) so the division never executes when denom is zero.

What it costs

At the hardware level, an if statement compiles into two cheap CPU instructions: a comparison (cmp) that sets status flags in the processor, followed by a conditional jump (je, jne, jl, jge) that changes the instruction pointer if a branch is skipped.

Comparing two registers takes less than a nanosecond (1 CPU cycle). Modern processors also contain a branch predictor that guesses which path an if statement will take so the CPU can keep its pipeline full. When a branch is predictable, it costs almost nothing; when a branch flips randomly on every check, a misprediction flushes the CPU pipeline and costs roughly 15 to 20 cycles (~5 nanoseconds).

Pitfalls and variations

MistakeWhat goes wrongFix
if (age = 18)Assigns 18 to age and always evaluates to true (18 != 0)Use the equality operator if (age == 18)
Writing if (18 <= age <= 65)C parses this as (18 <= age) <= 65, which compares 0 or 1 against 65 and is always trueCombine two comparisons with &&: if (age >= 18 && age <= 65)
Omitting curly braces {} on multi-line bodiesOnly the first statement after if (...) belongs to the branch; the second line runs unconditionallyAlways wrap if and else bodies in {} braces
Putting a semicolon right after if (x > 0);The semicolon acts as an empty body, so the {...} block after it always runsNever put a ; between if (...) and {

Where it is used

Every piece of software relies on conditional branching: operating system kernels check whether a process has permission to open a file, network servers validate packet headers before parsing payloads, and financial engines verify account balances before authorizing transfers.

In the next lesson, you will combine conditions with loops (for and while) so your program can repeat work thousands of times without duplicating code.

04 · Prove it

Question 1 of 3 · answer from memory

If age is 70, which block executes in the trace above?

05 · Practice

Something wrong with this lesson? Report a problem

Not started

Sign in to save your learning progress.

Sign in to save