Elephant Parade, Part 1: A Bad Idea
Let's write a program!
Hooray!! I love writing programs!
In our program, we'll have the user enter a bunch of elephant names.
Then the program will make the elephants parade in alphabetical order.
Here's an example of the interaction we'd like our program to offer:
$ ./elephant-parade
Please enter elephant 1
Name: Peanut
Age: 2
Another elephant (y/n)? y
Please enter elephant 2
Name: Manny
Age: 4000
Another elephant (y/n)? n
The elephants are parading!
Manny (4000)
Peanut (2)
$
From this example we can design our interaction loop:
int main() {
/////////////////
// Set up somehow
/////////////////
string anotherElephant = "y";
size_t numElephants = 0;
while (anotherElephant == "y") {
++numElephants;
cout << "Please enter elephant " << numElephants << endl;
string name;
cout << "Name: ";
cin >> name;
int age;
cout << "Age: ";
cin >> age;
Elephant el{name, age};
/////////////////////////////
// Store the elephant somehow
/////////////////////////////
cout << endl << "Another elephant (y/n)? ";
cin >> anotherElephant;
cout << endl;
}
/////////////////////////////
// Sort the elephants somehow
/////////////////////////////
cout << "The elephants are parading!" << endl;
//////////////////////////////////
// Print out the elephants somehow
//////////////////////////////////
}
Now the main thing is to decide how to store the
Elephant
s.Let's use an array!!
Good idea, but…
The problem is that we have no idea how many elephants the user might want in their parade.
That's right. So we don't know how big to make the array!
Maximum Elephants
Here's one idea: let's pick a maximum number of Elephant
s. That's how big we'll make our array. Then we'll put the user's Elephant
s in as they come.
The changes to the code are highlighted:
int main() {
constexpr size_t MAX_ELEPHANTS = 2;
Elephant elephants[MAX_ELEPHANTS];
string anotherElephant = "y";
size_t numElephants = 0;
while (anotherElephant == "y") {
if (numElephants >= MAX_ELEPHANTS) {
cout << "Sorry! We can't accept any more elephants!" << endl;
anotherElephant = "n";
} else {
++numElephants;
cout << "Please enter elephant " << numElephants << endl;
string name;
cout << "Name: ";
cin >> name;
int age;
cout << "Age: ";
cin >> age;
Elephant el{name, age};
elephants[numElephants - 1] = el;
cout << endl << "Another elephant (y/n)? ";
cin >> anotherElephant;
cout << endl;
}
}
// We'll just assume this works
sortElephantsByName(elephants, elephants + MAX_ELEPHANTS);
cout << "The elephants are parading!" << endl;
for (size_t i = 0; i < numElephants; ++i) {
cout << elephants[i].getName() << " (" << elephants[i].getAge() << ")" << endl;
}
return 0;
}
Let's trace it through with the user inputs from above (Peanut, age 2; and Manny, age 4000) and see if our code does what we expect!
Meh. Two elephants is not a parade…
That's true. How many elephants should we allow? Five? Ten?
A hundred! A million!!
MORE!!
Ahh, but there's a problem…
If we want to allow the user to make lots of elephants, our array is going to have to be big.
And that means our array will have a lot of
Elephant
objects in it.Elephant
s are big! So this approach wastes a lot of space (memory).Also, every time we add an
Elephant
, we need to first initialize it and then assign it into the array. ButElephant
s are big! We don't want to spend all that effort (CPU time) copying them from place to place.
Instead of filling our array with generic proto-Elephant
s from the beginning, and then overwriting them as the user defines them, it would be great it we only had to allocate and initialize an Elephant
when we actually need one. That way we'd avoid wasting space and unnecessary copying.
It turns out that pointers can help! But we'll need some new tools as well.
(When logged in, completion status appears here.)