.. _arrays: C++ Arrays! ########### .. seealso:: Reading Assignment Text: Chapter 7a Now, we come to an important concept - the `Data Structure`. Up to now, we have been using small containers to hold fairly simple pieces of data. Things like **integers**, **floats**, **characters** are all pretty small chunks of stuff, and only take a few of our little eight-bit boxes to store in memory. We cannot make very interesting programs if all we can do is play around with simple data like these. To paraphrase the sheriff in *Jaws* "We need a bigger boat" - er container for our data! Here is how we do it: .. code-block:: c int grades[25]; Hmmm. All we have added is some square brackets and a number in between after a name. In this example we have asked the compiler to reserve 25 integer boxes for us and call that entire chunk of memory by the name `grades`. This group of memory locations - all 25 of them - is called a `data structure` to emphasize the fact that we are dealing with a group of containers, each big enough to hold a single integer value. Obviously, we have to work harder to initialize this new kind of container, and we have several ways to do that. If the number of integers is small enough, we can use this approach: .. code-block:: c int grades[5] = {100,92,48,87,95}; Here, we have provided a list of values to be used to initialize all 5 integer containers in the array. This initialization would be a real pain for a big array with lots of numbers, but we could do this if we like. Accessing Array Elements ------------------------- How do we get at the individual elements of the array? We need a new notation to refer to one single element in the array - that notation uses the square brackets again, and a new thing called an index: .. code-block:: c grades[0] = 100; grades[4] = 95; .. warning:: In C++, unlike real life, the first container in a group of containers has an index of zero, not one! So, for our last example, we can refer to each of the five locations in the container named grades by using the index numbers from zero to four! Far to many mistakes in programming are due to thinking the first index should be one, and the last index should be five! Looping over the array ---------------------- Suppose we had a big class and wanted to initialize all the grades to zero (OK, lets make it 100, just to be nicer). We can set up a simple loop to do the job: .. code-block:: c int grades[25]; ... for(int i=0;i<25;i=i+1) { grades[i] = 100; } Here, we see that the thing inside the square brackets is actually an expression that evaluates to a simple integer - one that should be between 0 and 24 for this example. On each pass through the loop, a different element of the grades array gets set to the value 100. When the loop completes, all 25 locations will have been initialized. Examples of array problems -------------------------- Let's consider the problem of setting a letter grade for a numerical grade. Lets set up a problem and solve it using arrays: .. code-block:: c int grades[10] = {100,77,65,88,99,90,80,50,69,70}; char letters[5] = {'A','B','C','D','F'}; int main(void) { int thisGrade; int minGrade; char thisLetter; for(int i=0;i<10;i=i+1) { thisGrade = grades[i]; minGrade = 90; for(int j=0;j<5;j=j+1) { thisLetter = letters[j]; if(thisGrade >= minGrade) break; minGrade = minGrade - 10; } cout << "A grade of " << thisGrade << " gets a " << thisLetter << endl; } } Which gives us this: .. code-block:: bash A grade of 100 gets a A A grade of 77 gets a C A grade of 65 gets a D A grade of 88 gets a B A grade of 99 gets a A A grade of 90 gets a A A grade of 80 gets a B A grade of 50 gets a F A grade of 69 gets a D A grade of 70 gets a C Phew, how does this code work. Well, to figure it out, we need to walk it through by hand and see if it does what we want. What is the overall structure of this code? ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, We see a list of grades stored in an array, and we see a list of possible letter grades stored in a second array. The grades are arranged in the correct order, and we all know the rules for assigning letter grades to number grades. Grades from 90 to 100 get an A, from 80-89 get a B and so on. The break point starts off at 90 and decreases by 10 for each letter grade. Hmmm, maybe we can use this fact to figure out the letter grade. Our program starts off by looping over all the grades in the class - looping over the grades array, examining one grade at a time. For simplicity, I copy the particular grade from the array into another variable. I do not need to do this, but it might make the code easier to understand. Inside the body of this outer loop, my job is to figure out exactly what letter grade to assign. That takes another loop! Figuring out the letter grade ,,,,,,,,,,,,,,,,,,,,,,,,,,,,, While I could have used a giant `if statement` to figure out the grade, we are going to do it a bit differently. Since we have five possible letter grades available, we could loop over those grades and search for the one that one applies to the grade we are looking at at the moment. As soon as we can see that we have the right grade assigned, we can bail out of this second loop and print out the answer. But, how can we know we have found the right letter grade. Lets set up an integer variable called `minGrade` and set it to the lowest grade that will earn the first letter in our letter grade array. Anything equal to or above a 90 will get an A. Now we loop over the five letter grades, using the counter `j` to track which letter we are examining. If the grade we are checking is bigger than (or equal to) the minimum grade, we have found our letter grade and we can stop looking. The `if statement` checks this, and uses the `break statement` to bail out of the inner loop. If the grade we are examining is less than the current minimum grade value, we have not found the right letter grade yet, so we need to move on to the next letter in the letter array. For this next letter, the minimum grade is 10 points lower than it was for the last letter, so we decrease our '''minGrade''' variable by 10 and let the loop try again. You need to think about what happens if the number grade really gets an F. Is the logic of this code working right? On the last pass through the inner loop, what value does minGrade have? Is 50 really the lowest number grade that gets an F? Actually, no - any number grade we have left when we reach this last pass gets an F. The variable thisGrade will probably still be lower than the '''minGrade''' value, but all that means is that we will not break out of this loop on the ''if-statement''. But, since we are on the last pass, we will exit the loop anyway with thisLetter set to an F just like we want. This is too complicated! ,,,,,,,,,,,,,,,,,,,,,,,, Well, I admit that thinking this logic up might not come naturally to you until you have fought through a few situations like this. What is important here is that you see how the loops work and can walk your way through the code and figure out what is happening. .. note:: You learn a lot about programming by studying other people's code. There is a huge amount of code available on the Internet, and when you want to figure out how to do something, use your best friend; `Google `_ to find example code! If you like, you can always rewrite this to use the nested `if-statements` we used earlier to figure out the letter grades - eliminating the inner loop and array of letter grades in the process. Which way is better? You get to decide as long as both work!