Skip to main content

    Lesson 4 • Beginner

    Control Flow

    By the end of this lesson you'll be able to make your C++ programs decide what to do — branching with if/else if/else, choosing values with the ternary ?:, matching exact values with switch, and combining conditions with &&, || and !.

    What You'll Learn

    • Branch your code with if, else if and else
    • Pick a value in one line with the ternary ?: operator
    • Match exact values with switch / case / break / default
    • Use fall-through deliberately (and avoid it by accident)
    • Nest conditions and combine them with &&, || and !
    • Scope a variable to one test with if (init; condition) (C++17)

    💡 Real-World Analogy

    Control flow is the signpost at a fork in the road. Your program walks up to a junction, reads a condition ("is it raining?"), and takes the matching path. An if/else if/else chain is a row of signs checked in order — you follow the first one that points your way and ignore the rest. A switch is the departures board at a station: it looks up your exact destination and sends you straight to the right platform. Without these signposts, the program can only ever walk in one straight line.

    1. if / else if / else

    An if statement runs a block of code only when a condition is true. The condition goes in (parentheses) and must evaluate to true or false. Add else for a fallback, and chain else if for extra options. The chain is checked top to bottom and the first true branch wins — every branch below it is skipped — so put your most specific conditions first. Read this worked example, run it, then you'll write your own.

    Worked example: if / else if / else

    Read every comment, run it, and check which branch fires.

    Try it Yourself »
    C++
    #include <iostream>
    using namespace std;
    
    int main() {
        int score = 82;
    
        // An if statement runs its block ONLY when the condition is true.
        // The condition lives in (parentheses) and must be true or false.
        if (score >= 50) {
            cout << "You passed!" << endl;   // runs, because 82 >= 50 is true
        }
    
        // if / else — one of the two blocks ALWAYS runs.
        if (score >= 90) {
            cout << "Top of the class." << endl;
        } else {
            cout << "Not quite top, but well d
    ...

    ⚠️ Always use braces {}. Without them, only the single line after the if is conditional — the next line runs every time, which is a classic, silent bug.

    2. The Ternary Operator ?:

    The ternary is a compact if/else that returns a value. The shape is condition ? valueIfTrue : valueIfFalse. Because it produces a value, you can assign it directly (string s = ok ? "yes" : "no";) or drop it inside a bigger expression. Reach for it on short either/or choices; if a branch needs several statements, a normal if/else reads more clearly.

    Worked example: the ternary operator

    See how ?: returns a value you can assign or print.

    Try it Yourself »
    C++
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        // The ternary operator is a one-line if/else that RETURNS a value:
        //     condition ? valueIfTrue : valueIfFalse
        int age = 20;
        string status = (age >= 18) ? "Adult" : "Minor";
        cout << "Status: " << status << endl;   // Status: Adult
    
        // Great for picking the bigger of two numbers without a temp if-block.
        int a = 42, b = 17;
        int largest = (a > b) ? a : b;
        cout << "Largest: " << largest <<
    ...

    Your turn. Fill in the two ___ blanks using the hints in the comments, then run it.

    🎯 Your turn: write two ternaries

    Fill in the ___ blanks, then check your output against the expected lines.

    Try it Yourself »
    C++
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        // 🎯 YOUR TURN — replace each ___ then press "Try it Yourself".
    
        int temperature = 30;
    
        // 1) Use a ternary to set "advice" to "Hot" when temperature >= 25,
        //    otherwise "Mild".
        string advice = ___;   // 👉 (temperature >= 25) ? "Hot" : "Mild"
    
        // 2) Use a ternary to store the absolute value of -8 in "abs".
        int value = -8;
        int abs = ___;         // 👉 (value >= 0) ? value : -value
    
        co
    ...

    3. switch / case / break / default

    When you're comparing one value against many exact options, a switch is cleaner than a long else if chain. It works with int, char and enum (not strings or ranges). Each case ends with break to jump out of the switch; default is the catch-all, like else. If you omit break, execution falls through into the next case — handy when you deliberately stack cases (case 6: case 7: sharing one block), but a bug when you forget it.

    switch (variable) {
        case value1:
            // code for value1
            break;          // stop — without this it falls through
        case value2:
        case value3:        // value2 and value3 share the next block
            // code for value2 OR value3
            break;
        default:            // optional — runs when nothing matched
            // fallback code
    }

    Worked example: switch, break, default & fall-through

    Match days and a grade letter, and see deliberate fall-through.

    Try it Yourself »
    C++
    #include <iostream>
    using namespace std;
    
    int main() {
        // switch compares ONE value against many exact cases.
        // It works with int, char and enum — NOT with strings or ranges.
        int day = 3;
    
        switch (day) {
            case 1:
                cout << "Monday" << endl;
                break;          // break = stop here, jump out of the switch
            case 2:
                cout << "Tuesday" << endl;
                break;
            case 3:
                cout << "Wednesday" << endl;  // matches -> this r
    ...

    Now you try. This vending machine is missing the keyword that stops fall-through and the catch-all label. Fill in the two blanks:

    🎯 Your turn: finish the switch

    Add the missing break and default, then check the output.

    Try it Yourself »
    C++
    #include <iostream>
    using namespace std;
    
    int main() {
        // 🎯 YOUR TURN — a tiny vending machine. Fill in the blanks.
        int choice = 2;   // 1 = Water, 2 = Cola, anything else = unknown
    
        switch (choice) {
            case 1:
                cout << "Dispensing Water" << endl;
                ___          // 👉 add the keyword that stops fall-through here
            case 2:
                cout << "Dispensing Cola" << endl;
                break;
            ___:             // 👉 the catch-all label for unmatched
    ...

    4. Nesting, Logic & if-with-Initializer

    Real decisions often depend on several things at once. Combine conditions with the logical operators: && (AND — both must be true), || (OR — either is enough), and ! (NOT — flips true and false). You can also nest an if inside another to make a second decision only when the first passed. Finally, C++17's if-with-initializer lets you declare and test a variable together — if (int x = f(); x > 0) — keeping x scoped to just that if/else.

    Worked example: &&, ||, nesting & if (init; condition)

    Combine conditions, nest a decision, and scope a variable to one test.

    Try it Yourself »
    C++
    #include <iostream>
    #include <string>
    using namespace std;
    
    // Returns how many items are left in stock for an order id.
    int stockFor(int id) {
        return (id == 7) ? 3 : 0;   // only product 7 is in stock (3 left)
    }
    
    int main() {
        int age = 22;
        bool hasTicket = true;
        bool isVip = false;
    
        // Logical operators combine conditions:
        //   &&  AND  -> true only if BOTH sides are true
        //   ||  OR   -> true if EITHER side is true
        //   !   NOT  -> flips true <-> false
        cout 
    ...

    Common Errors (and the fix)

    • Missing break (accidental fall-through): if a case has no break, its code and the next case's both run. Add break; to every case unless you mean to fall through.
    • = instead of ==: if (x = 5) assigns 5 to x and is always true. Use == to compare; writing if (5 == x) turns the typo into a compile error.
    • No default case: if no case matches and there's no default, the switch silently does nothing. Add a default: to catch unexpected values.
    • Dangling else: an else binds to the nearest unmatched if, not the one you indented it under. Use braces {} on every nested if so the else pairs with the right one.
    • "error: 'x' was not declared in this scope": a variable from an if-with-initializer or a case block only lives inside that block. Declare it outside if you need it afterwards.

    Pro Tips

    • 💡 Handle edge cases first: deal with the unusual inputs early with simple ifs, then write the normal path without deep nesting.
    • 💡 Use switch for menus: it's ideal for processing numbered choices (1, 2, 3…) in a console app.
    • 💡 Flatten deep nesting: 4+ levels of indentation is a smell — pull the inner logic into a small function.
    • 💡 Scope tightly: prefer if (auto v = lookup(); v) so short-lived variables can't leak into the rest of your function.

    📋 Quick Reference

    ConceptSyntax
    Ifif (cond) { ... }
    If / elseif (cond) { ... } else { ... }
    Else if chainif (...) {} else if (...) {} else {}
    Ternaryresult = cond ? a : b;
    Switchswitch (x) { case 1: ...; break; default: ...; }
    Logical AND / OR / NOTa && b | a || b | !a
    If with initializer (C++17)if (int x = f(); x > 0) { ... }

    Frequently Asked Questions

    Q: When should I use a switch instead of an if/else chain?

    Use switch when you are comparing ONE variable against many exact, constant values (like menu numbers or a char grade). It is cleaner and shows your intent. Use if/else when you need ranges (score >= 80), combined conditions with && or ||, or anything other than an int, char or enum.

    Q: What is fall-through in a switch?

    If a case has no break, execution continues into the next case. Usually that is a bug — you forget the break and two messages print. But it is also a deliberate trick: stacking case 6: case 7: with one block lets several values share the same code.

    Q: Why does if (x = 5) always run?

    A single = is assignment, not comparison. if (x = 5) stores 5 in x and then tests that value, and any non-zero number counts as true in C++, so the branch always runs. Use == to compare. Putting the constant first — if (5 == x) — makes a typo a compile error.

    Q: Is the ternary operator just a shortcut for if/else?

    Almost. The key difference is that the ternary RETURNS a value, so you can assign it: string s = ok ? "yes" : "no";. A plain if/else does not return anything. Keep the ternary for short either/or choices; if a branch needs several statements, a normal if/else reads better.

    Q: What is an if-with-initializer and why use it?

    Since C++17 you can write if (int x = f(); x > 0) — declare x and test it in one line. The variable only exists inside the if/else, so it cannot leak into the rest of your function. It keeps short-lived variables tightly scoped and your code tidier.

    Mini-Challenge: Ticket Price Calculator

    No blanks this time — just a brief and a blank canvas (with an outline to keep you on track). Build it, run it, and check your output against the example in the comments. This combines an if/else if chain with a ternary, exactly like real code.

    🎯 Mini-Challenge: build a ticket price calculator

    Write the if/else chain and the ternary yourself.

    Try it Yourself »
    C++
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        // 🎯 MINI-CHALLENGE: Ticket price calculator
        // 1. Make an int "age" and a bool "isStudent".
        // 2. Decide the price with if / else if / else:
        //       under 5            -> 0   (free)
        //       65 and over        -> 8   (senior)
        //       isStudent is true  -> 10  (student)
        //       everyone else      -> 15  (standard)
        // 3. Print:  "Price: $X"
        // 4. BONUS: use a ternary to print "Child" w
    ...

    🎉 Lesson Complete

    • if / else if / else run the first branch whose condition is true
    • ✅ The ternary cond ? a : b returns a value you can assign or print
    • switch matches exact int/char/enum values; break stops fall-through; default is the catch-all
    • ✅ Combine conditions with &&, || and !, and nest ifs for layered decisions
    • if (init; condition) (C++17) scopes a variable to just that test
    • Next lesson: Loops — repeat code efficiently with for, while and do-while

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service

    Install LearnCodingFast

    Learn faster with the app on your home screen.