Mmmkay... simple enough.
Lets begin with your second
for
loop. I see you iterate over each variable within the gathered user input and each loop iteration represents a single person, with a total of three iterations, or three people. And after determining if the value is less/greater-than the current, you assign the new value to the Min/Max variable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
for (z = 0; z < 3; z++)
{
if (MaxEaten < PancakesEaten[z])
{
MaxEaten = PancakesEaten[z];
MaxPers = z + 1;
}
if (MinEaten > PancakesEaten[z])
{
MinEaten = PancakesEaten[z];
MinPers = z + 1;
}
}
|
When you are programming (in any language) you need to look for patterns that can 'tighten' your code. Not neccessarily make it smaller, or simpler, but to improve the readability so that your code can be easily understood, not read, by other developers. Being a small piece, your code is understood easily.
Now, lets look at the first 'for' loop (with all my comments):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
int x; // hmmm, used as iterator
int z; // hmmm, aswell
int MaxEaten; // maximum pancakes eaten
int MinEaten; // minimum pancakes eaten
int MaxPers = 1; // the person who ate the most
int MinPers; // the person who ate the least
int PancakesEaten[3]; // hmmm, store min and max variables
// well written sentence
cout << "How many pancakes did each person eat?" << endl;
// hmmm, constant three iterations
for (x = 0; x < 3; x++)
{
cout << "Person " << x + 1; cout << ": ";
cin >> PancakesEaten[x];
}
|
I see you are using the x and z variables as incrementers in the for loop and only incrementing them three times (once per iteration) with each iteration representing a single person.
Do you see any patterns? Instead having the the two incrementers, you could provide constant that represents the maximum number of loops to peform, or number of persons eating pancakes:
|
const int MaxPeople = 3; // 'const' modifier tells the compiler the value never changes
|
In for loops, you are allowed to declare temporary incrementers and using the above constant, your for loops can be written as:
1 2 3 4
|
for(int i = 1; i <= MaxPeople + 1; i++) // 'i = 1' and check for '<= MaxPeople + 1'
{
// ...
}
|
Additionally you can change:
1 2
|
int PancakesEaten[3]; // to:
int PancakesEaten[MaxPeople];
|
You programs behavior can now be influenced by the MaxPeople constant, verses hand written constants, like '3'.
The next part depends on whether or not, your professor, wants the data to be 'stored' and later operated on, or if your application can process data as its recieved.
If he wants the data to be stored and later operated on, your assignment can only contain the modified for loops by applying the above syntax and replacing
x
and
z
with
i
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
for(int i = 1; i <= MaxPeople + 1; i++)
{
// cout << "Person " << i; cout << ": ";
// can be cleanly written as:
cout << "Person " << i << ": "; // all << (goes into) cout
// the cout '<<' operator can be 'chained'
cin >> PancakesEaten[i];
}
// ...
for(int i = 1; i <= MaxPeople + 1; i++)
{
if (MaxEaten < PancakesEaten[i])
{
MaxEaten = PancakesEaten[i];
MaxPers = i + 1;
}
if (MinEaten > PancakesEaten[i])
{
MinEaten = PancakesEaten[i];
MinPers = i + 1;
}
}
|
For the sake of learning, we wil further optimize this code (for readability).
Instead of using the PancakesEaten[3] array, you can ditch the array completely and process user input data as its received. First, move the contents of the second for loop, into the first for loop, directly after
cin << PancakesEaten[i]
and introduce a loop local variable used to store user input, rewritten as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
// ...
for(int i = 1; i <= MaxPeople + 1; i++)
{
cout << "Person " << i << ": "; // all << (goes into) cout
// and change
// cin >> PancakesEaten[i];
// to:
int userinput;
cin >> userinput;
// a zero will create strange clauses below, introducing a bug
// so lets disqualify the persons answer, decrement i, and jump
// to the start of the loop
if (userinput == 0)
{
cout << "Impossible!" << endl; // endl is within the std:: namespace, represents end of line char
i--; // and lets not skip the person
// keyword, meaning: skip into the next iteration of the loop that
// current code scope belong to (including 'while' and 'do-while' loop)
// ignoring everything below
continue;
}
if (MaxEaten == 0)
{
MaxEaten = userinput; // single line if statement doesn't need {}
}
else if (userinput > MaxEaten) // note: checking userinput, not MaxEaten
{
MaxEaten = userinput;
MaxPers = i;
}
if MinEaten == 0)
{
MinEaten = userinput; // single line if statement doesn't need {}
}
else if (userinput < MinEaten) // note: checking userinput, not MinEaten
{
MinEaten = userinput;
MinPers = i;
}
}
// ...
|
To ensure that you don't get confusing results from your variables, assign a default value to them, and rewritten, the new approach looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
const int MaxPeople = 3; // more flexible! modifies the loop!
int MaxEaten = 0; // not '1', nobody ate pancakes yet!
int MinEaten = 0; // ...like I said
int MaxPerson = 0;
int MinPerson = 0;
cout << "How many pancakes did each person eat?" << endl;
for(int i = 1; i <= MaxPeople + 1; i++)
{
cout << "Person " << i << ": "; // all << (goes into) cout
int userinput;
cin >> userinput;
if (userinput == 0)
{
cout << "Impossible! Try that again!" << endl;
i--;
continue;
}
if (MaxEaten == 0)
MaxEaten = userinput;
else if (userinput > MaxEaten)
{
MaxEaten = userinput;
MaxPers = i;
}
if MinEaten == 0)
MinEaten = userinput;
else if (userinput < MinEaten)
{
MinEaten = userinput;
MinPers = i;
}
}
// 'endl' == '\n', usually
cout << "Person " << MaxPerson << " ate the most pancakes: " << MaxEaten << endl;
cout << "Person " << MinPerson << " ate the least pancakes: " << MinEaten << endl;
// always return '0', because the OS would like to know how the application 'exited'
// also known as the 'exit code'
return 0;
|
I hope this helps you with finding patterns, so that you can write better code. As far as the actual confusion you have about the value of MaxEaten, it could be a couple things, but don't quote me.
Most compiler will default values of most built-in data types to zero or false, or infinity. Sometimes, when receiving really strange results, the problem may not be in your written code or be an issue of software and the problem could exist as a hardware issue, possibly in your computers RAM. Your application is loaded into RAM when executed and if a variable is stored within an area of RAM that contains 'bad bits', the CPU will receive false-positive bits, resulting in a dramatic change within the value of the variable any 'bad bits' belong to.
When it happens again, try looking into using a debugger, so you can step through each line of code as it executes and watch the values of variables.
Research, research, research, practice.
Happy holidays!
EDIT: I need to type faster.