Learn C++ with Qt, Part 011:
Control Structures - If-Then-Else


So far, our programs have been very linear affairs - every line was executed step by step, from the top to the bottom of the code. 

Of course, that is not the way to write complex applications where your program has to react to different situations when you run it again and again. Most applications need at least a simple logical flow. Just like cooking according to a recipe from a cookbook, once you have all necessary ingredients and tools, you need to perform certain steps in a given order, while other steps can be performed at different times or even in parallel (if you have someone to help you with cooking).

That is where control structures come in. 

What is a control structure?

As the name implies, a control structure is a part of the program which allows you to control the logical flow within the program, i.e. control which part is executed next.

There are different types of control structures in C++ (just like in other programming languages). Which one you use at a given point in your program depends on the structure of the logical flow you want to implement.

When I talk about logical flow, that refers to a flow diagram representation of the program or application. You can find out more about that on the Wikipedia pages about flow diagrams.

IF... THEN...

The "if-then" construct is one of the simplest forms of control structures. It represents a simple, binary branch within the flow of the program.

The "if"-statement needs to be followed by a logical operation which at runtime can either be true or false. While more complex computations can be part of the boolean statement, it needs to be able to be computed into one of those two logical values.

When the value of the boolean operation is true, then the following block of code is executed, otherwise it is simply skipped.

In C and C++, there is no "then" keyword after the if statement. Instead, the "then"-part which is executed if the boolean operation returns "true", is simply marked by the wavy brackets which mark the beginning and end of the code block. Here is an example:

if (myVar > 42) { // execute this code if value of myVar is bigger than 42 // ... };

Every line of code which is contained in the "if"-code block is executed only if the boolean operation after the "if" statement returns true. In the example above, the code would be executed if the value stored in the variable "myVar" is bigger than 42. If the value is equal or lower than 42, the code within this block would not be executed.

...ELSE…

Any code after the end of the "if" code block will be allways executed, no matter which value the boolean operation for the "if" statement returns.

Often enough though, we want to execute a different part of the code if the boolean operation returns the value "false". For this, the "if" statement can be expanded using the "else" keyword after the related code block.

In C and C++, it looks like this:

if (myVar > 42) { // execute this code if value of myVar is bigger than 42 // ... } else { // do something else if value of myVar is less or equal to 42 // ... };

Just like before, the first code block in the example above will be executed if the value of "myVar" is bigger than 42. If the value is smaller than or equal to 42, then the first code block will not be executed. Instead, the program will continue with the execution of any code that is contained in the second code block after the "else" keyword.

Any code after the "else" code block will be executed independent of the value of "myVar".

Example program

Let's take a look at a small example.

I've created a new Qt console project named "IfThenElse" for this.

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. The code is based on what we've learned in earlier parts of this tutorial about text input and output, adding some "if-then-else" control structures.

Here is the coding:

#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); if (selection=='r') { // the R key was pressed printf("RED LIGHT:"); printf("The if the traffic light is red, then stop."); } else { // other key was pressed if (selection=='y') { // the Y key was pressed printf("YELLOW LIGHT:"); printf("The if the traffic light shows yellow, slow down and stop."); } else { // other key was pressed if (selection=='g') { // the G key was pressed printf("GREEN LIGHT:"); printf("The if the traffic light is green, then go."); } else { // other key was pressed printf("Please only press R, Y or G."); }; }; }; return a.exec(); }

Just like before, this is a simple console application. Once you compile and run it, you see a simple window with the initial text that prompts you to enter a letter.

Once the letter has been entered, it is converted into a lowercase version of the same letter by the " selection = tolower(selection); " command line.

The "tolower()" command is actually a function which is part of the C++ standard library. We'll be looking at functions in more depth in a later part of this tuturial.

For now, just accept that "tolower" returns a lower case version of a single character or a string by converting any uppercase characters contained in the character or string it was given. This is then again stored in the "selection" variable.

The conversion simplifies the following boolean operations since we only need to look at lower case characters.

The first "if"-statement then compares the input (which is stored in the "selection" variable) with the letter "r":

 if (selection=='r')

From the earlier parts of this tutorial, you should be able to see that "selection" is a variable of type "char" - this is defined right at the beginning of the main function.

Similarly, 'r' is recognizable as a character literal.

The round brackets just act as a container for the boolean expression which has to be evaluated by the computer in order to determine which part of the program has to be executed next.

As you might guess, the two equal signs (==) define the actual operation - in this case, a direct comparison of the values to the left and right side of the operation.

It's easy to confuse the boolean operator "==" with the single equal operator "=".

The first (==) compares two values (left and right to it) and returns a boolean value. The result is "true", if both values are equal, otherwise it is "false".

The normal, single equal operator (=) does not perform a computation, but instead assigns any value on the right side to the variable on the left side. So it does not return a boolean value in and of itself, it can only assign a boolean value to a boolean variable.

Boolean operators

For the "if"-statement - as well as for some other control structures - boolean operators are important. While you can also define a boolean variable and assign it a boolean value either directly or as the result of a boolean operation, usually the relevant boolean operations are placed right where the "if"-structure (or a similar control structure) needs a boolean value in order to decide where to resume the program.

There are some different boolean operators that you can use:

Operator Example Operation
== a == b returns TRUE if values of a and b are equal, otherwise returns FALSE
!= a != b returns TRUE if values of a and b are not equal, otherwise returns FALSE
< a < b returns TRUE if the value of a is smaller than the value of b, and returns FALSE if the value of a is equal or bigger than the value of b
> a > b returns TRUE if the value of a is bigger than the value of b, and returns FALSE if the value of a is equal or smaller than the value of b
<= a <= b returns TRUE if the value of a is smaller or equal than the value of b, and returns FALSE if the value of a is bigger than the value of b
>= a >= b returns TRUE if the value of a is bigger or equal than the value of b, and returns FALSE if the value of a is smaller than the value of b

For the example above, the equality comparison operator is enough. The code block after each "if"-statement is executed, if the letter you entered is equal to the character it is compared to. If it is not equal to the character in question, the execution of the program continues with the code block after the "else"-statement.

Stacking / Code hierarchy

What you can also see from the example above is somthing that is typical for more complex coding: code stacking, which creates a hierarchical structure within the code. 

This basically follows the structure of the logical flow of the program. Different parts of the code can be part of a specific branch within the flow structure.

Once a specific part of the code is selected based on a boolean operation (during runtime), this part can contain further boolean operations, each of which can have its own sub-branches.

When the execution of a code branch is finished - i.e. the last line of code in that branch has been executed - the computer continues with the execution at a point after the code block of the last boolean operation.

In the example above, if you enter the letter "r", the code in the first block right after the first "if"-statement ("if (selection=='r')")  is executed. Once the text for the red light has been printed on the screen, the computer will skip all of the code in the following "else"-statment's code block, and jump straight to the next line of code after that, which is "return a.exec();".

The same happens for the additional "if"-/"else"-statments and related code blocks within the first "else"-block, but since there is no additional code after each "else"-block, you cannot directly see this.

If you want to follow the code execution in more detail, you can add additional "printf()"-statements after each if/else-structure.

Final words

While "if"-statements are simple, they are pretty useful nonetheless. Feel free to experiment with them.

I hope you will also be joining me for the next part in this series. Stay tuned...