Switch Statements

What is a switch statement?

A switch statement is just a more convenient form for particular if-else statements, namely when you're checking a single value against many possibilities. This works especially well for

How to use a switch statement

There's a few different components to the switch statement, so we'll start with a basic one and build up from there:

switch, case, break

These are the basic components you'll see in practically all switch statements you'll come across. switch is accompanied by brackets that enclose the value that we will define cases for. Each case defines a value that we want to check against, with a colon and following by the action to perform. break Is used to signal the end of a case's execution, you might like to think of this as the closing bracket of conditional statements you've seen before.

Let's use these to build a simple test to check if a number is even or not:

#include <stdio.h>

int main(){
    int number;
    scanf("%d", &number);
    
    switch (number % 2){
        case 0:
            printf ("%d is even\n", number);
            break;
        case 1:
            printf ("%d is odd\n", number);
            break;
    }
    
    return 0;
}

Here we can see that the value we're using in our switch statement is the result of number % 2. We then define two cases, 0 and 1. If the result is 0, we execute case 0, if the result is 1 we execute case 1. At the end of each of these cases, we break (marking the end of that case's execution).

Now, you might be looking at this and thinking, "But I can do this with already with an if-else statement, and it looks much nicer!", and you're right. I wouldn't use a switch statement for such a simple comparison. Switch statements shine when you're comparing a single value against many different possiblities, but I don't want to show off something long as a first example; we'll look at one later!

Fallthrough

Sometimes you might see cases that don't have a break statement at the end. If it's not an unintentional bug, this called a fallthrough case. It allows you to execute case and continue downwards until a break is found or the switch statement is terminated by a closing curly brace. There's also a special cased identified by the keyword default which is executed if an appropriate case is not found. You can think of this as an else statement if you like.

Here's an example where we can count down to 1 from a number up to 3:

#include <stdio.h>

int main(){
    int number;
    
    printf("Enter 1, 2, or 3 to count down from: ");
    scanf("%d", &number);
    
    switch (number){
        case 3:
            printf("3...\n");
        case 2:
            printf("2...\n");
        case 1:
            printf("1...\nGO!!!\n");
            break;
        default:
            printf("I can only count down from numbers 1, 2, or 3\n");
    }
}

Here we can see that if the value of number is 2, we'll perform case 2's execution and then fallthrough to case 1 as there's no break statement for case 2. Also note the default statement that is executed if number is not equal to 1, 2, or 3. We don't require a break for the last statement in a switch statement, but this is considered bad style as it's prone to bugs if more cases are added later. When adding these cases, you may forget to add a break to the previous case, causing your code to unintentioanlly fallthrough that case.

Here's another short example where we simply stack numerous cases together

#include <stdio.h>

int main(){
    int number;
    
    scanf("%d", &number);
    
    switch (number){
        case 4:
        case 5:
        case 6:
            printf("%d is between 4 and 6\n");
            break;
        default:
            printf("%d is not between 4 and 6\n");
            break;
    }
}

Again, this probably isn't a good use of a switch statement, but hopefully the functionality is apparent.

Some common errors

Now, there's a couple of strange tidbits to mention about switch statements, namely scope and variable declarations. Take the following example:

#include <stdio.h>

int main(){
    int number = 0;
    
    switch (number){
        case 0:
            int i = 0;
            printf("i is now %d", i);
            break;
        case 1:
            int i = 1;
            printf("i is now %d", i);
            break;
    }
}

If you try to compile this example, you'll might receive the following error:

error: a label can only be part of a statement and a declaration is not a statement
    int i = 0;

So... without going into too much detail, you can't have a declaration as the first line of case. Strange, but we have to accept it. So what can we do? Well, one thing we can do is insert an empty statement before the declaration:

#include <stdio.h>

int main(){
    int number = 0;
    
    switch (number){
        case 0:
            ;
            int i = 0;
            printf("i is now %d", i);
            break;
        case 1:
            ;
            int i = 1;
            printf("i is now %d", i);
            break;
    }
}

...Ew. But okay! We have a statement there now! Let's compile again:

error: redefinition of 'i'
    int i = 1;

Now we have an issue with scope. Each case statement doesn't define a scope, and so what we've really done is tried to declare two variable integers, i. So one thing we could do is declare i before the switch statement, which also solves our gross empty statement!

#include <stdio.h>

int main(){
    int number = 0;
    int i;
    
    switch (number){
        case 0:
            i = 0;
            printf("i is now %d", i);
            break;
        case 1:
            i = 1;
            printf("i is now %d", i);
            break;
    }
}

There's also another way we can solve these problems, which is to create blocks with curly braces inside each case:

#include <stdio.h>

int main(){
    int number = 0;
    
    switch (number){
        case 0:
            {
                int i = 0;
                printf("i is now %d", i);
                break;
            }
        case 1:
            {
                int i = 1;
                printf("i is now %d", i);
            }
            break;
    }
}

I typically use this method for all my switch statements when they start getting larger, as it feels natural to assume a scope for each separate case. Note that it doesn't matter if the break is enclosed in the braces or not, and in some situations not everything needs to be in braces either. However, excluding anything other than the break might fall to bad style. To read more about the declaration quirk, check out this answer on Stack Overflow.