Loops and arrays
Because array elements can be accessed by a variable, it is common to use a loop to access or manipulate each array element in turn. Wherever you find arrays, you will almost certainly find loops as well.
Consider the case where we want to find the average test score of a class of students. Using individual variables:
const int nNumStudents = 5; int nScore0 = 84; int nScore1 = 92; int nScore2 = 76; int nScore3 = 81; int nScore4 = 56; int nTotalScore = nScore0 + nScore1 + nScore2 + nScore3 + nScore4; double dAverageScore = static_cast<double>(nTotalScore) / nNumStudents;
That’s a lot of variables and a lot of typing — and this is just 4 students! Imagine how much work we’d have to do for 30 students, or 150.
Plus, if a new student is added, a new variable has to be declared, initialized, and added to the nTotalScore calculation. Any time you have to adjust old code, you run the risk of introducing errors.
Using arrays without loops offers a slightly better solution:
const int nNumStudents = 5;
int anScores[nNumStudents] = { 84, 92, 76, 81, 56 };
int nTotalScore = anScores[0] + anScores[1] + anScores[2] + anScores[3] + anScores[4];
double dAverageScore = static_cast<double>(nTotalScore) / nNumStudents;
This cuts down on the number of variables declared significantly, but nTotalScore still requires each array element be listed individually. Furthermore, changing the number of students means the nTotalScore formula needs to be adjusted.
Using arrays with loops:
const int nNumStudents = 5;
int anScores[nNumStudents] = { 84, 92, 76, 81, 56 );
int nTotalScore = 0;
for (int nStudent = 0; nStudent < nNumStudents; nStudent++)
nTotalScore += anScores[nStudent];
double dAverageScore = static_cast<double(nTotalScore) / nNumStudents;
This solution is ideal in terms of both readability and maintenance. Because the loop does all of our array element accesses, the formulas adjust automatically to account for the number of elements in the array. This means the formulas do not have to be manually altered to account for new students, and we do not have to manually enter the name of each array element!
Here’s another example of using a loop with an array to determine the best score in the class:
const int nNumStudents = 5;
int anScores[nNumStudents] = { 84, 92, 76, 81, 56 );
int nMaxScore = 0;
for (int nStudent = 0; nStudent < nNumStudents; nStudent++)
if (anScores[nStudent] > nMaxScore)
nMaxScore = anScores[nStudent];
cout << "The best score was " << nMaxScore << endl;
In this example, we use a non-loop variable called nMaxScore. nMaxScore is initialized to 0 to represent that we have not seen any scores yet. We then iterate through each element of the array, and if we find a score that is higher than any we’ve seen before, we set nMaxScore to that value. Thus, nMaxScore always represents the best score out of all the elements we’ve searched so far. By the time we reach the end of the array, nMaxScore holds the highest score in the entire array.
Loops are typically used with arrays to do one of three things:
1) Search for a value (eg. highest, lowest).
2) Calculate a value (eg. average, total)
3) Reorganize the array (eg. sort from lowest to highest)
When searching for a value, a variable is typically used to hold the best candidate value seen so far (or the array index of the best candidate). In the above example where we use a loop to find the best score, this variable is used to hold the highest score encountered so far.
When calculating a value, a variable is typically used to hold an intermediate result that is used to calculate the final value. In the above example where we are calculating an average score, nTotalScore holds the total score for all the elements examined so far. This value is then later used to calculate the overall average score.
Sorting an array is a bit more tricky, as it typically involves nested loops. We will cover sorting an array in the next lesson.
Off-by-one errors
One of the trickiest parts of using loops with arrays is making sure the loop iterates the proper number of times. Off-by-one errors are easy to make, and trying to access an element that is larger than the size of the array can have dire consequences. Consider the following program:
const int nArraySize = 5;
int anArray[nArraySize ] = { 6, 8, 2, 4, 9 };
int nMaxValue = 0;
for (int nIndex = 0; nIndex <= nArraySize; nIndex++)
if (anArray[nIndex] > nMaxValue)
nMaxValue = anArray[nIndex];
The problem with this program is that the conditional in the for loop is wrong! The array declared has 5 elements, indexed from 0 to 4. However, this array loops from 0 to 5. Consequently, on the last iteration, the array will execute this:
if (anArray[5] > nMaxValue)
nMaxValue = anArray[5];
But anArray[5] is undefined! This can cause all sorts of issues, with the most likely being that anArray[5] results in a garbage value. In this case, the probable result is that nMaxValue will be wrong.
However, imagine what would happen if we inadvertently assigned a value to anArray[5]! We might overwrite another variable (or part of it), or perhaps corrupt something — these types of bugs can be very hard to track down!
Consequently, when using loops with arrays, always double-check your loop conditions to make sure you do not introduce off-by-one errors.
Quiz
1) Print the following array to the screen using a loop:
int anArray[9] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
2) Ask the user for a number between 1 and 9. If the user does not enter a number between 1 and 9, repeatedly ask for a number until they do. Once they have entered a number between 1 and 9, print the array. Then search the array for the number that the user entered and print the index of that element.
Quiz solutions
6.4 — Sorting an array using selection sort
|
Index
|
6.2 — Arrays (Part II)
|
6.4 — Sorting an array using selection sort
Index
6.2 — Arrays (Part II)
Please tell me what is wrong here:
for (int count=0; count < 9; countppp)
(p = key left to the “0″ key. it dose not work)
I got this error:
error C2059: syntax error : ‘)’
Thanks
On my keyboard (USA), the key to the left of the “0″ key is the “9″ key. count999 does not make any sense, so I suspect that’s not what you meant. I don’t think I can diagnose this without more information. Try posting a message in my forum with more information and I’ll see if I can help you there.
Oh, that was a very bad mistake. The key to the right of 0
If you mean this:
The answer is that it doesn’t work because you have three minuses instead of two. Two minuses means “decrement the value of count by 1″. Three minuses is meaningless — and it’s invalid syntax in C . That’s why it’s giving you a syntax error.
I ment plus, but just forget it
Well, three plusses also does not mean anything. To increment a variable, use two plusses.
Shouldn’t you put a break in your if statement? If we know that each element of naArray is unique, we only need to search until we find what we want. Searching the rest of the array just wastes time.
Yup, if we can assume that each element of naArray is unique, then we could terminate the loop after finding an element that matches. I will clarify the solution.
Hello Alex -
Would this also be a correct way to do the search?:
int iii = 0; while (anArray[iii] != nNumber) { iii++; } cout < < "The number: " << nNumber << " has index: " << iii << endl;Thanks!
Your code is not quite correct — what happens if it doesn’t find the number the user entered? In that case, iii will be 10 when the loop exits, and your code will still print that the number has index 10, which is not a valid index.
As an aside, using a for loop to iterate through an array is usually better than a while loop because it contains the initialization and increment all within one statement, making it less likely you’ll forget them.
The user is asked to enter a number between 1 and 9, but the array is indexed by 0 to 8, and the for loop runs from 0 to 8. This doesn’t make sense to me. Is this an error?
In C++, all arrays are 0-based, meaning the first element is numbered 0. In regular life, if we have 9 items, we’d count them like this: 1 2 3 4 5 6 7 8 9. However, in C++, we begin counting at 0, so we count 9 items like this: 0 1 2 3 4 5 6 7 8. That’s why the array is indexed 0 to 8.
Hi Alex. Well, since u said some pages ahead (This frase will take out your sleep dude xD):
“By all means, point out anything you see. I want this site to be as good as it can be.”
I couldn’t help coming back to this page and pointing a few errors I found on the examples given in here.
* In the 2nd example you didn’t close the static_cast declaration. The same error is repeated in the 3rd example (probably a copy paste of the previous).
* In the 3rd example you used the enum MAX_STUDENTS from the previous page instead of the const nNumStudents that was actually declared in the given example.
* In the 4th example you insisted with the enum MAX_STUDENTS, which is not incorrect since the variable declarations have been omited in this example, but seems a bit out of contest since you haven’t showed any example using enumerated types in this page and can be somewhat confusing to someone that got here without reading the previous page right before.
well that’s all for now. Thx for the great tuto, keep the good work
(sorry for the bad english)
Thanks for the note! I’ve fixed all of these issues. I appreciate you taking the time to point them out.