Control structures

Control structures are fundamental in programming languages that allow developers to control the flow of code execution based on certain conditions. These structures enable programmers to create programs that can make decisions, iterate over collections of data, and execute blocks of code repeatedly. This lesson will cover three such structures:

  • The if statement

  • The else if statement

  • The switch statement

Since all control structures rely on conditional statements that involve relational and logical operators, it’s a good idea to start by refreshing our knowledge of these operators.

Relational operators

Relational operators, also known as comparison operators, are used in programming to compare two values and return a boolean result. C++ provides six comparison operators, which are ==, !=, >, >=, <, and <=. When a comparison operator is executed, it returns either 1 or 0, depending on whether the comparison is true or false, respectively. Let’s take a look at an example of a comparison expression and see how it works with different relational operators.

Relational Operators

Symbol

Operation

Example

==

Equal to

1==1

This expression will be evaluated to 1.

!=

Not equal to

1!=1

This expression will be evaluated to 0.

>

Greater than

1>2

This expression will be evaluated to 0.

>=

Greater than or equal to

7>=7

This expression will be evaluated to 1.

<

Less than

6<9

This expression will be evaluated to 1.

<=

Less than or equal to

6<=9

This expression will be evaluated to 1.

Note: In C++, 0 is the result of the comparison if it evaluates to logical false, and 1 if it evaluates to true.

Logical operators

Logical operators in C++ are used to combine conditions or expressions and return a boolean value. C++ provides three logical operators: AND (&&), OR (||), and NOT (!).

  • AND returns true only if both conditions are true.

  • OR returns true if at least one condition is true.

  • NOT inverts the result of a condition.

Let’s look at an example of a logical expression and see how it works with different logical operators.

Logical Operators

Symbol

Operator

Example

&&

AND operator

(1==1 && 1>=2) will be evaluated to

(true && false) => 0 (false).

||

OR operator

(1==1 || 1>=2) will be evaluated to

(true || false) => 1 (true).

!

NOT operator

!(1==1 || 1>=2) will be evaluated to

!(true || false) => !(true)

=> 0 (false).


Now that we’ve grasped the concept of relational and logical operators, we can learn how we can apply these boolean expressions on conditional statements to manage a program’s flow.

The if statement

The if statement in C++ is a powerful control structure used for making decisions based on conditions. When using a single statement, the if statement evaluates a condition and, if true, executes the associated statement; otherwise, it is skipped. The syntax for an if statement with a single associated statement is as follows:

if (condition)
single_statement; // This statement executes if the condition is true
Syntax for the if statement (with a single associated statement)

On the other hand, when multiple statements need to be executed under the same condition, a compound statement (block) is employed, enclosing the statements within curly braces to ensure they are treated as a single unit of execution when the condition is true. The syntax for an if statement with a compound associated statement is as follows:

if (condition)
{
// statement 1
// statement 2
// ...
// statement n
}
Syntax for the if statement (with a compound associated statement)

By enclosing the statements within curly braces, we ensure that all the statements inside the block are executed when the condition is true. This approach not only improves code organization but also ensures that the multiple statements are treated as a single unit of execution.

Example: Finding the maximum

Let’s write a program that calculates the maximum of the five integers taken from the user. Add five different values in the input prompt with single spaces between them (1 2 3 4 5) and click the “Run” button.

Press + to interact
#include <iostream>
using namespace std;
int main()
{
int v1, v2, v3, v4, v5, max;
cin >> v1 >> v2 >> v3 >> v4 >> v5;
max = v1;
if(v2 > max)
max = v2;
if(v3 > max)
max = v3;
if(v4 > max)
max = v4;
if(v5 > max)
max = v5;
cout << "Maximum of " << v1 << " " << v2 << " " << v3 << " " << v4 << " "
<< v5 << " is: " << max << '\n';
}

Enter the input below

Note: The input values can be separated by a single space or written in a new line.

The if-else statement

An if-else statement is a programming construct that allows us to execute a block of code if a certain condition is true, and another block of code if the condition is false. The blocks of code can consist of a single instruction or multiple instructions. If we only have one instruction in a block, we can choose to omit the block delimiters (the { } that surround the block of code).

In simpler terms, an if-else statement is a way for a program to make decisions based on certain conditions, and it allows us to execute different code depending on whether the condition is true or false.

Press + to interact
if(condition)
{
//Statements
}
else
{
//Statements
}

Let’s solve an example problem using the if-else statement.

Example: Letter case conversion

Let’s write a program that converts the lowercase letter to uppercase and the uppercase to lowercase.

Note: We can use the ASCII values to solve this problem. Characters are stored as ASCII values in the char data type. For example, 'A' has an ASCII value of 65, 'B' has an ASCII value of 66, and so on. Similarly, 'a' has an ASCII value of 97, 'b' has an ASCII value of 98, and so on. The difference between the ASCII values of uppercase and lowercase letters occurs 32.

Let’s look at the program with a logical error.Logicalerror

Here’s the code solution:

Press + to interact
#include <iostream>
using namespace std;
int main()
{
char x;
cin >> x;
cout << "Convert the character: '" << x << "' into the alternative case\n";
if(x >= 97 && x<= 122)
{
x -= 32;
}
if(x >= 65 && x <= 90)
{
x += 32;
}
cout << "The converted version of character x is: " << x << "\n";
}

Enter the input below

The output of the above problem shows that the character x is not converted into the alternative case even though the condition and desired operation are working fine. So, what seems to be the problem? The following animation will help identify the issue. Let’s look into the flow of the above program.

In the animation above, we have defined a character 'b' in lowercase. The expression in the first condition evaluates to true and converts the value inside x to uppercase. After the complete execution of the first condition block, the character assigned to x is in uppercase: 'B'. This would evaluate to true for the condition in the second if, which is wrong. In case of the successful execution of the first condition, the program control should not execute the second condition. How can we do that?

We can use the else if statement because it is only executed when the first if statement evaluates to false. Let’s look at the correct code solution.

Press + to interact
#include <iostream>
using namespace std;
int main()
{
char x;
cin >> x;
cout << "Convert the character: '" << x << "' into the alternative case\n";
if(x >= 97 && x<= 122)
{
x -= 32;
}
else if(x >= 65 && x <= 90)
{
x += 32;
}
cout << "The converted version of character x is: " << x << "\n";
}

Enter the input below

As we can see, using the else-if control statement gave us the desired result. To understand this better, let’s look at the given animation.

The switch statement

In a switch statement, the expression or variable being evaluated can be any valid cardinal/ordinal expression or variable. This means it can be a literal value, a variable, or an integer result of an expression (remember that it can't be a floating value). The key point is that the value of the expression or variable determines which case statement is executed. The switch statement is considered efficient because it allows the program to jump directly to the appropriate case statement based on the value of the expression or variable rather than evaluating a series of if-else statements.

Here’s the general syntax of the switch statement:

switch(expression) // expression could be any varaible or any mathematical expression
{
case constant1:
// code to execute if expression matches constant1
break;
case constant2:
// code to execute if expression matches constant2
break;
...
default:
// code to execute if none of the constants match the expression
break;
}
Syntax for the switch-case statements

Example: Calculating the grades of students

Calculating the students’ grades using the given marks and the distribution of grades is as follows:

Grades Distribution

Marks

Grade

Between 90 and 100

A

Between 80 and 89

B+

Between 70 and 79

B

Between 60 and 69

C

Between 50 and 59

D

Below 50

F

Let’s look at the code solution.

Press + to interact
#include <iostream>
using namespace std;
int main()
{
int marks;
cin >> marks;
if(marks <= 100 && marks >= 0)
{
switch(marks / 10)
{
case 10:
case 9: // for 90 to 100
cout << "A" << '\n';
break;
case 8: // for 80 to 89
cout << "B+" << '\n';
break;
case 7: // for 70 to 79
cout << "B" << '\n';
break;
case 6: // for 60 to 69
cout << "C" << '\n';
break;
case 5: // for 50 to 59
cout << "D" << '\n';
break;
default: // for any value below 50
cout << "F" << '\n';
}
}
else
{
cout << "Wrong marks entered." << '\n';
}
return 0;
}

Enter the input below

  • Line 6: We define the marks variable that determines the students’ marks.

  • Line 8: We evaluate the condition to ensure the given marks are in the 0–100 range.

  • Line 10: We apply the switch statement to the expression marks / 10. For case 9 and case 10, it’ll give the A grade because of the integer division.

  • Lines 12–29: The grade of the student is evaluated using the case statements.

Note: The break statement is essential in the switch statement. If we don’t write break at the end of a case, the execution control falls through, meaning that the code for subsequent cases will be executed regardless of whether they match the expression's result or not, including the default case.

We can rewrite the same code using the ellipses operator ( ... ).

Press + to interact
#include <iostream>
using namespace std;
int main() {
int marks;
cin >> marks;
switch(marks){
case 90 ... 100:
cout << "A" << '\n';
break;
case 80 ... 89:
cout << "B+" << '\n';
break;
case 70 ... 79:
cout << "B" << '\n';
break;
case 60 ... 69:
cout << "C" << '\n';
break;
case 50 ... 59:
cout << "D" << '\n';
break;
case 0 ... 49:
cout << "F" << '\n';
break;
default:
cout << "Invaid marks";
}
return 0;
}

Enter the input below

The ellipsis operator (...) in the switch statements is used to specify a range of values that a variable can take, and it behaves like a range function. In this code, the marks variable represents the marks obtained by a student in an exam. The switch statement evaluates the value of marks and checks which range it falls into.

The code in the corresponding case statement will be executed if marks falls within a specific range. For example, if marks is 80, the second case (that is, case 80 ... 89) will be executed because it specifies a range that includes 80. The program will then output B+ to indicate that the student has obtained a B+ grade.

If marks does not fall into any of the specified ranges, the default statement will be executed, and the program will output Invalid marks.