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
| Criteria | if-else | switch |
|---|---|---|
| Expression type | Any (ranges, booleans, floats) | Integer or char only |
| Range checks | Yes: x > 10 && x < 20 | No |
| Many fixed values | Gets verbose | Clean and direct |
| Fall-through | Not possible | Built-in (use break to prevent) |
| Default/catch-all | trailing else | default label |
| Readability | Better for complex logic | Better 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?