Managing Arrays and Strings 417
LISTING 13.4 continued
19: int main()
20: {
21: Cat Litter[5];
22: int i;
23: for (i = 0; i < 5; i++)
24: Litter[i].SetAge(2*i +1);
25:
26: for (i = 0; i < 5; i++)
27: {
28: cout << “Cat #” << i+1<< “: “;
29: cout << Litter[i].GetAge() << endl;
30: }
31: return 0;
32: }
cat #1: 1
OUTPUT cat #2: 3
cat #3: 5
cat #4: 7
cat #5: 9
ANALYSIS Lines 5–17 declare the Cat class. The Cat class must have a default constructor
so that Cat objects can be created in an array. In this case, the default constructor
is declared and defined on line 8. For each Cat, a default age of 1 is set as well as a
default weight of 5. Remember that if you create any other constructor, the compiler-
supplied default constructor is not created; you must create your own.
The first for loop (lines 23 and 24) sets values for the age of each of the five Cat objects
in the array. The second for loop (lines 26–30) accesses each member of the array and
calls GetAge() to display the age of each Cat object.
Each individual Cat’s GetAge() method is called by accessing the member in the array,
Litter, followed by the dot operator (.), and the member function. You can access other
members and methods in the exact same way. 13
Declaring Multidimensional Arrays
It is possible to have arrays of more than one dimension. Each dimension is represented
as a subscript in the array. Therefore, a two-dimensional array has two subscripts; a
three-dimensional array has three subscripts; and so on. Arrays can have any number of
dimensions, although it is likely that most of the arrays you create will be of one or two
dimensions.
418 Day 13
A good example of a two-dimensional array is a chess board. One dimension represents
the eight rows; the other dimension represents the eight columns. Figure 13.3 illustrates
this idea.
FIGURE 13.3 1 2 3 4 5 6 7 8
2
A chess board and a 3
two-dimensional array. 4
5
6
7
8
7
6
5
4
3
2
1
0 0
7
6
5
4
3
2
1
1 0
7
6
5
4
3
2
1
2 0
7
6
5
4
3
2
1
7 0
Suppose that you have a class named SQUARE. The declaration of an array named Board
that represents it would be
SQUARE Board[8][8];
You could also represent the same data with a one-dimensional, 64-square array. For
example:
SQUARE Board[64];
Managing Arrays and Strings 419
This, however, doesn’t correspond as closely to the real-world object as the two-dimen-
sion. When the game begins, the king is located in the fourth position in the first row;
that position corresponds to
Board[0][3];
assuming that the first subscript corresponds to row and the second to column.
Initializing Multidimensional Arrays
You can initialize multidimensional arrays. You assign the list of values to array elements
in order, with the last array subscript (the one farthest to the right) changing while each
of the former holds steady. Therefore, if you have an array
int theArray[5][3];
the first three elements go into theArray[0]; the next three into theArray[1]; and so
forth.
You initialize this array by writing
int theArray[5][3] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
For the sake of clarity, you could group the initializations with braces. For example:
int theArray[5][3] = { {1,2,3},
{4,5,6},
{7,8,9},
{10,11,12},
{13,14,15} };
The compiler ignores the inner braces, but they do make it easier to understand how the
numbers are distributed.
When initializing elements of an array, each value must be separated by a comma, with-
out regard to the braces. The entire initialization set must be within braces, and it must
end with a semicolon.
Listing 13.5 creates a two-dimensional array. The first dimension is the set of numbers
13
from zero to four. The second dimension consists of the double of each value in the first
dimension.
LISTING 13.5 Creating a Multidimensional Array
0: // Listing 13.5 - Creating a Multidimensional Array
1: #include <iostream>
2: using namespace std;
3:
4: int main()
420 Day 13
LISTING 13.5 continued
5: {
6: int SomeArray[2][5] = { {0,1,2,3,4}, {0,2,4,6,8}};
7: for (int i = 0; i<2; i++)
8: {
9: for (int j=0; j<5; j++)
10: {
11: cout << “SomeArray[“ << i << “][“ << j << “]: “;
12: cout << SomeArray[i][j]<< endl;
13: }
14: }
15: return 0;
16: }
SomeArray[0][0]: 0
OUTPUT SomeArray[0][1]: 1
SomeArray[0][2]: 2
SomeArray[0][3]: 3
SomeArray[0][4]: 4
SomeArray[1][0]: 0
SomeArray[1][1]: 2
SomeArray[1][2]: 4
SomeArray[1][3]: 6
SomeArray[1][4]: 8
Line 6 declares SomeArray to be a two-dimensional array. The first dimension
ANALYSIS
indicates that there will be two sets; the second dimension consists of five inte-
gers. This creates a 2×5 grid, as Figure 13.4 shows.
FIGURE 13.4
A 2×5 array.
4 4
3 3
2 2
1 1
0 0
Some Array [5] [2]
The values are based on the two sets of numbers. The first set is the original numbers;
the second set is the doubled numbers. In this listing, the values are simply set, although
they could be computed as well. Lines 7 and 9 create a nested for loop. The outer for
loop (starting on line 7) ticks through each member of the first dimension, which is each
of the two sets of integers. For every member in that dimension, the inner for loop (start-
ing on line 9) ticks through each member of the second dimension. This is consistent
with the printout. SomeArray[0][0] is followed by SomeArray[0][1]. The first
Managing Arrays and Strings 421
dimension is incremented only after the second dimension has gone through all of its
increments. Then counting for the second dimension starts over.
A Word About Memory
When you declare an array, you tell the compiler exactly how many objects you expect to
store in it. The compiler sets aside memory for all the objects, even if you never use it.
This isn’t a problem with arrays for which you have a good idea of how many objects
you’ll need. For example, a chessboard has 64 squares, and cats have between 1 and 10
kittens. When you have no idea of how many objects you’ll need, however, you must use
more advanced data structures.
This book looks at arrays of pointers, arrays built on the free store, and various other col-
lections. You’ll see a few advanced data structures, but you can learn more in the book
C++ Unleashed from Sams Publishing. You can also check out Appendix E, “A Look at
Linked Lists.”
Two of the great things about programming are that there are always more things to
learn and that there are always more books from which to learn them.
Building Arrays of Pointers
The arrays discussed so far store all their members on the stack. Usually, stack memory
is more limited, whereas free store memory is much larger. It is possible to declare each
object on the free store and then to store only a pointer to the object in the array. This
dramatically reduces the amount of stack memory used. Listing 13.6 rewrites the array
from Listing 13.4, but it stores all the objects on the free store. As an indication of the
greater memory that this enables, the array is expanded from 5 to 500, and the name is
changed from Litter to Family.
LISTING 13.6 Storing an Array on the Free Store
0: // Listing 13.6 - An array of pointers to objects 13
1:
2: #include <iostream>
3: using namespace std;
4:
5: class Cat
6: {
7: public:
8: Cat() { itsAge = 1; itsWeight=5; }
9: ~Cat() {} // destructor
10: int GetAge() const { return itsAge; }
11: int GetWeight() const { return itsWeight; }
12: void SetAge(int age) { itsAge = age; }