We can store any type of object we like in an array. We've seen
ints, doubles, strings,
etc. already. We could choose something more exotic, like
ofstreams, even! For example, imagine a situation
where we'd like a program that reads a list of file names from the
user, creates those files, and then takes a sentence he types and
writes it to each of those files. Can we do this? Well, let's
try the following strategy:
// Get number of files, call it N
int N;
cout << "Enter number of files: ";
cin >> N;
// Create an array of N ofstreams
ofstream *FILE = new ofstream[N];
Now we have a problem, FILE points to M
objects of type ofstream, but how do we tell each
ofstream object what file they should point to?
I mean usually we tell the object what file it should point to at
the same time it is created, as in:
ofstream OUT("temp.txt");
When we create arrays of objects using new, those
objects are uninitialized, so we have to go through and initialize
each one individually. In this case, that means opening a file
for each ofstream object. To do this, we need to use
.open() to attach a stream to a file. For example,
we can create OUT as above in this way:
ofstream OUT;
OUT.open("temp.txt");
In the case of our array, we can read in names and initialize this
way:
cout << "Please enter " << N << " filenames: ";
for( int j = 0; j < N; j++ ) {
string s;
cin >> s;
FILE[j].open(s.c_str());
}
Having done this, we can write whatever we want to all the files,
like this:
for(int k = 0; k < N; k++)
FILE[k] << "Hello file number " << k << "!!!" << endl;
You can take a look at this complete program
that writes a sentence to a whole list of files.
ints, of course! So, each object in my array of
students is itself an array of ints, i.e. each
object is an int*. Remember, we create an array of
10 objects of type T like this:
T* array = new T[10]
So, if the type of object that gets stored in the array is
int*, we create our array like this:
int** array = new int*[10];
Now, having done that, we have an array full of uninitialized
pointers, in otherwords we have an array of pointers that don't
yet point to anything! Thus, for each of these 10 pointers we
must allocate an array for them to point to! Remember,
array[i] is an object of type
int*. So wherever you see
array[i] just think of it as being a normal old
pointer:
int** array = new int*[10];
for(int i = 0; i < 10; i++)
array[i] = new int[10];
What gets created and how you index elements in it are depicted
in this diagram:

This is how you can create "multi-dimensional" arrays in C++. You just have arrays of arrays! Okay, now let's read the grade information and store it in our 2-dimensional array:
ifstream IN("grades.txt");
for(int s = 0; s < 10; s++)
for(int g = 0; g < 10; g++)
IN >> array[s][g];
With this, I can get the grade for student stu
on homework assignment hwa as
array[stu][hwa]. This
program is a simple one that reads the grade info and allows
the user to ask questions about grades.
This version makes nice use of functions,
and gives you an idea of how we pass multi-dimensional arrays
around for this sort of thing.
Here are three extensions
of the functionality of this program you might like to consider:
new
live on until the end of your program, or until deleted with the
delete [] command. With mutli-dimensional arrays,
you have to remember to delete each array you created. That
means, if we refer back to the grades problem from above, that all
of the arrays pointed to by the elements of the array
grade must be deleted before we can delete the array
grade itself.
for(int k = 0; k < 10; k++)
delete [] grade[k];
delete [] grade;
~/$ ./ex1 There are 24 people. How many teams would you like? (make it evenly divide n) 3 Team 0: Mike Dan Chris Joni Christy Seung-Geol Cathy Susan Team 1: Gavin Nate Paul Adina Jeff Carl Karen Eric Team 2: Phong Betty Madeline Marianne Don Shirley Tim Steve