Skip to content
Lesson 6 of 15

Step 1 of 5 · Reading · ~4 min

Learn

Control Flow

Conditionals

By the end of this lesson you can make a program choose between several outputs with an if / else if / else chain, put the checks in an order that gives the right answer, and avoid the C++ traps that compile cleanly but choose the wrong branch.

if, else if, else

An if statement runs its block only when its condition is true. An else if is tested only when every check above it was false, and a final else catches whatever is left. Exactly one block in the chain runs: the first one whose condition is true.

int temp = 12;
if (temp < 0) {
    std::cout << "freezing\n";
} else if (temp < 15) {
    std::cout << "cold\n";
} else {
    std::cout << "warm\n";
}
// prints: cold

Trace it: 12 < 0 is false, so C++ moves on; 12 < 15 is true, so it prints cold and skips the rest. Once a branch has won, the later checks are never looked at. Always use braces, even for one statement: an if without braces controls exactly one statement, whatever the indentation suggests.

Testing divisibility with %

a % b is the remainder from the Numbers lesson, so "a is a multiple of b" is written a % b == 0:

expressionvaluemultiple?
12 % 40yes
14 % 42no
0 % 40yes, 0 is a multiple of every number
-8 % 40yes
-6 % 4-2no, and the remainder is negative

That last row matters: for a negative number the remainder can be negative, so test == 0 or != 0, never == 1 or > 0.

Order matters: most specific first

Because the first true branch wins, a rule that covers a special case must come before the general rule that also matches it. The leap-year rule shows this. Years divisible by 4 are leap years, except those divisible by 100, except those divisible by 400:

int year = 1900;
if (year % 400 == 0) {
    std::cout << "leap\n";
} else if (year % 100 == 0) {
    std::cout << "common\n";
} else if (year % 4 == 0) {
    std::cout << "leap\n";
} else {
    std::cout << "common\n";
}
yearbranch takenoutput
2000% 400leap
1900% 100common
2024% 4leap
2023elsecommon

Put the % 4 test first and 1900 prints leap: 1900 is also divisible by 4, and that check wins before the exception is ever tested. It compiles, it looks reasonable, and it is wrong. To require two conditions in one test, use && (both true) or || (either true): year % 4 == 0 && year % 100 != 0.

Chain versus separate ifs

int x = 20;
if (x % 2 == 0) { std::cout << "even\n"; }
if (x % 10 == 0) { std::cout << "round\n"; }
// prints two lines: even, round

Two separate ifs are two independent questions, and both can print. When the output must be exactly one line, join the tests with else if so that only one branch can run.

Two traps that compile

  • if (x = 5) assigns 5 and then tests it, so it is always true. Comparison is ==.
  • if (x % 3) means "the remainder is non-zero", which is not divisible. Any non-zero integer converts to true. Write the comparison out.

switch

switch (c) { case 'y': ... break; default: ... } picks a branch by an exact integer or char value. It cannot test ranges or remainders and it does not accept std::string; leaving out break makes execution fall into the next case. Since C++17 an if can also start with an initializer scoped to the if/else: if (int r = n % 7; r != 0) { ... }.

Common mistakes

  • General check before specific: testing a single divisor before the combined case, so a number matching both takes the wrong branch. 30 and 45 would print the wrong word.
  • Separate ifs instead of else if: one input prints two or three lines instead of one.
  • Truthiness backwards: if (n % 3) is true when n is not a multiple of 3.
  • Forgetting 0 and negatives: 0 is a multiple of every number and -9 % 3 is 0, so both are classified like positive multiples. A test like % 3 == 1 gets negatives wrong.

Your exercise

Classify one integer FizzBuzz-style. The starter reads n and prints it; replace that print with a single chain so exactly one line comes out. The most common mistake is putting the checks in the wrong order.

Up nextLoopsControl Flow

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…