Learn C++ with Qt, Part 012:
Control Structures - Switch-Case


In the last part, we looked at the basic "if-then-else" control structure. 

This allows the computer to execute different parts of a program based a runtime condition or calculation that can be converted into a boolean "yes/no" decision.

If you have more complex conditions that your program needs to react to, a simple two-way flow branch may not be enough. Often, the result of a given check or computation can lead to a list of different output values. In order to execute code that is tailored to each of these values, you would need to create a complex structure of "nested" if-statements.

With more output values, this can get complicated and introduce several problems (if you aren't careful enough).

Thankfully, in such cases we can use the "switch"-statement instead of a couple of nested "if"-statments.

Switch statement

Just like the "if"-statement, the "switch"-statement is a control structure that allows the conditional execution of different parts of the program. 

In its basic form, you can use it similar to an "if"-statement. However, instead of just two options for your condition, you get more - as much as you need.

The basic syntax for the "switch"-statement looks like this:

switch(EXPRESSION) { case CONSTANT_EXPRESSION_1: // ... do something ... break; case CONSTANT_EXPRESSION_2: // ... do something else ... break; // ... continue as needed ... default: // ... do something if everything else fails ... break; };

In the example code above, "EXPRESSION" can be a variable or a computation or function call that results in a value (based on other conditions, current values of other variables etc.). The result of the expression acts as the input value for the switch-case statement.

Similar to the boolean true or false values for the condition in an "if"-statement, the input used for "switch" should have a limited number of concrete values. For example, if a key was pressed, the resulting character can be analysed and compared to expected inputs within the "case" statements. This would allow you - just as an example - to only accept and handle number keys. 

Case condition blocks

While the selection value for the case statements is entered right after "switch", the following "case" blocks contain the code instructions for each of the possible input values.

In the example above, each "case" statement handles a single value option or value-based condition. The code directly after a single "case" statement is only executed, if the case condition is true (i.e. if the value of "EXPRESSION" is equal to the value of "CONSTANT_EXPRESSION_1", "CONSTANT_EXPRESSION_2" and so on).

If none of the case conditions are true for the initial switch input value, none of the related code blocks will be executed and the program will continue after the switch-case block.

Along with specific case conditions, you can use the "default" case as shown in the example above.

The code contained in the "default" block is executed when all other case conditions have been checked and none of them was true. As the name implies, this is the default option that is executed if everything else fails.  

The "default" case is just an option within the switch-case control structure. You can leave it out of you don't need it.

Break statement

In the above example, the "break;" statement at the end of each "case" block is important to note. 

It tells the computer to stop executing code contained in the following "case" code blocks and continue to execute the program after the end of the current "switch-case" structure. This way, if one of the case conditions is true, only the code for this specific case block is executed.

However, you can leave out one or more "break" statements if you need to combine some case block with a following case block coding. Occasionally this can be useful, but you need to be careful with this - it can mess up your logical flow pretty fast.

Example program

As an example, I've created a new Qt console project named "Switch". The code is based on the "IfThenElse" example from the previous part of the tutorial.

Just like before, this is based on a standard traffic light. You can enter one of the letters "R", "Y" or "G" to select red, yellow or green. After entering one of these letters, the program prints out some text related to the chosen color. 

Instead of using nested "if"-statements, I've changed the code to use a "switch-case" control structure instead:

#include <QCoreApplication> #include <stdio.h> int main(int argc, char *argv[]) { char selection; QCoreApplication a(argc, argv); printf("Please think of a traffic light with red, yellow and green lights."); printf("Choose one of the colors by pressing the R, Y or G key: "); selection = getchar(); selection = tolower(selection); switch(selection) { case 'r': // the R key was pressed printf("RED LIGHT:"); printf("The if the traffic light is red, then stop."); break; case 'y': // the Y key was pressed printf("YELLOW LIGHT:"); printf("The if the traffic light shows yellow, slow down and stop."); break; case 'g': // the G key was pressed printf("GREEN LIGHT:"); printf("The if the traffic light is green, then go."); break; default: // other key was pressed printf("Please only press R, Y or G."); }; return a.exec(); }

Here, the switch value is the key that was entered by the user. Each "case" block only prints the text related to the letters "R", "Y" or "G".

The "default" case is used when other characters were entered. As you might notice, I haven't added a "break" statement at the end of the code block for the "default" case. Usually, like in this example, the default section is placed at the end of the switch segment, so the execution of the program will automatically continue after this point.

As you can see, this code looks a little simpler than the nested "if"-statements from the previous part of the tutorial. Since the expected input values are only a few, the "switch"-statement is a good way to execute different sections of code related to the input.

Final words

Our example still is a little rough. We need to add other types of control structures in order to transform it in a useful way.

So please come back for the next installment of this tutorial...