Navigation



6.3 — Arrays and loops

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 5 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

1) Show Solution

2) Show Solution

6.4 — Sorting an array using selection sort
Index
6.2 — Arrays (Part II)

52 comments to 6.3 — Arrays and loops

  • Jonas

    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

  • Chad

    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.

  • Tom

    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.

  • John

    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.

  • Zak

    Thanks a lot for these very helpful tutorials! Much appreciated.

  • flashtastic

    Hi Alex,

    The tutorial is great so far. I noticed some syntax errors in some of the above code samples:

    In both the 3rd and fourth code samples you have an incorrect closing bracket:

    int anScores[nNumStudents] = { 84, 92, 76, 81, 56 );
    

    instead of

    int anScores[nNumStudents] = { 84, 92, 76, 81, 56 };
    

    Also in the 3rd code sample you have a missing angle bracket:

    double dAverageScore = static_cast<double(nTotalScore) / nNumStudents;
    

    instead of

    double dAverageScore = static_cast<double>(nTotalScore) / nNumStudents;
    

    Cheers!

    [ Fixed! Thank you. -Alex ]

  • Ben

    So trying to access an undefined array value (like

    anArray[5]

    in your example) will not return a compiler error?
    How come? It seems pretty dangerous.

    • anArray[5] won’t cause a compiler error, and it IS dangerous. C++ does not do any sort of compile-time bounds checking on it’s arrays — and perhaps worse, it doesn’t do any runtime bounds checking either! This is one of those areas that definitely falls under “trust the programmer”.

      The underlying reason is due to the fact that arrays are implemented as pointers, and [] is implemented as a pointer addition operation. You’ll learn more about this in lesson 6.8.

      Once you learn about C++ classes, you’ll be able to write your own array classes that look and feel exactly like C++ built-in arrays, but can have additional safety features like runtime range checking.

  • [...] 2007 Prev/Next Posts « 6.3 — Arrays and loops | Home | A.3 — Using libraries with Code::Blocks » Tuesday, July 3rd, 2007 at 1:47 [...]

  • runner

    Isn’t it better to do the array printing and the searching in the same loop?

    int nIndex=-1;
    	for(int iii=0;iii<9;iii++)
    	{
    		cout<<anArray[iii]<<" ";
    		if (anArray[iii]==nValue)
    			nIndex = iii;
    	}
    	if (nIndex==-1)
    	{
    		cout<<"Number not found."<<endl;
    		exit(1);
    	}
    	else
    		cout<<endl<<"The index of "<<nValue<<" is "<<nIndex<<endl;

    Also, entering a char input is leading to an infinite loop, why?

    • For efficiency purposes, yes, it’s better to only loop through the array once instead of twice. I personally would have written it the way you did, but I opted for a quiz solution that conformed more closely to the way the question was worded.

      As to your infinite loop question, I answered that one here. The issue here is the same.

  • maxs139

    Hi Alex! :) your tutorial is very awsome without it i don’t think i would be able to learn C++ so easily of course its still hard though. im a 15 year old Homeschooler very much interested in programming. i would however just like to point out something.

    in this example shouldent the ) be a } so instead of
    int anScores[nNumStudents] = { 84, 92, 76, 81, 56 );
    it should be like this
    int anScores[nNumStudents] = { 84, 92, 76, 81, 56 };

    [ Yep. I fixed it. Thanks for letting me know. -Alex ]

  • Shai

    I’ve already fixed the following silly problem, but I thought I might as well share it :)

    #include <stdafx.h>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int anArray[9] = { 4, 6, 7, 3, 8, 2, 1, 9 ,5 };
    	int nUserNum;
    	cout << "Enter a number between 1 and 9: ";
    	cin >> nUserNum;
    
    		while (nUserNum < 1 || nUserNum > 9)
    		{
    			cout << "Invalid number. Enter a number between 1 and 9: ";
    			cin >> nUserNum;
    		}
    
    	for (int nIndex = 0; nIndex < 9; nIndex++)
    	{
    		cout << anArray[nIndex] << " ";
    		if (anArray[nIndex] == nUserNum)
    			nUserNum = nIndex; // Possible unintentional override!
    	}
    
    	cout << "\nThe element containing your chosen number is " << nUserNum << endl;
    
    	return 0;
    }
    

    It’s just wrong to try to do too many things with one variable. :P

    It left me baffled for a while because most user inputs would print the correct element!

    • Yup, generally speaking it’s good to have a variable keep track of one and only one thing. Here, your nUserNum has two jobs: to accept the user input, and then later to store the index of the matching array element, which is a totally different thing!

      Although it may have taken you a while to find and fix the issue, it’s a good lesson to learn.

  • Taha

    hi alex,
    i dont understand solution to question no:2
    the iii & jjj is confusing.

    which comes first???

    await your reply.

    • What do you mean “which comes first?”

      The program executes sequentially. You can think of it as being 3 parts.

      First is the do-while. The do-while executes until the while is false.

      Second is the for iii loop. This loop executes until iii >= 9.

      Third is the for jjj loop. This loop executes until jjj >= 9.

  • Mithrildor

    I made this one for question 2 is this oen right too?

     #include <iostream>
    #include <cmath>
    
    int main()
    {
        using namespace std;
        tryAgain:
        cout<<"Enter a number between 1 and 9: ";
        int x;
        cin>> x;
        cin.ignore();
        if (x > 9)
        {
              goto tryAgain;
        }
        else if (x < 1)
        {
             goto tryAgain;
        }
        else
        {
        int anArray[9] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
        for (int iii=0; iii < 9; iii++)
            cout << anArray[iii] << " ";
        cin.ignore();
        cout<< anArray[x-1];
        cin.get();
    
        }
    }
     

    It looks easir to understand to me.

  • I dont know about Visual C++ 2005, but on Visual C++ 2008, the code on the second quiz does not seem to work right. I am using the professional edition of Visual Studio 2008 so it might be different for some people. The error on the program is that when it identifies the index it is allways off by one. For example if I type 4, this will be the following output:

    7
    4 6 7 3 8 2 1 9 5

    The number 4 has index 2

    The index output in the 4th line is always decreased by 1. If you are expirencing the same problem, please try to use this code instead. It has the increment statement added in a certain point that increases the index value to the right amount (or you could use “jjj += 1;” statement but I used incrementation). And its aloways a good idea to make sure the program doesn’t automatically close (the “break;” statement is now used only for just in case):

    #include <iostream>
    int main()
    {
        using namespace std;
        int nNumber;
        do
        {
            cout << "Enter a number: ";
            cin >> nNumber;
        } while (nNumber < 1 || nNumber > 9);
        int anArray[9] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
        for (int iii=0; iii < 9; iii++)
            cout << anArray[iii] << " ";
        cout << endl;
        for (int jjj=0; jjj< 9; jjj++)
        {
            if (anArray[jjj] == nNumber)
            {
                ++jjj;
                cout << "The number " << nNumber << " has index " <<
                    jjj << endl;
                cin.clear();
                cin.get();
                break;
            }
        }
        return 0;
    }
    

    If anyone know why this problem is occuring and / or how to solve it “properly”, please leave a comment here.

  • FuturePixstar

    …typo

    and this is just 4 students!

    should be

    and this is just 5 students… *sigh* I hate when people do that to me.

    Also I would like to thank you very very very much for all the work you put into this.
    I’m aspiring to be a programmer for pixar (or square-enix… not a fan of the new disney owners).
    I’m working on a game right now and when im done i just have to let all who plays it know about this site, its amazing. THX YOU!

  • Matthew
    #include "stdafx.h"
    #include <iostream>
    
    int main()
    {
    int anArray[12] = { 4, 6, 7, 3, 8, 2, 1, 9, 5, 11, 14, 2 };
    
    using namespace std;
    
    cout << "Enter a number between 1 and 12: ";
    
    int h;
    do
    {
    	cin >> h;
    }	while (h = <1 || >9);
    
    cout << anArray[h - 1];
    
    while (1) ;	// Pause the program for debugging purposes
    
    }
    
    

    I’m getting a “syntax error : ‘<’” when I try to compile; it’s pointing to this line:

    } while (h = <1

    My code looks the same as yours!!!! This is driving me nuts! What have I done wrong?

  • Mattias

    For the second question, would this also work? (When each element in the array has a unique value of course)
    If it has any downsides please let me know.

    #include "stdafx.h"
    #include <iostream>
    
    int main()
    {
    	using namespace std;
    	int nInputNumber;
    	do
    	{
    		cout << "Please enter a number between 1 and 9: ";
    		cin >> nInputNumber;
    	}while((nInputNumber < 0) || (nInputNumber >= 9));
    
    	const int nArrayElements = 9;
    	int anArray[nArrayElements] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
    	cout <<"The array contains the following elements: ";
    	int nInputElement = -1;  // This will hold the place of the input number.
    	for(int iii = 0; iii < 9; iii++)
    	{
    		cout << anArray[iii] << " ";
    		if(anArray[iii] == nInputNumber)
    			nInputElement = iii+1;
    	}
    	cout << endl;
    	cout << "Your number was element number " << nInputElement << "." << endl;
    	return 0;
    }
    
  • Sagar
     In solution number 2, shouldn't it be nNumber > 1 || nNumber < 9 ?
  • Jesper

    Hey – the below code is copy pasted directly from Microsoft Visual 2010 and as far as i can see its exactly the same as the solution Alex posted.

    I’m new to learning c++, and I’m really enjoying following this tutorial.

    My question is this:
    When i run the program it correctly keeps asking for a number between 1 and 9 as long as i input a number when prompted. However if I input a letter (Tried it to see what would happen incase of a misstype) it seems to go into an endless loop. Is it supposed to do that (with the code written) or is there another way to avoid this problem I should implement?

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int x;
    	do
    	{
    		cout << "Please input a number between 1 and 9: ";
    		cin >> x;
    	}	while (x < 1 || x > 9);
    
    	int anArray[9] = {4, 6, 7, 3, 8, 2, 1, 9, 5};
    	for (int iii = 0; iii < 9; iii++)
    		cout << anArray[iii] << " ";
    
    	cout << endl;
    
    	for (int jjj = 0; jjj < 9; jjj++)
    	{
    		if (anArray[jjj] == x)
    		{
    			cout << "The number you entered (" << x << ") has index number: " << jjj << endl;
    			break;
    		}
    	}
    
    	return 0;
    }
    • Slotenmaker

      I had the same problem, it is because of cin.
      cin tries to stream a character inside an integer, which will fail. But the stream will stay in memory! So the next loop it will again try the same character, and again, and again, etc.

      If you put this code in the while loop it fixes this problem, you will also have to #include .
      It clears the stream:

      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');

      Also you can use strings as an alternative.

  • bonno

    hi people… i’ve written some codes to compose a multiplying equation that consist of every integer from 1 to 9.
    anybody have any idea to simplify my codes so that it won’t look so messy?

    #include “stdafx.h”
    #include

    int main()
    {
    using namespace std;

    int anX[9];

    for(anX[0]=1; anX[0]<5; anX[0]++)
    {
    for(anX[1]=1; anX[1]<10; anX[1]++)
    {
    if(anX[0]==anX[1])
    continue;
    for(anX[2]=1; anX[2]<10; anX[2]++)
    {
    if(anX[1]==anX[2])
    continue;
    for(anX[3]=1; anX[3]<10; anX[3]++)
    {
    if(anX[2]==anX[3])
    continue;
    for(anX[4]=1; anX[4] 9999 || aaa < 1000)
    continue;
    anX[5] = aaa/1000;
    anX[6] = (aaa – anX[5]*1000)/100;
    anX[7] = (aaa – anX[5]*1000 – anX[6]*100)/10;
    anX[8] = aaa – anX[5]*1000 – anX[6]*100 – anX[7]*10;
    if(anX[5]==0 || anX[6]==0 || anX[7]==0 || anX[8]==0)
    continue;
    bool result = true;

    for(int iii=0; iii<9; iii++)
    for(int jjj=0; jjj<9; jjj++)
    {
    if(iii!=jjj && anX[iii]==anX[jjj])
    result = false;
    }
    if(result)
    {
    cout << "The Result is?" << endl;
    int bbb = anX[0]*1000 + anX[1]*100 + anX[2]*10 + anX[3];
    int ccc = bbb * anX[4];
    cout << bbb << " * " << anX[4] << " = " << ccc << endl;
    }
    }
    }
    }
    }
    }
    }
    cout << "The End?" << endl;
    }

  • pinky

    hi, i am having a problem in this program:
    int _tmain(int argc, _TCHAR* argv[])
    {

    int n=0 ,num;
    int list[4];
    int j;
    cout<<"Enter 5 numbers"<> list[n])
    {
    n++;
    if (n== 4);
    //break;
    }*/
    for(int i=0 ; i>list[i];
    }
    cout<<"Enter a number "<>num;
    for(j=0;j<5;j++)
    {
    if(list[j]==num)
    {
    cout<<"The number of term is: "<<j<<endl;
    }
    }

    return 0;
    }
    // i know how to run it using while loop but a debug error occurs while using a for loop.
    please answer

  • eect13

    is my solution same on #2?

    #include
    using namespace std;

    void main()
    {
    int number;
    do
    {
    cout <> number;
    }
    while(number 9);

    int array[] = {1,3,2,5,8,11,4,9,21,24};

    for (int index = 0; index <= 9; index++)
    {
    cout << array[index] << " ";
    }
    cout << endl << number << " has index " << array[number] << endl;

    system("pause");
    }

    • eect13

      #include
      using namespace std;

      void main()
      {
      int number;
      do
      {
      cout <> number;
      }
      while(number 9);

      int array[] = {1,3,2,5,8,11,4,9,21,24};

      for (int index = 0; index <= 9; index++)
      {
      cout << array[index] << " ";
      }
      cout << endl << number << " has index " << array[number] << endl;

      system("pause");
      }

  • eect13

    cant paste my code properly sorry

  • Silvia

    For 6.3 — Arrays and loops – 2nd Quiz: If I run your code, and enter any letter instead of a number, it loops infinitely on printing the request. Why? (Entering any number other than 1..9 it works instead: it properly stops on asking)

  • Keroronsk

    I guess it’s better to use sizeof(anScores) instead of nNumStudents=5 :)

  • Refat Eid

    hay,
    first of all thanks a lot for this tutorial :)
    now i have a simple problem, when i try to do the second Quiz
    if I entered char for example $
    it enter an infinite loop

    • Refat Eid

      int anArray[9] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
      int num;
      do
      {
      cout <> num;
      }
      while(num 9);

      for(int nIndex =0; nIndex < sizeof(anArray)/sizeof(anArray[0]);nIndex++)
      if(anArray[nIndex] == num)
      {
      cout << "Your array index is : " << nIndex <<endl;
      break;
      }

  • ahmed20

    hi iam just a student and i cannot answer this quiz can you help me; please?
    4.2 Determine the score
    Your friend has developed a game in which you have a
    player that walks in a maze and kills his enemies. He
    has a problem in calculating his score. He asked you to
    write a program that prints his score.
    You will be given: 2 Integers M and N (1<= M <= N
    <= 100) followed by a 2D representation of the maze
    (M X N), where the point [i, j] represents the value of
    killing the monster on this grid.
    The path that the player will take: string which points
    the direction you move to ( N for North, W for West, E
    for East, S for South )
    The player's starting point is [0, 0]
    Print the score of the player.
    Sample Input :-
    5 5
    1 2 3 4 5
    6 5 4 3 2
    5 8 5 2 9
    1 3 4 9 7
    6 5 4 3 2
    SSESEN
    Sample Output :-
    32

You must be logged in to post a comment.