Introduction to Conditional Statements and Control Structures in C++

Learn how to use conditional statements and control structures in C++ to write efficient and flexible programs. Explore loops, decision-making, and best practices.

Credit: Taras Shypka | Openverse

In C++, one of the key elements that contribute to a program’s functionality is the use of conditional statements and control structures. These features allow a program to make decisions, repeat actions, and control the flow of execution. Without these structures, programs would execute in a linear fashion, without any flexibility or logic to adapt to different conditions or inputs. Conditional statements and control structures enable programmers to write flexible, efficient, and interactive code that can solve complex problems.

In this article, we will explore the foundational concepts of conditional statements and control structures in C++. These include if-else statements, switch-case statements, loops, and conditional operators, which form the backbone of most decision-making and repetitive operations in a program.

In the first section, we will focus on understanding the basic conditional statements: if, else, and else if. We’ll also discuss how these statements work together to control program execution based on conditions. The concept of decision-making is central to any programming language, and C++ provides powerful tools to evaluate conditions and branch code accordingly.

The if Statement: Basic Decision-Making

The simplest form of decision-making in C++ is achieved using the if statement. The if statement allows a program to execute a block of code only if a specified condition is true. If the condition evaluates to false, the code block is skipped.

Here’s the basic syntax of an if statement:

if (condition) {
    // Code to execute if condition is true
}

The condition inside the parentheses is a logical expression, and it can evaluate to either true or false. If the condition is true, the block of code within the curly braces {} is executed. If the condition is false, the code inside the block is skipped.

Example:

#include <iostream>
using namespace std;

int main() {
    int age = 18;

    if (age >= 18) {
        cout << "You are eligible to vote." << endl;
    }

    return 0;
}

In this example, the program checks whether the value of age is greater than or equal to 18. If the condition evaluates to true, the message “You are eligible to vote” is printed to the console. Since age is set to 18, the condition is true, and the message is displayed.

The else Statement: Handling False Conditions

In many cases, you may want to execute one block of code if a condition is true and another block of code if the condition is false. This is where the else statement comes into play. The else statement is used to specify a block of code that runs if the condition in the if statement is false.

The syntax for using if with else is as follows:

if (condition) {
    // Code to execute if condition is true
} else {
    // Code to execute if condition is false
}

Example:

#include <iostream>
using namespace std;

int main() {
    int age = 16;

    if (age >= 18) {
        cout << "You are eligible to vote." << endl;
    } else {
        cout << "You are not eligible to vote." << endl;
    }

    return 0;
}

In this case, since age is less than 18, the condition in the if statement evaluates to false. As a result, the code inside the else block is executed, and the message “You are not eligible to vote” is printed to the console.

The else if Statement: Multiple Conditions

There are situations where a program needs to check multiple conditions and execute different code blocks depending on which condition is true. This is where the else if statement comes in. The else if statement allows you to test multiple conditions in sequence, and it executes the block of code associated with the first condition that evaluates to true.

The syntax for else if is:

if (condition1) {
    // Code to execute if condition1 is true
} else if (condition2) {
    // Code to execute if condition2 is true
} else {
    // Code to execute if none of the above conditions are true
}

Example:

#include <iostream>
using namespace std;

int main() {
    int age = 20;

    if (age < 13) {
        cout << "You are a child." << endl;
    } else if (age >= 13 && age < 20) {
        cout << "You are a teenager." << endl;
    } else {
        cout << "You are an adult." << endl;
    }

    return 0;
}

In this example, the program evaluates the age and categorizes it as “child”, “teenager”, or “adult” based on the value of age. If age is less than 13, the first block of code executes. If age is between 13 and 19, the second block runs. If neither of these conditions is true, the final else block is executed. Since age is set to 20, the output is “You are an adult.”

Nesting if Statements

C++ allows you to nest if statements inside other if statements to create more complex decision-making structures. This means you can place one if (or else if) statement inside the block of another if statement.

Example:

#include <iostream>
using namespace std;

int main() {
    int number = 15;

    if (number > 0) {
        if (number % 2 == 0) {
            cout << "The number is positive and even." << endl;
        } else {
            cout << "The number is positive but odd." << endl;
        }
    } else {
        cout << "The number is negative." << endl;
    }

    return 0;
}

In this example, the outer if checks if the number is positive. If the number is positive, the nested if checks whether it is even or odd. If the number is negative, the program immediately executes the else block. Here, number is 15, so the output will be “The number is positive but odd.”

The Ternary (Conditional) Operator

The ternary operator is a shorthand way of writing if-else statements. It’s particularly useful when you need to write concise conditional expressions. The ternary operator is represented by the ? and : symbols and follows this syntax:

condition ? expression1 : expression2;

If the condition is true, expression1 is executed; otherwise, expression2 is executed.

Example:

#include <iostream>
using namespace std;

int main() {
    int age = 18;
    string eligibility = (age >= 18) ? "You are eligible to vote." : "You are not eligible to vote.";
    cout << eligibility << endl;

    return 0;
}

In this example, the ternary operator checks if age is greater than or equal to 18. If the condition is true, the string “You are eligible to vote.” is assigned to eligibility. Otherwise, the string “You are not eligible to vote.” is assigned. The result is then printed to the console.

The ternary operator is particularly useful when you want to make quick decisions and assign values based on conditions, all within a single line of code.

The switch Statement: An Alternative to if-else

The switch statement is another control structure that is useful when you have to choose between multiple possible values for a single variable. It provides a cleaner and more readable alternative to multiple else if statements when you need to check the value of a variable against several fixed options.

The syntax of a switch statement is:

switch (variable) {
    case value1:
        // Code to execute if variable equals value1
        break;
    case value2:
        // Code to execute if variable equals value2
        break;
    default:
        // Code to execute if no matching case is found
}

The break statement is crucial because it prevents the program from continuing to check subsequent cases after a match has been found. If you omit break, the program will execute the code for all the following cases, even if one of them matches.

Example:

#include <iostream>
using namespace std;

int main() {
    int day = 3;

    switch (day) {
        case 1:
            cout << "Monday" << endl;
            break;
        case 2:
            cout << "Tuesday" << endl;
            break;
        case 3:
            cout << "Wednesday" << endl;
            break;
        case 4:
            cout << "Thursday" << endl;
            break;
        case 5:
            cout << "Friday" << endl;
            break;
        default:
            cout << "Weekend" << endl;
    }

    return 0;
}

In this example, the program checks the value of the variable day. Since day is 3, the program prints “Wednesday.” If no case matches, the default block is executed, providing a fallback option.

Introduction to Control Structures: Loops in C++

While conditional statements like if, else, and switch help a program make decisions, control structures like loops allow the program to repeat a set of instructions multiple times. Loops are essential in programming because they let you automate repetitive tasks, process large datasets, or iterate over collections of data.

C++ provides three primary loop structures: for, while, and do-while loops. Each of these loops is used for different situations, depending on whether the number of iterations is known beforehand or the condition must be checked at the beginning or end of each iteration. In this section, we will explore each of these loops, explain how they work, and examine common use cases for each.

The for Loop: Iterating a Fixed Number of Times

The for loop is one of the most commonly used loops in C++, and it is ideal for situations where the number of iterations is known in advance. It allows you to repeat a block of code a specific number of times by controlling the loop using a counter or an index variable.

Syntax of the for Loop

The for loop consists of three main components:

  1. Initialization: Setting the loop control variable to an initial value.
  2. Condition: A test condition that is evaluated before each iteration. If the condition is true, the loop continues; if false, the loop terminates.
  3. Increment/Decrement: Updating the loop control variable after each iteration.

Here’s the basic syntax:

for (initialization; condition; increment/decrement) {
    // Code to execute during each iteration
}

Example:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 5; i++) {
        cout << "Iteration " << i << endl;
    }
    return 0;
}

In this example:

  • The loop control variable i is initialized to 0.
  • The condition i < 5 ensures that the loop runs while i is less than 5.
  • After each iteration, the control variable i is incremented by 1.
  • The loop prints “Iteration” followed by the current value of i, and it repeats five times, with i taking the values 0 through 4.

Using the for Loop to Iterate Over Arrays

The for loop is particularly useful for iterating over arrays or collections of data. Let’s look at an example where the for loop is used to process an array:

#include <iostream>
using namespace std;

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    for (int i = 0; i < size; i++) {
        cout << "Element at index " << i << ": " << numbers[i] << endl;
    }

    return 0;
}

In this example:

  • An array numbers[] holds five integers.
  • The for loop iterates over each element in the array, and the size of the array is determined dynamically using sizeof().
  • During each iteration, the loop prints the index and the corresponding array element.

The while Loop: Conditional Iteration

The while loop is used when the number of iterations is not known beforehand, and the loop should continue executing as long as a certain condition remains true. Unlike the for loop, where the control variable is typically part of the loop structure, the while loop checks the condition at the beginning of each iteration and relies on manual updates within the loop body.

Syntax of the while Loop

while (condition) {
    // Code to execute as long as condition is true
}

The loop continues as long as the condition evaluates to true. If the condition is false at the beginning, the loop body will not be executed even once.

Example:

#include <iostream>
using namespace std;

int main() {
    int count = 0;

    while (count < 5) {
        cout << "Count: " << count << endl;
        count++;  // Increment count
    }

    return 0;
}

In this example:

  • The while loop runs as long as the value of count is less than 5.
  • During each iteration, the value of count is printed, and then it is incremented by 1.
  • The loop terminates once count reaches 5, ensuring that the loop executes exactly five times.

Using while for Input Validation

The while loop is often used for input validation, where you want to repeatedly prompt the user for input until they provide a valid response.

#include <iostream>
using namespace std;

int main() {
    int number;

    cout << "Enter a number between 1 and 10: ";
    cin >> number;

    while (number < 1 || number > 10) {
        cout << "Invalid input. Please try again: ";
        cin >> number;
    }

    cout << "You entered: " << number << endl;
    return 0;
}

In this example:

  • The while loop ensures that the user enters a number between 1 and 10. If the user enters an invalid number, the loop repeats until valid input is provided.

The do-while Loop: Post-Condition Loop

The do-while loop is similar to the while loop, but with one important difference: the condition is checked at the end of each iteration. This guarantees that the loop body is executed at least once, even if the condition is false initially.

Syntax of the do-while Loop

do {
    // Code to execute
} while (condition);

Example:

#include <iostream>
using namespace std;

int main() {
    int count = 0;

    do {
        cout << "Count: " << count << endl;
        count++;
    } while (count < 5);

    return 0;
}

In this example:

  • The loop first prints the value of count, then increments it.
  • After each iteration, the condition count < 5 is checked. The loop repeats until count reaches 5.
  • Because the condition is checked after the loop body, the loop will run at least once, even if count is initially greater than or equal to 5.

Use Case for do-while: Menu Systems

The do-while loop is commonly used in menu-driven programs where the menu should be displayed at least once, and then the user is prompted to make a choice. Here’s a simple example of using do-while to implement a basic menu system:

#include <iostream>
using namespace std;

int main() {
    int choice;

    do {
        cout << "Menu:" << endl;
        cout << "1. Option 1" << endl;
        cout << "2. Option 2" << endl;
        cout << "3. Exit" << endl;
        cout << "Enter your choice: ";
        cin >> choice;

        switch (choice) {
            case 1:
                cout << "You selected Option 1." << endl;
                break;
            case 2:
                cout << "You selected Option 2." << endl;
                break;
            case 3:
                cout << "Exiting program." << endl;
                break;
            default:
                cout << "Invalid choice. Please try again." << endl;
        }
    } while (choice != 3);

    return 0;
}

In this example:

  • The do-while loop ensures that the menu is displayed at least once.
  • The loop continues to display the menu until the user selects option 3 (exit).
  • The switch statement inside the loop handles the user’s choice and provides the appropriate response.

Breaking and Continuing Loops

C++ provides two important statements to control the flow of loops:

  • break: Exits the loop entirely, terminating it even if the loop’s condition is still true.
  • continue: Skips the remaining statements in the current iteration and proceeds to the next iteration of the loop.

The break Statement

The break statement is used to exit a loop prematurely when a certain condition is met.

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            break;  // Exit the loop when i equals 5
        }
        cout << "Iteration " << i << endl;
    }

    return 0;
}

In this example, the for loop terminates when i reaches 5, even though the condition of the loop is i < 10. The output will display iterations 0 through 4, and the loop will exit after printing “Iteration 4”.

The continue Statement

The continue statement skips the current iteration and jumps to the next iteration, bypassing the remaining code in the loop body.

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            continue;  // Skip the rest of the loop when i equals 5
        }
        cout << "Iteration " << i << endl;
    }

    return 0;
}

In this case, when i equals 5, the continue statement skips the current iteration, so the message “Iteration 5” is not printed. The loop continues with the next iteration.

Nested Loops and Control Structures

In C++, nested loops and nested conditional statements enable more complex control flow within a program. A nested loop refers to a loop inside another loop, and similarly, a nested conditional statement is when one conditional statement is placed inside another. These structures are often used when working with multidimensional arrays or handling complex data-processing tasks that require multiple levels of iteration or decision-making.

Nested for Loops

The nested for loop is frequently used in situations where you need to iterate over multiple dimensions of data, such as traversing a matrix or processing nested lists. A common use case is iterating over a two-dimensional array (or matrix), where you have one loop to traverse the rows and another to traverse the columns.

Example: Using Nested for Loops for a 2D Array

#include <iostream>
using namespace std;

int main() {
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

In this example:

  • We have a 3×3 matrix (2D array) and use a nested for loop to iterate over each element.
  • The outer loop (i) iterates over the rows, and the inner loop (j) iterates over the columns.
  • The matrix is printed row by row as the loops iterate through each element.

Nested while and do-while Loops

Similar to nested for loops, you can also nest while or do-while loops. Nested loops can be useful when performing tasks that involve checking conditions at multiple levels.

Example: Nested while Loop

#include <iostream>
using namespace std;

int main() {
    int i = 0;

    while (i < 3) {
        int j = 0;
        while (j < 3) {
            cout << "(" << i << "," << j << ")" << " ";
            j++;
        }
        cout << endl;
        i++;
    }

    return 0;
}

In this example:

  • We use nested while loops to simulate a grid of coordinates, printing (i, j) pairs.
  • The outer loop controls the row (i), and the inner loop controls the column (j), effectively printing a grid of 3×3 coordinates.

Nested if-else Statements

Nested if-else statements are useful when multiple conditions need to be checked, and each condition depends on the result of the previous condition. This can be particularly helpful in more complex decision-making scenarios where you need to evaluate several interdependent conditions.

Example: Nested if-else Statement

#include <iostream>
using namespace std;

int main() {
    int score = 85;

    if (score >= 90) {
        cout << "Grade: A" << endl;
    } else {
        if (score >= 80) {
            cout << "Grade: B" << endl;
        } else {
            if (score >= 70) {
                cout << "Grade: C" << endl;
            } else {
                cout << "Grade: F" << endl;
            }
        }
    }

    return 0;
}

In this example:

  • We use nested if-else statements to assign a grade based on the value of score.
  • The first condition checks if the score is greater than or equal to 90. If this is false, the program checks the next range (80-89), and so on.
  • This approach allows for detailed decision-making but can become cumbersome with many conditions.

Best Practices for Control Structures

To write efficient and maintainable C++ programs, it’s important to follow best practices when using control structures like loops and conditional statements. Here are some guidelines that will help you write better code:

1. Avoid Deeply Nested Loops and Conditions

Deeply nested loops and conditions can make code hard to read and maintain. If you find that your code has multiple levels of nesting, consider breaking it into smaller, more modular functions. This makes the code easier to debug and understand.

// Instead of deeply nested loops, refactor into a function
void processMatrix(int matrix[3][3]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }
}

2. Use Meaningful Variable Names

When working with loops and conditions, it’s important to use descriptive variable names that indicate the purpose of the variable. For example, use row and col instead of i and j when iterating over a matrix to make the code more readable.

for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
        cout << matrix[row][col] << " ";
    }
}

3. Break Complex Conditions into Functions

When you have complex conditions in if-else statements, it’s a good idea to encapsulate them into functions. This improves readability and makes it easier to reuse the logic elsewhere in your code.

bool isEligibleForDiscount(int age) {
    return age >= 18 && age <= 25;
}

if (isEligibleForDiscount(userAge)) {
    cout << "You are eligible for a discount." << endl;
} else {
    cout << "You are not eligible for a discount." << endl;
}

4. Use switch for Multiple Discrete Conditions

The switch statement is preferable over multiple if-else conditions when testing a single variable against many discrete values. It provides better performance and is easier to read.

switch (menuChoice) {
    case 1:
        cout << "Option 1 selected." << endl;
        break;
    case 2:
        cout << "Option 2 selected." << endl;
        break;
    default:
        cout << "Invalid choice." << endl;
}

5. Avoid Infinite Loops

Ensure that your loops have a well-defined termination condition to avoid infinite loops, which can crash your program. Always make sure the loop control variables are updated properly, and the exit condition is reachable.

// Ensure the loop variable is updated to avoid an infinite loop
while (counter < 10) {
    cout << counter << endl;
    counter++;  // Correctly update counter
}

Control Flow in Algorithms: A Case Study

Now that we’ve covered loops and conditional statements, let’s look at a practical example of how control structures are used in algorithms. One classic algorithm that demonstrates control flow in action is Bubble Sort. This algorithm sorts an array of numbers by repeatedly swapping adjacent elements if they are in the wrong order.

Example: Bubble Sort Algorithm

#include <iostream>
using namespace std;

void bubbleSort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // Swap the elements
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int size = sizeof(arr) / sizeof(arr[0]);

    bubbleSort(arr, size);
    cout << "Sorted array: ";
    printArray(arr, size);

    return 0;
}

In this example:

  • The nested for loop iterates over the array multiple times, comparing and swapping adjacent elements until the array is sorted.
  • The control structures in the Bubble Sort algorithm ensure that the array is processed in the correct order, making it a simple yet effective sorting algorithm.

Mastering Control Structures in C++

Conditional statements and control structures are foundational tools in C++ that enable decision-making and repetitive operations. By mastering these concepts, you can write flexible, efficient, and complex programs that adapt to various conditions and automate tasks. In this article, we covered:

  • Conditional statements (if, else, else if, switch), which allow for branching logic.
  • Loop structures (for, while, do-while), which enable repetition of code blocks.
  • Techniques for controlling the flow of loops (break and continue), and handling nested loops and conditionals.
  • Best practices for writing clean, readable, and maintainable code using these control structures.

By applying these techniques and principles, you will be able to develop programs that are not only functional but also optimized and easy to understand. As you continue working with C++, practicing these structures and exploring more complex scenarios will deepen your understanding of the language and improve your programming skills.

Discover More

Understanding Clustering Algorithms: K-means and Hierarchical Clustering

Explore K-means and Hierarchical Clustering in this guide. Learn their applications, techniques, and best practices…

What is Instance-Based Learning?

Discover what instance-based learning is, its applications and best practices for building adaptable, memory-efficient machine…

Introduction to Programming: A Beginner’s Guide

Explore the basics of programming in this beginner’s guide. Learn about languages, tools, and career…

Introduction to Operating Systems

Learn about the essential functions, architecture and types of operating systems, and explore how they…

Introduction to Machine Learning

Learn the fundamentals of machine learning from essential algorithms to evaluation metrics and workflow optimization.…

Variables and Data Types in C#

Learn about variables, data types, type safety and type inference in C# to write efficient…

Click For More