Switch conditional statement

4 minutes read

You already know how to shape a program's flow using if-else statements. However, in some cases, you will be working with a limited set of discrete options. For example, when you have 5-10 options to choose from, you would need to write complex if/else chains for each case. Fortunately, you can avoid this approach and make your code both readable and maintainable. Let's explore an alternative way to handle multiple choices.

Background

Let's explore a common scenario: a game menu. Imagine you want to present players with several options that they can select from:

#include <iostream>

int main() {
    int choice;

    std::cout << "Game Menu\n";
    std::cout << "1. New Game\n";
    std::cout << "2. Continue Game\n";
    std::cout << "3. Settings\n";
    std::cout << "4. Quit\n";
    std::cout << "Choose an option: ";
    std::cin >> choice;

    if (choice == 1) {
        std::cout << "Starting a new game...\n";
    } else if (choice == 2) {
        std::cout << "Continuing the game...\n";
    } else if (choice == 3) {
        std::cout << "Opening settings...\n";
    } else if (choice == 4) {
        std::cout << "Exiting the game...\n";
    } else {
        std::cout << "Invalid choice. Please try again.\n";
    }

    return 0;
}

While this code works, it can become difficult to understand when dealing with many conditional branches, especially for other developers (or yourself when reviewing the code later). This is where the switch statement becomes particularly useful.

Introducing the switch statement

The switch statement provides a clear way to choose between multiple cases based on a single variable's value. Let's look at the same game menu example using the switch statement:

#include <iostream>

int main() {
    int choice;

    std::cout << "Game Menu\n";
    std::cout << "1. New Game\n";
    std::cout << "2. Continue Game\n";
    std::cout << "3. Settings\n";
    std::cout << "4. Quit\n";
    std::cout << "Choose an option: ";
    std::cin >> choice;

    switch (choice) {
        case 1:
            std::cout << "Starting a new game..." << std::endl;
            break;
        case 2:
            std::cout << "Continuing the game..." << std::endl;
            break;
        case 3:
            std::cout << "Opening settings..." << std::endl;
            break;
        case 4:
            std::cout << "Exiting the game..." << std::endl;
            break;
        default:
            std::cout << "Invalid choice. Please try again.\n";
            break;
    }

    return 0;
}

Notice how this code is cleaner and more structured than a long if/else if chain. Each option is clear. Even if you're new to switch, case, and break, you can probably already understand what they do.

Dissecting the switch statement

Now, let's take a closer look at the switch statement and its components:

switch (choice) { // The 'switch' keyword initiates the statement
    case 1: // 'case' labels define specific values
        std::cout << "Starting a new game..." << std::endl;
        break; // 'break' exits the switch statement 
    case 2:
        std::cout << "Continuing the game..." << std::endl;
        break;
    case 3:
        std::cout << "Opening settings..." << std::endl;
        break;
    case 4:
        std::cout << "Exiting the game..." << std::endl;
        break;
    default: // 'default' handles unmatched values
        std::cout << "Invalid choice. Please try again.\n";
        break;
}
  • switch (expression): The switch keyword introduces the statement, followed by an expression in parentheses that will be evaluated. This expression is typically an integral type (like int, bool, char), and can include others like enum and certain class types (those that can be implicitly converted to integral or enum types).

  • case value:: The case keyword defines a specific value to match against the switch expression. When the expression's value equals value, the code block for that case will run.

  • break;: This statement is optional, but essential within switch. When the program reaches break, it immediately exits the entire switch statement, preventing the execution of other case labels.

  • default:: The default keyword is optional. When included, its code block runs if no case values match the switch expression. It serves as a catch-all for unexpected values.

Why break is your friend

You may have noticed that the break statement is optional. This is where switch statements can become tricky if you're not careful. When you omit break after a case, the execution will "fall through" to the next case label, executing its code. This continues until one of the following termination conditions occurs:

  • The end of the switch block is reached.

  • A return statement is encountered

  • A break statement is executed.

If none of these termination conditions are met, the program will execute all the cases following the matched case. Here's an example:

#include <iostream>

int main() {
    int option = 2;

    switch (option) {
        case 1:
            std::cout << "This option is not suitable, we will not print.\n";
        case 2:
            std::cout << "Oh we'll print it.\n";
        case 3:
            std::cout << "And we'll print it too...\n";
        case 4:
            std::cout << "And this too??? YEP!\n";
        case 5:
            std::cout << "And this 8)\n";
        default:
            std::cout << "And this\n";
    }

    return 0;
}

As a result of executing the code, you get the following:

Oh we'll print it.
And we'll print it too...
And this too??? YEP!
And this 8)
And this

This behavior is likely not what you intended! Without break statements, the program executes code for case 3, case 4, case 5, and default, even though option matches only case 2. Remember to include break statements at the end of each case block unless you specifically want fall-through behavior (which is rare and should be clearly documented).

Conclusion

When you have a limited number of cases to choose from, switch statements can help you avoid long if-else ladders and provide better readability and maintainability in certain situations.

Just remember the key components: the switch keyword to evaluate an expression, case labels for specific values, and most importantly, the break statement to prevent unwanted "fall-through" behavior. Mastering switch will add a valuable tool to your C++ programming toolkit!

10 learners liked this piece of theory. 2 didn't like it. What about you?
Report a typo