Looping Statements in C++

Looping statements, also known as loops or iteration statements, allow you to execute a block of code repeatedly until a certain condition is met. They are essential for handling repetitive tasks efficiently in programming.

1. Types of Loops in C++

C++ provides three primary types of loops:

  1. for loop - used when the number of iterations is known in advance
  2. while loop - used when the number of iterations is not known in advance
  3. do-while loop - similar to while loop but guarantees at least one execution

Each type of loop has its own syntax and best use cases.

2. The for Loop

The for loop is the most versatile and commonly used loop in C++. It’s particularly useful when you know exactly how many times you want to execute a block of code.

Syntax:

for (initialization; condition; update) {
    // code to execute in each iteration
}

Where:

  • initialization: Executed once before the loop begins
  • condition: Evaluated before each iteration; loop continues if true
  • update: Executed after each iteration

Example:

#include <iostream>
using namespace std;

int main() {
    // Print numbers 1 to 5
    for (int i = 1; i <= 5; i++) {
        cout << i << " ";
    }
    // Output: 1 2 3 4 5
    
    return 0;
}

Variations of for Loop:

1. Multiple Initializations and Updates:

for (int i = 0, j = 10; i < j; i++, j--) {
    cout << "i = " << i << ", j = " << j << endl;
}

2. Omitting Parts:

// Initialization outside the loop
int i = 0;
for (; i < 5; i++) {
    cout << i << " ";
}

// Infinite loop with break condition
for (int j = 0; ; j++) {
    if (j >= 5) break;
    cout << j << " ";
}

// Update within the loop body
for (int k = 0; k < 5;) {
    cout << k << " ";
    k++;
}

3. Range-based for Loop (C++11 and later):

int numbers[] = {1, 2, 3, 4, 5};

// Traditional way
for (int i = 0; i < 5; i++) {
    cout << numbers[i] << " ";
}

// Range-based for loop
for (int num : numbers) {
    cout << num << " ";
}

Important Points:

  1. Variables declared in the initialization part are local to the loop.
  2. The condition is checked before each iteration, including the first one.
  3. If the condition is initially false, the loop body never executes.
  4. The update expression executes after each iteration, not before.
  5. All three parts of the for loop are optional.

3. The while Loop

The while loop repeatedly executes a block of code as long as a specified condition is true. It’s ideal when the number of iterations isn’t known beforehand.

Syntax:

while (condition) {
    // code to execute while condition is true
}

Example:

#include <iostream>
using namespace std;

int main() {
    int i = 1;
    
    while (i <= 5) {
        cout << i << " ";
        i++;
    }
    // Output: 1 2 3 4 5
    
    return 0;
}

Important Points:

  1. The condition is evaluated before each iteration.
  2. If the condition is initially false, the loop body never executes.
  3. The condition must eventually become false, or the loop will continue indefinitely (infinite loop).
  4. Variables used in the condition must be initialized before the loop and updated inside the loop.

Common Use Cases:

  1. Processing input until a sentinel value:
int number;
cout << "Enter numbers (0 to quit): ";

while (true) {
    cin >> number;
    if (number == 0) break;
    cout << "You entered: " << number << endl;
}
  1. Processing until a specific condition:
string password;
cout << "Set a password (at least 8 characters): ";

while (true) {
    cin >> password;
    if (password.length() >= 8) break;
    cout << "Password too short! Try again: ";
}

4. The do-while Loop

The do-while loop is similar to the while loop, but it always executes the code block at least once before checking the condition.

Syntax:

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

Example:

#include <iostream>
using namespace std;

int main() {
    int i = 1;
    
    do {
        cout << i << " ";
        i++;
    } while (i <= 5);
    // Output: 1 2 3 4 5
    
    return 0;
}

Important Points:

  1. The condition is evaluated after each iteration, not before.
  2. The loop body always executes at least once, even if the condition is initially false.
  3. The semicolon after the closing parenthesis of the condition is mandatory.

Example with Initially False Condition:

int i = 10;

do {
    cout << "This will print once even though i > 5" << endl;
} while (i <= 5);

Common Use Cases:

  1. Input validation:
int number;
do {
    cout << "Enter a positive number: ";
    cin >> number;
} while (number <= 0);
  1. Menu-driven programs:
int choice;
do {
    cout << "\nMenu:\n";
    cout << "1. Option One\n";
    cout << "2. Option Two\n";
    cout << "3. Quit\n";
    cout << "Enter your choice: ";
    cin >> choice;
    
    switch (choice) {
        case 1: cout << "Processing Option One...\n"; break;
        case 2: cout << "Processing Option Two...\n"; break;
        case 3: cout << "Exiting...\n"; break;
        default: cout << "Invalid choice!\n";
    }
} while (choice != 3);

5. Nested Loops

Loops can be nested inside one another, allowing for more complex iteration patterns like processing multi-dimensional arrays or generating patterns.

Example - Multiplication Table:

#include <iostream>
using namespace std;

int main() {
    // Print a 5x5 multiplication table
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++) {
            cout << i * j << "\t";
        }
        cout << endl;
    }
    
    return 0;
}

Output:

1    2    3    4    5
2    4    6    8    10
3    6    9    12   15
4    8    12   16   20
5    10   15   20   25

Example - Pattern Printing:

#include <iostream>
using namespace std;

int main() {
    // Print a right-angled triangle pattern
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= i; j++) {
            cout << "* ";
        }
        cout << endl;
    }
    
    return 0;
}

Output:

* 
* * 
* * * 
* * * * 
* * * * * 

Important Points:

  1. Inner loops complete all their iterations for each single iteration of the outer loop.
  2. Each loop can use its own loop variable.
  3. Nesting can be done with any combination of for, while, and do-while loops.
  4. Deep nesting (more than 2-3 levels) can reduce readability and performance.

6. Loop Control Statements

C++ provides statements to control the flow of loops beyond their normal operation.

1. break Statement

The break statement immediately terminates the innermost loop it appears in, transferring control to the statement following the loop.

for (int i = 1; i <= 10; i++) {
    if (i == 6) {
        break;  // Exit loop when i reaches 6
    }
    cout << i << " ";
}
// Output: 1 2 3 4 5

2. continue Statement

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

for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue;  // Skip even numbers
    }
    cout << i << " ";
}
// Output: 1 3 5 7 9

While C++ supports the goto statement, it’s generally discouraged as it can lead to “spaghetti code” that’s difficult to follow and maintain.

int i = 1;

start:
    if (i <= 5) {
        cout << i << " ";
        i++;
        goto start;
    }
// Output: 1 2 3 4 5

7. Infinite Loops

An infinite loop is a loop that continues indefinitely because its termination condition is never met. While usually undesirable, they can be useful in certain situations when combined with a break statement.

Common Forms of Infinite Loops:

// Infinite for loop
for (;;) {
    // code
    if (exit_condition) break;
}

// Infinite while loop
while (true) {
    // code
    if (exit_condition) break;
}

// Infinite do-while loop
do {
    // code
    if (exit_condition) break;
} while (true);

Example - Processing Input Until Sentinel Value:

#include <iostream>
using namespace std;

int main() {
    int sum = 0, number;
    
    cout << "Enter numbers to sum (enter 0 to finish):" << endl;
    
    while (true) {
        cin >> number;
        if (number == 0) break;
        sum += number;
    }
    
    cout << "Sum = " << sum << endl;
    
    return 0;
}

Important Points:

  1. Always ensure there’s a way to exit an infinite loop (usually with a break statement).
  2. Infinite loops are often used in embedded systems, game loops, server applications, etc.
  3. Accidental infinite loops can cause your program to hang and potentially crash.

8. Loop Best Practices and Optimization

1. Choose the Right Loop

  • Use for when the number of iterations is known in advance
  • Use while when the loop might not execute at all
  • Use do-while when the loop must execute at least once
  • Use range-based for loops when iterating over containers (C++11 and later)

2. Avoid Expensive Operations in Loop Conditions

// Inefficient: vector.size() called in every iteration
for (int i = 0; i < vector.size(); i++) { ... }

// Better: Calculate size once
int size = vector.size();
for (int i = 0; i < size; i++) { ... }

3. Minimize Work Inside Loops

// Less efficient
for (int i = 0; i < n; i++) {
    result += pow(base, i);  // pow() is expensive
}

// More efficient
double power = 1;
for (int i = 0; i < n; i++) {
    result += power;
    power *= base;
}

4. Consider Loop Unrolling for Performance-Critical Code

// Normal loop
for (int i = 0; i < 1000; i++) {
    array[i] = 0;
}

// Unrolled loop
for (int i = 0; i < 1000; i += 4) {
    array[i] = 0;
    array[i+1] = 0;
    array[i+2] = 0;
    array[i+3] = 0;
}

5. Use Iterator-Based Loops with STL Containers

// Range-based for loop (C++11 and later)
for (const auto& item : container) {
    // Use item
}

// Iterator-based loop (any C++ version)
for (auto it = container.begin(); it != container.end(); ++it) {
    // Use *it
}

6. Be Careful with Floating-Point Comparisons in Loops

// Potentially problematic due to floating-point precision
for (double x = 0.0; x <= 1.0; x += 0.1) {
    cout << x << " ";
}

// Better approach
const int steps = 10;
for (int i = 0; i <= steps; i++) {
    double x = static_cast<double>(i) / steps;
    cout << x << " ";
}

9. Common Loop Patterns

1. Counting Loop

for (int i = 0; i < n; i++) {
    // Repeat n times
}

2. Accumulation/Reduction

int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum += i;  // Sum of numbers 1 to 100
}

3. Searching

bool found = false;
for (int i = 0; i < size; i++) {
    if (array[i] == target) {
        found = true;
        break;
    }
}

4. Filtering

vector<int> evenNumbers;
for (int i = 0; i < size; i++) {
    if (array[i] % 2 == 0) {
        evenNumbers.push_back(array[i]);
    }
}

5. Transformation

for (int i = 0; i < size; i++) {
    result[i] = transform(array[i]);
}

6. In-place Modification

for (int i = 0; i < size; i++) {
    array[i] = array[i] * 2;  // Double each element
}

10. for Loop vs while Loop vs do-while Loop

Comparison Table:

Featureforwhiledo-while
StructureCompact, all components in headerCondition in header, initialization and update separateSimilar to while, but condition at the end
Minimum iterations001
When to useKnown number of iterationsUnknown number of iterations, pre-test loopUnknown number of iterations, post-test loop
Variable scopeCan declare loop variables in header (limited scope)Variables must be declared before loopVariables must be declared before loop
Common applicationsIterating over arrays, countingReading input until condition metUser input validation, menu-driven systems

Example of each loop doing the same task:

// Using for loop
for (int i = 1; i <= 5; i++) {
    cout << i << " ";
}

// Using while loop
int i = 1;
while (i <= 5) {
    cout << i << " ";
    i++;
}

// Using do-while loop
int i = 1;
do {
    cout << i << " ";
    i++;
} while (i <= 5);

Loops are fundamental constructs in programming that enable the execution of repetitive tasks efficiently. Understanding when and how to use each type of loop is essential for writing clean, efficient, and effective code.