Control Flow

While Loops

Master C++ while and do-while loops — event-driven repetition, input validation loops, infinite loops, loop invariants, and choosing between loop types.

While Loops

A while loop repeats as long as its condition is true. Unlike a for loop where the number of iterations is usually known in advance, while loops are ideal when the exit condition depends on events, user input, or data that changes during execution.


Basic While Loop

cpp
#include <iostream>
using namespace std;

int main() {
    int count = 0;

    while (count < 5) {
        cout << count << " ";
        count++;    // Update must happen inside the body!
    }
    cout << "\n";
    // Output: 0 1 2 3 4

    // Countdown
    int n = 5;
    while (n > 0) {
        cout << n << "... ";
        n--;
    }
    cout << "Go!\n";
    // Output: 5... 4... 3... 2... 1... Go!

    return 0;
}

Warning: Always ensure the loop condition eventually becomes false. If you update the variable incorrectly (or forget to update it), you get an infinite loop that freezes your program.


While vs For: When to Choose

cpp
// Use 'for' when: you know the count before the loop starts
for (int i = 0; i < 10; i++) {
    // Exactly 10 iterations
}

// Use 'while' when: the count depends on what happens inside
int value;
cin >> value;
while (value != -1) {
    cout << "Processing: " << value << "\n";
    cin >> value;   // Read the next value
}

Input Validation Loop

The most common while use case — keep asking until the user gives valid input:

cpp
#include <iostream>
#include <limits>
using namespace std;

int getValidAge() {
    int age;
    cout << "Enter age (1-120): ";
    cin >> age;

    while (cin.fail() || age < 1 || age > 120) {
        cout << "Invalid age. Enter a number between 1 and 120: ";
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cin >> age;
    }
    return age;
}

string getValidGrade() {
    string grade;
    cout << "Enter grade (A, B, C, D, or F): ";
    cin >> grade;

    while (grade != "A" && grade != "B" && grade != "C" &&
           grade != "D" && grade != "F") {
        cout << "Invalid grade. Enter A, B, C, D, or F: ";
        cin >> grade;
    }
    return grade;
}

int main() {
    int    age   = getValidAge();
    string grade = getValidGrade();
    cout << "Age: " << age << ", Grade: " << grade << "\n";
    return 0;
}

Do-While Loop

A do-while loop executes the body at least once before checking the condition:

cpp
#include <iostream>
using namespace std;

int main() {
    int x = 10;

    // Condition is false from the start — but body runs once
    do {
        cout << "This always runs once: " << x << "\n";
        x++;
    } while (x < 5);

    cout << "\n";

    // Menu loop — display once, then ask to continue
    int choice;
    do {
        cout << "\n--- Menu ---\n";
        cout << "1. Option A\n";
        cout << "2. Option B\n";
        cout << "0. Exit\n";
        cout << "Choice: ";
        cin >> choice;

        switch (choice) {
            case 1: cout << "You chose A\n"; break;
            case 2: cout << "You chose B\n"; break;
            case 0: cout << "Goodbye!\n"; break;
            default: cout << "Invalid choice\n";
        }
    } while (choice != 0);

    return 0;
}
LoopCondition checkedMinimum iterations
whileBefore body0
do-whileAfter body1
forBefore body0

Infinite Loop

An intentional infinite loop with while (true) is common in servers, event loops, and embedded systems:

cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    // Command-line REPL (Read-Eval-Print Loop)
    string input;

    while (true) {
        cout << "> ";
        getline(cin, input);

        if (input == "quit" || input == "exit") {
            cout << "Bye!\n";
            break;
        } else if (input == "help") {
            cout << "Commands: help, quit, exit\n";
        } else if (!input.empty()) {
            cout << "You said: " << input << "\n";
        }
    }

    return 0;
}

Nested While Loops

cpp
#include <iostream>
using namespace std;

int main() {
    // Print a grid of numbers
    int row = 1;
    while (row <= 4) {
        int col = 1;
        while (col <= 4) {
            cout << row * col << "\t";
            col++;
        }
        cout << "\n";
        row++;
    }
    // Output:
    // 1  2  3  4
    // 2  4  6  8
    // 3  6  9  12
    // 4  8  12 16

    return 0;
}

Searching with While

cpp
#include <iostream>
#include <vector>
using namespace std;

// Linear search — return index or -1
int linearSearch(const vector<int>& v, int target) {
    int i = 0;
    while (i < (int)v.size()) {
        if (v[i] == target) return i;
        i++;
    }
    return -1;
}

// Binary search — requires sorted array
int binarySearch(const vector<int>& v, int target) {
    int low = 0, high = (int)v.size() - 1;

    while (low <= high) {
        int mid = low + (high - low) / 2;   // Avoids overflow vs (low+high)/2

        if (v[mid] == target) return mid;
        else if (v[mid] < target) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

int main() {
    vector<int> sorted = {2, 5, 8, 12, 16, 23, 38, 45, 67, 90};

    cout << linearSearch(sorted, 23) << "\n";   // 5
    cout << binarySearch(sorted, 23) << "\n";   // 5
    cout << binarySearch(sorted, 99) << "\n";   // -1

    return 0;
}

Loop Invariants

A loop invariant is a condition that holds true at the start of every iteration — it helps you reason about correctness:

cpp
#include <iostream>
using namespace std;

int main() {
    // Sum all elements — invariant: sum == sum of v[0..i-1]
    vector<int> v = {1, 2, 3, 4, 5};
    int sum = 0;
    int i = 0;

    while (i < (int)v.size()) {
        // Invariant holds here: sum == sum of v[0..i-1]
        sum += v[i];
        i++;
        // Invariant still holds: sum == sum of v[0..i-1]
    }
    cout << "Sum: " << sum << "\n";  // 15

    return 0;
}

Practical Example: Number Guessing Game

cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

int main() {
    srand(static_cast<unsigned>(time(nullptr)));
    int secret = rand() % 100 + 1;  // Random 1-100

    int guess     = 0;
    int attempts  = 0;
    const int MAX = 10;

    cout << "=== Number Guessing Game ===\n";
    cout << "Guess the number between 1 and 100 (max " << MAX << " tries).\n\n";

    while (attempts < MAX && guess != secret) {
        cout << "Attempt " << (attempts + 1) << "/" << MAX << ": ";

        while (!(cin >> guess) || guess < 1 || guess > 100) {
            cout << "Enter a number between 1 and 100: ";
            cin.clear();
            cin.ignore(1000, '\n');
        }

        attempts++;

        if (guess < secret) {
            int diff = secret - guess;
            cout << (diff > 20 ? "Much too low!" : "A bit low.") << "\n";
        } else if (guess > secret) {
            int diff = guess - secret;
            cout << (diff > 20 ? "Much too high!" : "A bit high.") << "\n";
        } else {
            cout << "\n🎉 Correct! You got it in " << attempts << " attempt"
                 << (attempts == 1 ? "" : "s") << "!\n";

            string rating = (attempts <= 3) ? "Excellent!" :
                            (attempts <= 6) ? "Good!"      : "Lucky!";
            cout << rating << "\n";
        }
    }

    if (guess != secret) {
        cout << "\nOut of attempts. The number was " << secret << ".\n";
    }

    return 0;
}

Summary

  • while (condition) — checks condition first; body may execute zero times
  • do { } while (condition) — body always executes at least once; check comes after
  • while (true) with break — intentional infinite loop for event loops, REPLs, and servers
  • Always update the loop variable inside the body — failure to do so causes an infinite loop
  • while is best when the number of iterations is not known before the loop starts
  • Use while with cin >> x for input validation loops; use cin.clear() + cin.ignore() to recover from bad input
  • break exits the loop; continue skips to the next iteration — both work the same as in for

Next, we'll learn about functions — the building blocks of structured, reusable C++ programs.