C++ Fundamentals IV: Loops, For, While, Do-While & Nested Loops

3
1

C++ Fundamentals IV

This part of C++ fundamentals is about repetition. In programming, repetition appears whenever the same work has to be done again and again. Instead of copy-pasting the same statement many times, C++ gives looping structures that repeat a block of code in a controlled way.

Suppose the task is to print Hello five times. A direct approach is:

#include <iostream>
using namespace std;
int main() {
cout << "Hello\n";
cout << "Hello\n";
cout << "Hello\n";
cout << "Hello\n";
cout << "Hello\n";
return 0;
}

This works for five lines, but it is not scalable. If the task changes to printing Hello one million times, copy-pasting is not readable, convenient, or acceptable. A loop represents controlled repetition and solves this problem cleanly.

The while Loop

A while loop repeats a block of code while a condition remains true.

Before writing a loop, ask four questions:

  • What is repeating?

  • How many times, or until what condition, should it repeat?

  • What changes after each repetition?

  • What will eventually make the loop stop?

For printing Hello five times, the repeating work is the print statement. The repetition should happen five times. A variable can be used to track the current repetition count.

#include <iostream>
using namespace std;
int main() {
int i = 1;
while (i <= 5) {
cout << "Hello\n";
i = i + 1;
}
return 0;
}

Dry Run of the While Loop

Initially, i = 1.

  • i <= 5 is true, so Hello is printed. Then i becomes 2.

  • 2 <= 5 is true, so Hello is printed. Then i becomes 3.

  • 3 <= 5 is true, so Hello is printed. Then i becomes 4.

  • 4 <= 5 is true, so Hello is printed. Then i becomes 5.

  • 5 <= 5 is true, so Hello is printed. Then i becomes 6.

  • 6 <= 5 is false, so the loop stops.

After the loop finishes, i has the value 6. This is the first value for which the loop condition became false.

Changing the Number of Repetitions

To print Hello ten times, only the condition needs to change:

int i = 1;
while (i <= 10) {
cout << "Hello\n";
i = i + 1;
}

To print it one million times, the same structure still works:

int i = 1;
while (i <= 1000000) {
cout << "Hello\n";
i = i + 1;
}

Infinite Loop

An infinite loop happens when the loop condition never becomes false.

int i = 1;
while (i <= 5) {
cout << "Hello\n";
}

Here, i is never changed. It remains 1 forever, so i <= 5 is always true. The loop keeps printing endlessly until the environment stops the program, often with a time limit exceeded or memory/output limit issue.

For a loop to be safe, something inside it must move the program toward termination.

The for Loop

A for loop is useful when initialization, condition, and progress form one clear counting pattern.

#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 5; i++) {
cout << "Hello\n";
}
return 0;
}

The three parts inside the parentheses are:

  • int i = 1: initialization, executed only once.

  • i <= 5: condition, checked before every iteration.

  • i++: update, executed after each iteration.

Execution Flow of a For Loop

The initialization happens once. Then the condition is checked. If true, the body executes. After the body, the update runs. Then control returns to the condition again.

for (int i = 1; i <= 5; i++) {
cout << "Hello\n";
}

The loop behaves like this:

  • Start with i = 1.

  • Check i <= 5.

  • If true, print Hello.

  • Run i++.

  • Repeat the condition check.

When i becomes 6, the condition fails and the loop ends.

i++ and ++i in a For Loop

In this kind of loop, both i++ and ++i usually behave the same for the loop’s counting purpose.

for (int i = 1; i <= 5; i++) {
cout << "Hello\n";
}
for (int i = 1; i <= 5; ++i) {
cout << "Hello\n";
}

In both cases, i is incremented after the body runs and before the next condition check.

Scope of the Loop Variable

If i is declared inside the for loop, it is accessible only inside that loop.

for (int i = 1; i <= 5; i++) {
cout << "Hello\n";
}
cout << i; // invalid: i is not accessible here

If i must be accessed after the loop, declare it before the loop.

int i;
for (i = 1; i <= 5; i++) {
cout << "Hello\n";
}
cout << i; // valid, prints 6

Empty Parts in a For Loop

The initialization can be done before the loop, leaving the first part empty.

int i = 1;
for (; i <= 5; i++) {
cout << "Hello\n";
}

The update can also be moved inside the body, though this should be done carefully.

int i = 1;
for (; i <= 5;) {
cout << "Hello\n";
i++;
}

This works, but the normal for loop form is usually cleaner when the loop is a straightforward counting loop.

The do while Loop

A do while loop runs the body first and checks the condition afterward. This guarantees at least one execution.

do {
// body
} while (condition);

The semicolon after the while condition is required.

Difference from While and For

In a while loop, the condition is checked before the body runs.

int i = 6;
while (i <= 5) {
cout << "Hello\n";
i++;
}

This body never runs because 6 <= 5 is false from the beginning.

In a for loop, the condition is also checked before the body runs.

for (int i = 6; i <= 5; i++) {
cout << "Hello\n";
}

This also never runs as i is initialized with 6.

But a do while loop runs once before checking.

int i = 6;
do {
cout << "Hello\n";
i++;
} while (i <= 5);

This prints Hello once, then checks the condition and stops.

Problem: Repeat Until Zero

Keep taking integers as input and stop only when the user enters 0.

Using While

#include <iostream>
using namespace std;
int main() {
int num;
cout << "Enter number: ";
cin >> num;
while (num != 0) {
cout << "Number entered by you is " << num << "\n";
cout << "Enter number: ";
cin >> num;
}
return 0;
}

This works, but the input logic appears once before the loop and again inside the loop.

Using Do While

#include <iostream>
using namespace std;
int main() {
int num;
do {
cout << "Enter number: ";
cin >> num;
if (num != 0) {
cout << "Number entered by you is " << num << "\n";
}
} while (num != 0);
return 0;
}

This structure fits naturally because at least one input must be taken before deciding whether to repeat.

The variable num must be declared before the do block. If it is declared inside the block, the while (num != 0) condition outside the block cannot access it.

Choosing the Right Loop

  • Use a for loop when the initialization, condition, and update form a clear counting story, such as printing from 1 to n.

  • Use a while loop when repetition depends on a condition that changes during processing, such as extracting digits until the number becomes 0.

  • Use a do while loop when the work must happen at least once before the condition is checked.

Loop Practice Problems

Print Numbers from 1 to n

Given an integer n, print all numbers from 1 to n.

#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cout << i << "\n";
}
return 0;
}
/*
If n = 7, the output is:
1
2
3
4
5
6
7
*/

Count Down from n to 1

Given an integer n, print all numbers from n down to 1.

#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = n; i >= 1; i--) {
cout << i << "\n";
}
return 0;
}
/*
If n = 7, the output is:
7
6
5
4
3
2
1
*/

Sum from 1 to n

Given an integer n, find the sum of all numbers from 1 to n.

For n = 5: 1 + 2 + 3 + 4 + 5 = 15

The formula is: n * (n + 1) / 2

But to understand loops, we can compute it programmatically using an accumulator.

#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++) {
sum = sum + i;
}
cout << sum;
return 0;
}

If n = 7, the output is: 28

Counter and Accumulator

A counter records how many times something happens.

int count = 0;
for (int i = 1; i <= n; i++) {
count = count + 1;
}

Every time the loop body runs, count increases by 1. At the end, count tells how many iterations occurred.

An accumulator collects a running result, such as a sum.

int sum = 0;
for (int i = 1; i <= n; i++) {
sum = sum + i;
}

Here, each value of i is added into sum.

Multiplication Table

Given an integer n, print its multiplication table from 1 to 10.

If n = 5, the output values are:

5
10
15
20
25
30
35
40
45
50

The changing part is the multiplier: 1, 2, 3, and so on up to 10.

#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= 10; i++) {
cout << n * i << "\n";
}
return 0;
}

Off-by-One Errors

An off-by-one error happens when a loop runs one time too many or one time too few.

To run a loop exactly five times, there are multiple valid ways:

for (int i = 1; i <= 5; i++) {
// runs for i = 1, 2, 3, 4, 5
}
for (int i = 0; i < 5; i++) {
// runs for i = 0, 1, 2, 3, 4
}
for (int i = 5; i <= 9; i++) {
// runs for i = 5, 6, 7, 8, 9
}

All three loops run five times. The correct form depends on the problem requirement. If the problem asks to include n, use a condition such as i <= n. If it asks for values before n, use a condition such as i < n.

Nested Loops

A nested loop is a loop inside another loop. It is useful when the work itself contains repetition. Patterns are a common example.

Pattern Problem

Print this pattern:

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

There are three rows, and every row has four asterisks.

First, print one row:

for (int j = 1; j <= 4; j++) {
cout << "*";
}
cout << "\n";

This prints one line containing four stars. Since the same row logic must repeat three times, place it inside another loop.

#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 4; j++) {
cout << "*";
}
cout << "\n";
}
return 0;
}

How the Nested Loop Runs

The outer loop controls the rows. The inner loop controls the columns inside each row.

  • For row 1, the inner loop prints four stars, then a newline is printed.

  • For row 2, the inner loop starts fresh from j = 1, prints four stars, then a newline is printed.

  • For row 3, the same thing happens again.

The outer loop runs 3 times. The inner loop runs 4 times for each outer iteration. So the inner body runs 3 * 4 = 12 times, producing twelve stars.

Common Nested Loop Mistakes

  • Printing the newline inside the inner loop when the row is not finished.

  • Using the same loop variable for both outer and inner loops.

  • Moving the inner loop variable initialization outside when it should restart for every row.

Use different variables such as i for rows and j for columns.

break and continue

break

break exits the nearest loop immediately.

#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
cout << i << "\n";
}
return 0;
}
/*
Output:
1
2
3
4
*/

When i becomes 5, break runs and the loop ends. Control moves to the first statement after the loop.

In nested loops, break exits only the nearest loop.

for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 4; j++) {
if (j == 3) {
break;
}
cout << "*";
}
cout << "\n";
}

The break affects the inner loop only. The outer loop continues to the next row.

continue

continue skips the remaining body of the current iteration and moves to the next iteration.

#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue;
}
cout << i << "\n";
}
return 0;
}
/*
Output:
1
2
3
4
6
7
8
9
10
*/

For i = 5, continue skips the print statement. The loop itself does not end.

If more than one value is skipped:

for (int i = 1; i <= 10; i++) {
if (i == 5 || i == 7) {
continue;
}
cout << i << "\n";
}

The output skips both 5 and 7.

Be Careful with Continue in While Loops

In a while loop, the update statement is often written manually inside the body. If continue skips the update, the loop may become infinite.

int i = 1;
while (i < 5) {
if (i == 2) {
continue;
}
i = i + 1;
}

When i becomes 2, continue runs before i = i + 1. So i stays 2 forever, and the loop never ends.

One safe version is to update before continuing:

int i = 1;
while (i < 5) {
if (i == 2) {
i = i + 1;
continue;
}
i = i + 1;
}

Problem: Sum of Digits

Given a non-negative integer, print the sum of its decimal digits.

Examples:

  • 507 gives 5 + 0 + 7 = 12.

  • 1234 gives 1 + 2 + 3 + 4 = 10.

Extracting the Last Digit

The last digit of a number can be extracted using modulo 10.

507 % 10 = 7
1234 % 10 = 4

This works because division by 10 leaves the last digit as the remainder.

Removing the Last Digit

Integer division by 10 removes the last digit.

507 / 10 = 50
50 / 10 = 5
5 / 10 = 0

So the repeated process is:

  • Extract the last digit using num % 10.

  • Add that digit to the sum.

  • Remove the last digit using num / 10.

  • Repeat until the number becomes 0.

Pseudocode

sum = 0
while num > 0:
digit = num % 10
sum = sum + digit
num = num / 10
print sum

C++ Code

#include <iostream>
using namespace std;
int main() {
int num;
cin >> num;
int sum = 0;
while (num > 0) {
int digit = num % 10;
sum = sum + digit;
num = num / 10;
}
cout << sum;
return 0;
}

Dry Run for 621

Initially:

num = 621
sum = 0

Step 1:

digit = 621 % 10 = 1
sum = 0 + 1 = 1
num = 621 / 10 = 62

Step 2:

digit = 62 % 10 = 2
sum = 1 + 2 = 3
num = 62 / 10 = 6

Step 3:

digit = 6 % 10 = 6
sum = 3 + 6 = 9
num = 6 / 10 = 0

Now num is 0, so the loop stops and the answer is 9.

Problem: Reverse a Number

Given a non-negative integer, print its reverse.

Examples:

  • 482 becomes 284.

  • 9001 becomes 1009.

Stitching a Digit to a Number

To stitch digit 9 after number 8, first make space by multiplying by 10:

8 * 10 + 9 = 89

To stitch digit 7 after number 124:

124 * 10 + 7 = 1247

In general, to append a single digit:

newNumber = oldNumber * 10 + digit

If the value being appended has more than one digit, multiplying by 10 is not enough. For example, to stitch 35 after 123:

123 * 100 + 35 = 12335

For reversing digits, however, each extracted value is a single digit, so multiplying by 10 is exactly what is needed.

Algorithm

Extract digits from the back and stitch them into a new number.

reverse = 0
while num > 0:
digit = num % 10
reverse = reverse * 10 + digit
num = num / 10
print reverse

C++ Code

#include <iostream>
using namespace std;
int main() {
int num;
cin >> num;
int reverse = 0;
while (num > 0) {
int digit = num % 10;
reverse = reverse * 10 + digit;
num = num / 10;
}
cout << reverse;
return 0;
}

Dry Run for 482

Initially:

num = 482
reverse = 0

Step 1:

digit = 482 % 10 = 2
reverse = 0 * 10 + 2 = 2
num = 482 / 10 = 48

Step 2:

digit = 48 % 10 = 8
reverse = 2 * 10 + 8 = 28
num = 48 / 10 = 4

Step 3:

digit = 4 % 10 = 4
reverse = 28 * 10 + 4 = 284
num = 4 / 10 = 0

Now num is 0, so the loop stops and 284 is printed.

Problem: Fibonacci Number

The Fibonacci sequence starts as: 0, 1, 1, 2, 3, 5, 8, 13, ...

The 0th Fibonacci number is 0. The 1st Fibonacci number is 1. Every later Fibonacci number is the sum of the previous two.

F(0) = 0
F(1) = 1
F(n) = F(n - 1) + F(n - 2)

Examples:

  • F(2) = F(1) + F(0) = 1 + 0 = 1.

  • F(3) = F(2) + F(1) = 1 + 1 = 2.

  • F(5) = 5.

  • F(7) = 13.

Iterative Idea

To calculate the next Fibonacci number, we only need the previous two numbers in the sequence. We start with last2 = 0 and last = 1, where last2 stores the second-last Fibonacci number and last stores the last Fibonacci number. We calculate the next number by adding these two values using current = last + last2.

After calculating current, we update the variables to move forward in the sequence. First, we assign last to last2, making the previous last number the new second-last number. Then, we assign current to last, making the newly calculated number the latest Fibonacci number. This process repeats to generate the next Fibonacci numbers without storing the entire sequence.

C++ Code

#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n == 0 || n == 1) {
cout << n;
return 0;
}
int last2 = 0;
int last = 1;
for (int i = 2; i <= n; i++) {
int current = last + last2;
last2 = last;
last = current;
}
cout << last;
return 0;
}

Dry Run for n = 5

Initially:

last2 = 0
last = 1

For i = 2:

current = 1 + 0 = 1
last2 = 1
last = 1

For i = 3:

current = 1 + 1 = 2
last2 = 1
last = 2

For i = 4:

current = 2 + 1 = 3
last2 = 2
last = 3

For i = 5:

current = 3 + 2 = 5
last2 = 3
last = 5

The answer is 5.

Key Takeaways

  • Loops are used for controlled repetition.

  • A while loop is useful when repetition depends on a changing condition.

  • A for loop is useful when the counting pattern is clear.

  • A do while loop runs at least once before checking the condition.

  • Every loop needs progress toward termination.

  • Off-by-one errors come from choosing the wrong start, end, or comparison condition.

  • Nested loops are useful when repeated work itself contains repetition.

  • break exits the nearest loop.

  • continue skips the rest of the current iteration.

  • Digit problems often use % 10 to extract the last digit and / 10 to remove it.

  • Problem-solving logic is language-independent; C++ only provides the syntax to express it.

C++

Read Similar Blogs

Comments0