Skip to main content

📝 Lesson 4: Control Structures

Teaching your program to make decisions based on changing conditions.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Use IF, IF-ELSE, and IF-ELSE-IF statements to implement decision logic.
  • Understand when to use SWITCH statements for better readability with multiple cases.
  • Implement nested IF statements to handle complex conditional scenarios.
  • Use the ternary operator for concise conditional assignments.

Estimated Time: 60–90 minutes

Project: Build a text-based adventure game where user choices determine the outcome, or an ATM machine simulation.

In This Lesson

What Are Control Structures?

Imagine you're giving directions to a friend. You don't just say "go straight forever" - you say things like "IF you see the red building, TURN LEFT" or "KEEP GOING UNTIL you reach the park." Control structures let your program make similar decisions!

The IF Statement: Your Program's First Decision

The IF statement is like a bouncer at a club - it checks if a condition is true before letting code execute.

graph TD A[Check Condition] --> B{Is it true?} B -->|Yes| C[Execute Code Block] B -->|No| D[Skip Code Block] C --> E[Continue Program] D --> E

Basic IF Statement Syntax

if (condition) {
    // Code runs ONLY if condition is true
    cout << "Condition was true!" << '\n';
}

Real-World Example: Temperature Checker

int temperature = 75;

if (temperature > 70) {
    cout << "It's a warm day!" << '\n';
    cout << "Perfect for outdoor activities." << '\n';
}

if (temperature > 90) {
    cout << "It's very hot! Stay hydrated!" << '\n';
}

🆕 Modern C++ (C++17): if with an initializer

Since C++17 you can declare a variable right inside the if. It stays scoped to the if-else, so temporary helpers don't leak into the surrounding code:

if (int statusCode = getStatusCode(); statusCode == 200) {
    cout << "Success!" << '\n';
} else {
    cout << "Failed with code " << statusCode << '\n';  // still visible in else
}
// statusCode is NOT visible out here

The same form works for switch (int c = getChoice(); c) { ... }. You'll see this pattern often in Unreal Engine code.

The IF-ELSE Statement: Either This OR That

IF-ELSE is like a fork in the road - you MUST go one way or the other, never both!

IF-ELSE Decision Tree Age >= 18? Can Vote! Register today Too Young Wait a bit TRUE FALSE

IF-ELSE Example: Pass/Fail Grade

int score = 75;

if (score >= 60) {
    cout << "Congratulations! You passed!" << '\n';
    cout << "Your score: " << score << '\n';
} else {
    cout << "Sorry, you didn't pass." << '\n';
    cout << "You need at least 60 to pass." << '\n';
}

The IF-ELSE-IF Ladder: Multiple Choices

Sometimes life isn't just yes or no - it's multiple choice! The IF-ELSE-IF ladder handles multiple conditions.

Complete Grade Calculator Example

int score = 85;
char grade;

if (score >= 90) {
    grade = 'A';
    cout << "Excellent work!" << '\n';
} else if (score >= 80) {
    grade = 'B';
    cout << "Good job!" << '\n';
} else if (score >= 70) {
    grade = 'C';
    cout << "Satisfactory." << '\n';
} else if (score >= 60) {
    grade = 'D';
    cout << "Needs improvement." << '\n';
} else {
    grade = 'F';
    cout << "Please see your instructor." << '\n';
}

cout << "Your grade is: " << grade << '\n';

Nested IF Statements: Decisions Within Decisions

Like Russian nesting dolls, you can put IF statements inside other IF statements!

graph TD A[Is it weekend?] --> B{Yes} A --> C{No} B --> D[Is it raining?] D --> E{Yes} D --> F{No} E --> G["Stay home & read"] F --> H[Go to the park] C --> I[Go to work/school]

Nested IF Example: Event Planning

bool isWeekend = true;
bool isRaining = false;
int temperature = 75;

if (isWeekend) {
    cout << "It's the weekend!" << '\n';

    if (isRaining) {
        cout << "Stay inside and watch movies." << '\n';
    } else {
        if (temperature > 70) {
            cout << "Perfect day for a picnic!" << '\n';
        } else {
            cout << "Maybe visit a museum." << '\n';
        }
    }
} else {
    cout << "It's a weekday - time for work/school!" << '\n';
}

The Switch Statement: Multiple Choice Made Easy

When you have many specific values to check, SWITCH is like a more elegant multiple-choice answer sheet.

Switch Statement Syntax

int choice = 2;

switch (choice) {
    case 1:
        cout << "You ordered a hamburger!" << '\n';
        break;
    case 2:
        cout << "You ordered pizza!" << '\n';
        break;
    case 3:
        cout << "You ordered a salad!" << '\n';
        break;
    case 4:
        cout << "You ordered pasta!" << '\n';
        break;
    default:
        cout << "Invalid choice!" << '\n';
        break;
}

Important: The Break Statement

Without 'break', switch cases "fall through" like dominoes!

Switch Fall-through Example With break: Case 1 Case 2 Case 3 Only Case 1 executes Without break: Case 1 Case 2 Case 3 All cases execute!

🆕 Modern C++ (C++17): marking intentional fall-through

Sometimes you want a case to fall through on purpose. Since C++17 you can say so explicitly with the [[fallthrough]] attribute, which documents your intent and silences compiler warnings:

switch (choice) {
    case 1:
    case 2:  // cases 1 and 2 stacked with no code between — a safe, common fall-through
        cout << "Low option" << '\n';
        break;
    case 3:
        cout << "Handling 3..." << '\n';
        [[fallthrough]];  // intentional: also run case 4's code
    case 4:
        cout << "Handling 4" << '\n';
        break;
}

Ternary Operator: The Compact IF-ELSE

The ternary operator is like IF-ELSE compressed into one line - perfect for simple decisions!

Ternary Operator Examples

// Example 1: Simple assignment
int age = 20;
string status = (age >= 18) ? "Adult" : "Minor";

// Example 2: In output
int score = 85;
cout << "You " << (score >= 60 ? "passed" : "failed") << " the test!" << '\n';

// Example 3: Calculating values
int items = 5;
double price = (items > 3) ? 9.99 : 12.99;

Practice Exercise: Adventure Game

🏋️ Create Your Own Adventure!

Build a simple text adventure game where the player makes choices:

#include <iostream>
using namespace std;

int main() {
    int choice;

    cout << "=== The Mysterious Cave ===" << '\n';
    cout << "You stand at the entrance of a dark cave." << '\n';
    cout << "What do you do?" << '\n';
    cout << "1. Enter the cave" << '\n';
    cout << "2. Walk away" << '\n';
    cout << "3. Call for help" << '\n';
    cout << "Enter your choice (1-3): ";
    cin >> choice;

    // TODO: Use switch or if-else to handle choices
    // Each choice should lead to different outcomes

    return 0;
}
✅ Solution
switch (choice) {
    case 1:
        cout << "\nYou bravely enter the cave..." << '\n';
        cout << "You find a treasure chest!" << '\n';
        break;
    case 2:
        cout << "\nYou decide to play it safe." << '\n';
        cout << "Maybe another day..." << '\n';
        break;
    case 3:
        cout << "\nYou call out loudly." << '\n';
        cout << "A friendly explorer appears to help!" << '\n';
        break;
    default:
        cout << "\nThat's not a valid choice!" << '\n';
}

Common Patterns and Best Practices

graph TD A[Control Structure Best Practices] --> B[Use braces even for single lines] A --> C[Keep conditions simple] A --> D[Avoid deep nesting] A --> E[Always include default in switch] B --> F["if (x > 0) {<br/> count++;<br/>}"] C --> G["Break complex conditions<br/>into variables"] D --> H["Consider using functions<br/>for complex logic"] E --> I[Handles unexpected values]

Debugging Tips: Common Control Structure Mistakes

Common Mistakes to Avoid Missing Braces if (x > 0) cout << "Positive"; x++; // Always runs! Assignment vs Comparison if (x = 5) // Wrong! if (x == 5) // Correct! Forgetting Break case 1: cout << "One"; // Missing break!

Challenge Exercise: Grade Report System

🏋️ Advanced Challenge

Create a comprehensive grade reporting system that:

  1. Accepts a numeric grade (0-100)
  2. Validates the input (must be 0-100)
  3. Assigns a letter grade
  4. Determines if the student is on the honor roll (90+)
  5. Provides appropriate feedback
  6. Asks if they want to check another grade
💡 Hint
  • Use input validation with if statements
  • Use if-else-if for grade assignment
  • Use nested if for honor roll check
  • Use a ternary operator somewhere
  • Handle invalid inputs gracefully

Real-World Application: ATM Machine

// Simplified ATM System
double balance = 1000.00;
int choice;
double amount;

cout << "=== Welcome to SimpleBank ATM ===" << '\n';
cout << "1. Check Balance" << '\n';
cout << "2. Withdraw" << '\n';
cout << "3. Deposit" << '\n';
cout << "4. Exit" << '\n';
cout << "Enter choice: ";
cin >> choice;

switch (choice) {
    case 1:
        cout << "Your balance is: $" << balance << '\n';
        break;

    case 2:
        cout << "Enter withdrawal amount: $";
        cin >> amount;
        if (amount > balance) {
            cout << "Insufficient funds!" << '\n';
        } else if (amount <= 0) {
            cout << "Invalid amount!" << '\n';
        } else {
            balance -= amount;
            cout << "Dispensing $" << amount << '\n';
            cout << "New balance: $" << balance << '\n';
        }
        break;

    case 3:
        cout << "Enter deposit amount: $";
        cin >> amount;
        if (amount > 0) {
            balance += amount;
            cout << "Deposit successful!" << '\n';
            cout << "New balance: $" << balance << '\n';
        } else {
            cout << "Invalid amount!" << '\n';
        }
        break;

    case 4:
        cout << "Thank you for using SimpleBank!" << '\n';
        break;

    default:
        cout << "Invalid choice!" << '\n';
}

🎯 Quick Quiz

Question 1: In a C++ switch statement, what happens if you omit the break at the end of a matching case?

Question 2: What does string status = (age >= 18) ? "Adult" : "Minor"; do?

Question 3: In an if-else-if ladder that assigns letter grades, why must you check score >= 90 before score >= 80, rather than the other way around?

Summary

🎉 Key Takeaways

  • IF statements let your program make decisions based on conditions
  • IF-ELSE provides two paths: one for true, one for false
  • IF-ELSE-IF handles multiple conditions in sequence
  • SWITCH is perfect for checking one variable against many specific values
  • Always use break in switch statements unless you want fall-through
  • Ternary operator is great for simple conditional assignments
  • Nest carefully - too much nesting makes code hard to read
graph LR A[Master Control Structures] --> B[Write Dynamic Programs] B --> C[Handle User Input] C --> D[Create Interactive Apps] D --> E[Build Amazing Software!]

📚 Additional Resources

🚀 What's Next?

You can now make your programs decide between paths - but so far each decision has run once. Next, in Lesson 5: Loops, you'll learn how to repeat those decisions and actions automatically with for, while, and do-while loops, so your programs can process many values without you writing the same code over and over.

🎉 You can now make decisions in code!

If, else, switch, and the ternary operator are the backbone of every interesting program you'll ever write - nice work getting comfortable with all four.