Control Flow: Conditional Statements

Control which code runs using if, else-if, nested conditions, and switch-case statements.

if Statement

The if statement runs a block of code only when its condition evaluates to true. If the condition is false, the block is skipped entirely and execution continues after it.

if Statement

The condition inside the parentheses must be a boolean expression, any non-zero value is treated as true.

  • Syntax: if (condition) { /* body */ }
  • The braces are optional for a single-statement body, but always including them prevents bugs
  • Condition can be any expression: comparison, logical, or even an integer
  • Zero = false, any non-zero = true

if Statement

C++

The message prints only when temperature exceeds 30.

if-else Statement

Adding else provides an alternative block that runs when the condition is false. Exactly one of the two blocks always executes.

if-else

if-else guarantees one of two paths is always taken, use it whenever there are exactly two outcomes.

  • If the condition is true, the if block runs; otherwise the else block runs
  • Never both blocks execute in the same run
  • The else block has no condition of its own
  • Nesting if-else inside another if-else creates multi-level branching

if-else Statement

C++

Exactly one branch runs depending on the score.

else-if Ladder

When you have more than two mutually exclusive outcomes, chain else if clauses. The conditions are tested top to bottom and only the first matching block executes.

else-if Ladder

Order matters: put the most specific or most common conditions first so the ladder exits as early as possible.

  • Each else-if has its own condition
  • As soon as one condition is true, the rest are skipped
  • The trailing else is optional; it acts as a catch-all
  • For a large number of fixed integer values, switch-case is often cleaner

else-if Ladder: Grade Calculator

C++

The first condition that matches wins; all others are skipped.

Nested if-else

You can place an if statement inside another if or else block to check further conditions only when an outer condition is true.

Nested if-else

The dangling-else rule: an else always pairs with the nearest preceding unmatched if, use braces to make the pairing explicit.

  • Inner if only runs if the outer condition is already satisfied
  • Always use braces even for single-line bodies to avoid dangling-else bugs
  • More than two levels of nesting is a sign the logic should be refactored
  • Consider early-return or logical operators (&&) to flatten deep nesting

Nested if-else

C++

The inner condition is only checked once the outer condition passes.

switch-case Statement

switch compares one integer or character expression against a list of constant case labels. It is cleaner than a long else-if ladder when testing a single variable against many fixed values.

switch-case

switch only works with integer and character types (int, char, enum) not float, double, or string.

  • Syntax: switch (expression) { case value: ... }
  • Each case label must be a compile-time constant
  • Execution jumps directly to the matching case
  • Without break, execution falls through to the next case automatically

switch-case

C++

Jump directly to the matching case label.

break in switch

Without break, execution falls through from the matched case into every subsequent case until the closing brace or a break is encountered. This is almost always a bug, add break at the end of every case.

break

Fall-through without break is a common source of bugs always end each case with break unless intentional fall-through is documented.

  • break exits the switch block immediately
  • Without break, all cases after the match run until a break or end of switch
  • Intentional fall-through (grouping cases) should be clearly commented
  • Modern compilers warn about implicit fall-through: -Wimplicit-fallthrough

Fall-through Without break

C++

x matches case 2, then falls through to case 3 because there is no break.

default in switch

The default label runs when none of the case values match the switch expression. It is optional but strongly recommended as a safety net.

default

Always include a default case, it catches unexpected values and makes the switch exhaustive, preventing silent no-ops.

  • default does not need a constant value, it matches anything not handled above
  • Conventionally placed last, but can appear anywhere in the switch
  • Break after default is optional (nothing follows it), but include it for consistency
  • Without default, an unmatched switch silently does nothing

switch with default

C++

default catches any grade letter not listed as a case.

Grouping Cases with Fall-through

Sometimes you want multiple case labels to share the same body. Stack them without a body in between, this is intentional, documented fall-through.

Grouping Cases

C++

Months 4, 6, 9, and 11 all share the same 30-day output.

if-else vs switch: When to Use Each

Criteriaif-elseswitch
Expression typeAny (ranges, booleans, floats)Integer or char only
Range checksYes: x > 10 && x < 20No
Many fixed valuesGets verboseClean and direct
Fall-throughNot possibleBuilt-in (use break to prevent)
Default/catch-alltrailing elsedefault label
ReadabilityBetter for complex logicBetter for discrete value dispatch

Knowledge Check

1. What does an if statement do when its condition is false?

2. Which keyword handles a fallback case when no if or else-if condition matches?

3. In a switch statement, what happens without a break?

4. Which types can be used as a switch expression in C++?

5. What is an else-if ladder best used for?

6. In a nested if-else, which if does an else pair with?