Switch Statement in C

The switch statement in the C programming language allows you to transfer control to one or more statements by choosing among different alternatives depending on the value assumed by the control expression.

A switch statement is more convenient than an if statement when the number of cases to manage is large, making it cumbersome to use many concatenated if statements.

In C, however, the switch statement has limitations since it can only be used with control expressions that produce integer values.

In this lesson, we will examine in detail how to use these statements to control the flow of our programs.

Key Takeaways
  • The switch statements in C are conditional statements that allow jumping to a statement chosen from multiple alternatives based on the value of the control expression;
  • The control expression must evaluate to an integer;
  • The different cases must be specified using case clauses;
  • Each group of instructions for a case should end with a break statement;
  • If break is omitted, the next case is executed;
  • The default case is specified using the default clause.

switch Statements

In programming, it is often necessary to compare an expression with a series of values to determine which one it matches. In the lesson on if statements, we saw that it is possible to use concatenated if statements for this purpose.

For example, suppose we have an integer variable that contains a value associated with a day of the week. This variable can take on a value from 1 (Monday) to 7 (Sunday). We want to print the corresponding day name or print Invalid day if the value is not between 1 and 7.

Using if statements, we can write the following code:

if (day_of_the_week == 1)
    printf("Monday");
else if (day_of_the_week == 2)
    printf("Tuesday");
else if (day_of_the_week == 3)
    printf("Wednesday");
else if (day_of_the_week == 4)
    printf("Thursday");
else if (day_of_the_week == 5)
    printf("Friday");
else if (day_of_the_week == 6)
    printf("Saturday");
else if (day_of_the_week == 7)
    printf("Sunday");
else
    printf("Invalid day");

However, C provides a more convenient statement for such cases: the switch statement.

Using it, we can rewrite the code above as follows:

switch (day_of_the_week) {
    case 1:     printf("Monday");
                break;
    case 2:     printf("Tuesday");
                break;
    case 3:     printf("Wednesday");
                break;
    case 4:     printf("Thursday");
                break;
    case 5:     printf("Friday");
                break;
    case 6:     printf("Saturday");
                break;
    case 7:     printf("Sunday");
                break;
    default:    printf("Invalid day!");
                break;
}

When the switch statement is executed, the value of the variable day_of_the_week is compared to the values from 1 to 7.

If, for example, the value is 3, the statement printf("Wednesday") is executed, printing Wednesday, followed by the break statement which transfers execution to the statement after the switch.

If the value of day_of_the_week does not match any listed value, the default case is executed, printing Invalid day.

The advantage of using a switch statement is that it is much more readable than a series of concatenated if statements. Additionally, in many cases, the code generated by the compiler for switch statements is more efficient than that generated for equivalent if statements.

The most common form of a switch statement is:

switch ( integer_control_expression ) {
    case constant_expression_1:     statements;
                                    break;

    case constant_expression_2:     statements;
                                    break;
    /* .... */
    default:                        statements;
                                    break;
}

Since a switch statement is quite complex, let’s break down its components:

  • Integer control expression. The switch keyword must be immediately followed by a control expression in parentheses. This expression must be of an integer type, or at least convertible to an integer. For example, expressions using integers are supported, and char values are converted to integers. Floating point numbers or strings are not supported.

  • Case labels. Each case begins with a label of the form:

    case constant_expression:
    

    The expression constant_expression must be a constant integer expression. Variables or function calls are not allowed.

    For example, 6 is allowed, and so are expressions like 2 * 4 or 20 - 2, as they are constant expressions. Expressions like x * 2 or y - 4 are not allowed, since they contain variables.

  • Statements. Each case label can be followed by any number of statements, without the need for curly braces. Typically, the last instruction in each group is a break.

Definition

switch Statement

A switch statement is a conditional statement that executes different instructions depending on the value of an integer control expression.

The general syntax of a switch statement is:

switch ( integer_control_expression ) {
    case constant_expression_1:     statements;
                                    break;

    case constant_expression_2:     statements;
                                    break;
    /* .... */
    default:                        statements;
                                    break;
}
  • The expression integer_control_expression must yield an integer value;
  • The various constant_expression must also be integer values;
  • The default label is executed when the control expression doesn't match any listed case;
  • Each group of instructions for a case should end with a break.

switch Statement Caveats

When using the switch statement in C programs, care must be taken.

Note

Cases cannot be duplicated.

Cases within a switch statement cannot be duplicated. You cannot write code like this:

/* Invalid code */
switch (expression) {
    case 1:     statement_1;
                break;
    case 1:     statement_2; /* Duplicate case */
                break;
    default:    default_statement;
                break;
}
Hint

The order of cases doesn't matter.

The order in which cases appear in the switch statement is completely irrelevant. There is no need to follow any order because the compiler will always select the case corresponding to the value of the control expression.

Hint

The default case doesn't have to be last.

As a consequence of the above, the default case doesn't have to appear last. You can, in fact, write code like this:

switch (expression) {
    default:    default_statement;
                break;
    case 1:     statement_1;
                break;
    /* ... */
}
Hint

The default case is optional.

The default case in a switch statement is optional. If omitted, and the value of the control expression does not match any case, control simply passes to the statement after the switch.

For example:

switch (x) {
    case 1:     statement_1;
                break;
    case 2:     statement_2;
                break;
}

next_statement;

If variable x is not equal to 1 or 2, control simply proceeds to next_statement.

Multiple Cases

In general, the following rule applies to switch statements:

Note

The case keyword can only be followed by one constant expression.

You cannot associate multiple constant expressions to a single case. For example, the following code is not valid:

switch(x) {
    /* INVALID CODE! */
    case 1, 2, 3:   statement;
                    break;
    /* ... */
}

Also, unlike other programming languages, you cannot specify a range for a case in a switch statement.

The above limitation, however, can be circumvented to some extent. By omitting the break statement, multiple cases can lead to the same block of instructions.

For example, revisiting the earlier example of the days of the week, suppose we want to print whether a day is a weekday or a weekend.

Naively, we might write:

switch (day_of_the_week) {
    case 1:     printf("Weekday");
                break;
    case 2:     printf("Weekday");
                break;
    case 3:     printf("Weekday");
                break;
    case 4:     printf("Weekday");
                break;
    case 5:     printf("Weekday");
                break;
    case 6:     printf("Weekend");
                break;
    case 7:     printf("Weekend");
                break;
    default:    printf("Invalid day!");
                break;
}

However, since cases 1 through 5 and 6–7 yield the same result, we can rewrite the code more succinctly by omitting the break statements in the intermediate cases:

switch (day_of_the_week) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:     printf("Weekday");
                break;
    case 6:
    case 7:     printf("Weekend");
                break;
    default:    printf("Invalid day!");
                break;
}

Therefore:

Definition

Multiple Cases in a switch Statement

To manage multiple cases in a switch statement in C, simply precede the group of shared instructions with the various case labels, omitting the break until after the final instruction.

The general form of multiple cases is:

switch (control_expression) {
    /* ... */

    case case_1:
    case case_2:
    /* ... */
    case case_n:    statement_1;
                    statement_2;
                    /* ... */
                    statement_n;
                    break;

    /* ... */
}

The break Statement

At this point, having examined the switch statement and how it works in detail, it's necessary to take a moment to focus on the break statement and fully understand what it actually does.

As we’ve seen above, the purpose of the break statement is to exit the switch statement and continue execution with the instruction that follows it.

In reality, the switch statement is nothing more than a computed jump, and therefore the break instruction is necessary. When the control expression is evaluated, program execution jumps to the corresponding case label. A case label is essentially a placeholder that marks a position inside the switch block. Once the last statement in the case is executed, the control continues with the next case’s statements, and the subsequent label is simply ignored. If we don't use a break statement, execution will fall through to the following case.

To clarify this, let’s return to the weekday example:

#include <stdio.h>

int main() {
    int day_of_the_week = 1;

    switch (day_of_the_week) {
        case 1:     printf("Monday\n");
                    break;
        case 2:     printf("Tuesday\n");
                    break;
        case 3:     printf("Wednesday\n");
                    break;
        case 4:     printf("Thursday\n");
                    break;
        case 5:     printf("Friday\n");
                    break;
        case 6:     printf("Saturday\n");
                    break;
        case 7:     printf("Sunday\n");
                    break;
        default:    printf("Invalid day!\n");
                    break;
    }

    return 0;
}

If we compile and run this program, the output we get is correct:

Monday

Now, let’s remove all the break statements like so:

#include <stdio.h>

int main() {
    int day_of_the_week = 1;

    switch (day_of_the_week) {
        case 1:     printf("Monday\n");
        case 2:     printf("Tuesday\n");
        case 3:     printf("Wednesday\n");
        case 4:     printf("Thursday\n");
        case 5:     printf("Friday\n");
        case 6:     printf("Saturday\n");
        case 7:     printf("Sunday\n");
        default:    printf("Invalid day!\n");
    }

    return 0;
}

If we compile and run the above program, we get the following output:

Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Invalid day!

This happens because the switch statement checks the value of the variable day_of_the_week and, finding that it is 1, jumps to the line corresponding to case 1. At this point, the program prints the string "Monday\n" via printf. Since there's no break, the program continues to execute the next case instructions, printing all subsequent strings one after the other.

Note

Forgetting break at the end of each case is a common mistake.

One of the most common programming errors in C is forgetting to add the break statement at the end of each case. Even though, as we saw in multiple-case examples, omitting it can be intentional, in general it leads to bugs.

To avoid such mistakes, it is good practice to always add a break to each case. In fact, it’s recommended to include a break even after the default case—even though it’s not strictly necessary:

switch (control_expression) {
    case case_1:    statement;
                    break;
    case case_2:    statement;
                    break;
    /* ... */
    default:        statement;
                    /* Not strictly required */
                    /* But good practice */
                    break;
}

If omitting break is intentional, you can leave a comment to clarify:

switch (control_expression) {
    case case_1:    /* Multiple case */
    case case_2:    statement;
                    break;
    /* ... */
    default:        statement;
                    break;
}

Summary

In this lesson, we studied the second conditional statement provided by the C language: the switch statement. Compared to the if statement, the switch allows you to define different actions for multiple specific values—not just true or false conditions.

The main limitation of this statement, however, is that the control expression must be of an integer type, and the case labels must be constant integer values.