C++ switch...case statement


Introduction

The switch...case statement in C++ provides a simpler and more readable way to handle multiple conditions compared to a series of if...else statements. It allows you to test a variable or expression against multiple possible values and execute different blocks of code based on the value.

In this blog post, we’ll cover:

  • The purpose and syntax of the switch...case statement.
  • How to use switch with different types of values (integer, char).
  • Practical examples demonstrating how to implement switch...case in C++.
  • Key differences between switch...case and if...else.

1. Syntax of the switch...case Statement

The general syntax of the switch statement is as follows:

switch (expression) {
    case constant1:
        // Code to execute if expression == constant1
        break;
    case constant2:
        // Code to execute if expression == constant2
        break;
    case constant3:
        // Code to execute if expression == constant3
        break;
    default:
        // Code to execute if none of the above cases match
}

Key Components:

  • switch expression: The value or variable that is tested.
  • case labels: Each case compares the value of the switch expression to a constant. If a match is found, the corresponding code block is executed.
  • break statement: Prevents "fall-through" behavior and exits the switch statement once a case is matched.
  • default case: The optional default case is executed if no case matches the expression. It's similar to the else in an if...else statement.

2. Using the switch...case Statement

Let’s look at a basic example of using switch...case in C++.

Example 1: Basic switch...case Usage

#include <iostream>
using namespace std;

int main() {
    int number;
    cout << "Enter a number between 1 and 5: ";
    cin >> number;
    
    switch (number) {
        case 1:
            cout << "You entered one." << endl;
            break;
        case 2:
            cout << "You entered two." << endl;
            break;
        case 3:
            cout << "You entered three." << endl;
            break;
        case 4:
            cout << "You entered four." << endl;
            break;
        case 5:
            cout << "You entered five." << endl;
            break;
        default:
            cout << "Invalid number!" << endl;
            break;
    }

    return 0;
}

Output:

Enter a number between 1 and 5: 3
You entered three.

Explanation:

  • The program checks the value of number against the values in each case (1, 2, 3, 4, 5).
  • When number is 3, it matches the case 3, and the corresponding block of code is executed.
  • The break statement ensures that the program exits the switch block after executing the code for the matched case.
  • If the value doesn't match any of the case labels, the default case is executed.

3. Using switch with char Data Type

The switch...case statement in C++ can also be used with char values. The character is internally treated as its ASCII value.

Example 2: Using switch with char

#include <iostream>
using namespace std;

int main() {
    char grade;
    cout << "Enter your grade (A, B, C, D, F): ";
    cin >> grade;
    
    switch (grade) {
        case 'A':
            cout << "Excellent!" << endl;
            break;
        case 'B':
            cout << "Good!" << endl;
            break;
        case 'C':
            cout << "Average!" << endl;
            break;
        case 'D':
            cout << "Below average!" << endl;
            break;
        case 'F':
            cout << "Fail!" << endl;
            break;
        default:
            cout << "Invalid grade!" << endl;
            break;
    }

    return 0;
}

Output:

Enter your grade (A, B, C, D, F): B
Good!

Explanation:

  • The program checks the value of grade (a char) against each case label.
  • If the user enters B, the corresponding block prints "Good!".
  • The default case handles invalid inputs that aren't A, B, C, D, or F.

4. Fall-through Behavior in switch

In C++, if you omit the break statement in a case, control "falls through" to the next case, even if that case doesn't match the expression. This behavior can sometimes be useful, but it is generally discouraged because it can lead to logical errors.

Example 3: Fall-through in switch

#include <iostream>
using namespace std;

int main() {
    int number = 2;
    
    switch (number) {
        case 1:
            cout << "One" << endl;
        case 2:
            cout << "Two" << endl;
        case 3:
            cout << "Three" << endl;
        default:
            cout << "Invalid" << endl;
    }

    return 0;
}

Output:

Two
Three
Invalid

Explanation:

  • The switch starts by checking number == 2, and since there’s no break after case 1, control falls through to case 2, then case 3, and finally the default case.
  • This is fall-through, which is often not intended.
  • To avoid this, always include a break after each case unless fall-through is deliberately required.

5. Multiple case Labels for the Same Code

You can group multiple case labels together to execute the same block of code for different values.

Example 4: Grouping case Labels

#include <iostream>
using namespace std;

int main() {
    int number;
    cout << "Enter a number between 1 and 3: ";
    cin >> number;
    
    switch (number) {
        case 1:
        case 2:
            cout << "You entered one or two." << endl;
            break;
        case 3:
            cout << "You entered three." << endl;
            break;
        default:
            cout << "Invalid number!" << endl;
            break;
    }

    return 0;
}

Output:

Enter a number between 1 and 3: 2
You entered one or two.

Explanation:

  • Both case 1 and case 2 will execute the same block of code, printing "You entered one or two.".
  • The break ensures that the control exits the switch statement after that.

6. Key Differences Between switch...case and if...else

Feature switch...case if...else
Expression type Works with constants (integers, characters, etc.). Works with expressions of any type (boolean, integer, etc.).
Use cases Best for comparing a variable against multiple values of the same type. Suitable for more complex conditions or when working with ranges.
Performance Generally faster when dealing with many conditions. More flexible but can be less efficient with many conditions.