C++ Tutorial
C++ Nested Loops
A loop inside a loop walks rows and columns: tables, grids, and multiplication.
A loop inside a loop
Nested loops means the body of one loop contains another loop. The outer loop runs once per row. For each of those passes, the inner loop runs all the way through. If the outer loop has 3 passes and the inner loop has 4, the inner body runs 12 times.
That product is the point. One loop walks a line. Two loops walk a rectangle: seats in a theater, cells in a spreadsheet, pairs of numbers. Keep the counters on different names. This tutorial uses row andcol, or i and j.
Print every cell of a grid
This program does not store a table. It only prints coordinates. The outer loop picks the row. The inner loop prints every column on that row, then endl starts the next line. Read the output as a 3 by 4 grid.
Example
#include <iostream>
using namespace std;
int main() {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 4; col++) {
cout << "(" << row << "," << col << ") ";
}
cout << endl;
}
return 0;
}Run this in /cpp/try. Change 3 or 4 and watch the rectangle grow. The inner loop restarts from col = 0 on every new row.
A multiplication table
Each cell is the product of its row number and its column number. The outer loop is the left factor. The inner loop is the right factor. A newline after the inner loop finishes one row of the table.
Example
#include <iostream>
using namespace std;
int main() {
for (int row = 1; row <= 5; row++) {
for (int col = 1; col <= 5; col++) {
cout << (row * col) << "\t";
}
cout << endl;
}
return 0;
}The loops count from 1 this time because people read a times table that way. Array indexes still start at 0; this chapter is about nested repetition, not storage. \t is a tab so the columns line up.
Read the counters the same way every time
| Name | Job |
|---|---|
| Outer counter | Picks the row. Changes slowly. |
| Inner counter | Picks the column. Resets on every outer pass. |
| Inner body | Runs once per cell. |
Declare each counter in its own for header. Then row is not visible after the outer loop, and col is not visible after the inner loop. Reusing one name for both loops is a common source of off-by-one bugs.
Nested loops over a list
You can nest without a rectangle of numbers. This program prints every pair of names from a small vector. The outer index is the first person. The inner index starts at i + 1 so each pair appears once, and a name is never paired with itself.
Example
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> names = {"Ada", "Ben", "Cara"};
for (size_t i = 0; i < names.size(); i++) {
for (size_t j = i + 1; j < names.size(); j++) {
cout << names[i] << " / " << names[j] << endl;
}
}
return 0;
}size_t is an unsigned type used for sizes and indexes. Matching it to names.size()keeps the comparison clean. Three names produce three pairs: Ada/Ben, Ada/Cara, Ben/Cara.
break leaves only the inner loop
break ends the loop it sits in. Inside the inner loop, it stops that row and the outer loop continues with the next row. It does not jump out of both loops. If you need to stop the whole nest, set abool flag and test it in the outer condition, or return from a function.
A nested loop with a large inner count is still a product. Ten thousand times ten thousand is a hundred million inner-body runs. Keep the bounds small while you learn, and know why the inner work repeats.
From printing a grid to storing one
Nested loops print a table. They also fill one and read one. The next chapter stores the cells in a 2D array and walks them with the same outer-row, inner-column shape you used here.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C++ editor at /cpp/try. Change one measurement and check whether the result still has the right unit.
Maths
A multiplication grid
Times tables are a Cartesian product: every r with every c. The inner loop finishes a row. The outer loop starts the next.
Example
#include <iostream>
using namespace std;
int main() {
for (int r = 1; r <= 4; r++) {
for (int c = 1; c <= 4; c++) {
cout << r * c << "\t";
}
cout << endl;
}
return 0;
}Chemistry
Every mix in a small design
Two acid concentrations and three temperatures give six experiments. Nested loops walk every pair. That is a factorial design with two factors, not a reaction mechanism.
Example
#include <iostream>
using namespace std;
int main() {
for (int acid = 1; acid <= 2; acid++) {
for (int temp = 20; temp <= 40; temp += 10) {
cout << "acid " << acid << " @ " << temp << " C" << endl;
}
}
return 0;
}