To demonstrate the behavior of nested for-loops and how to coordinate them to form a solution, we set ourselves the problem of writing a program to print a 12 × 12 multiplication table.
Problem | Algorithm / Pseudo Code |
---|---|
j=1 j=2 j=3 ... j=12 i=1 d d d ... d ↵ i=2 dd dd dd ... dd ↵ . . . . . ↵ . . . . . ↵ . . . . . ↵ i=12 ddd ddd ddd ... ddd ↵ |
for i = 1, 2, ..., 12 // (a) for j = 1, 2, ..., 12 // (b) print i x j // (c) next j (j = j + 1) // (d) print new line // (e) next i (i = i + 1) // (f) reset j (j = 1) // (g) |
(a) | (b) |
The algorithm correctly calculates and logically places the multiplication values but does not separate them, forming a single, long sequence of digits for each row. Modifying the nested print statement to put spaces between the numbers fails to make an aesthetically pleasing and readable table. Part (a) above suggests the problem: the lengths of the numbers in the table vary from one to three digits. So, the number of spaces needed to separate two numbers depends on their lengths. Programmers sometimes print horizontal tab characters to create columns, but tabs have two problems. If the lengths of the individual data items vary too much, then the number of tabs separating them also varies, which is challenging to calculate. Furthermore, tabs always align the numbers on the left side, but aligning on the right is desirable - as if we were manually performing column addition.
Code | Output |
---|---|
cout << '|' << setw(3) << 1 << '|' << endl; cout << '|' << setw(3) << 12 << '|' << endl; cout << '|' << setw(3) << 123 << '|' << endl; cout << '|' << setw(3) << 1234 << '|' << endl; |
| 1| | 12| |123| |1234| |
(a) | (b) |
#include <iostream>
, but manipulators with arguments, like setw, require a separate directive: #include <iomanip>
. Please see setw later in the chapter for more detail.
Program | Output |
---|---|
#include <iostream> #include <iomanip> using namespace std; int main() { for (int i = 1; i <= 12; i++) // (a and f) { for (int j = 1; j <= 12; j++) // (b, d, and g) cout << setw(5) << i * j; // (c) cout << endl; // (e) } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 6 9 12 15 18 21 24 27 30 33 36 4 8 12 16 20 24 28 32 36 40 44 48 5 10 15 20 25 30 35 40 45 50 55 60 6 12 18 24 30 36 42 48 54 60 66 72 7 14 21 28 35 42 49 56 63 70 77 84 8 16 24 32 40 48 56 64 72 80 88 96 9 18 27 36 45 54 63 72 81 90 99 108 10 20 30 40 50 60 70 80 90 100 110 120 11 22 33 44 55 66 77 88 99 110 121 132 12 24 36 48 60 72 84 96 108 120 132 144 |