cs1ch7sec2.htm
 
 
 
CHAPTER 7

ARRAYS: A BETTER WAY OF HANDLING MULTIPLE INSTANCES
Section II: Accessing Array Elements Section I : Introducing Arrays Section III: Arrays and For Loops Section IV: Arrays as Parameters

  


Table of Contents

Learning C++:
An Index of Entry Points


2. The
Essentials
of C++

A reference document on the basic elements of C++.



3. The Patterns





A. Naming the Individual Elements
The variable 'itemInventory' refers to all 10,000 integer memory locations being used to hold the inventory. How does one get at the individual elements of this array? Since each inventory item has its own memory location, all we need is some way to tell the system which memory location we want. C++ and most other languages that include arrays use what are called subscripts or sometimes indices (singular, index) to 'name' the individual elements of an array. Unfortunately, C++ has a bit of a trick in its usage of subscripts. Left over probably from the days when memory was expensive and programmers had to save all the memory they could, C++ starts counting, not from one like we usually do, but from zero. In other words, the first element of an array is not given the subscript 1 but the subscript 0. Similarly, the 10th element of an array has the subscript value 9! UGH!

At the code level, the C++ name for the memory location for the first item in the inventory array is:

itemInventory[0]

while the name for the 10th item is:

itemInventory[9]

Note that although we have 10,000 items, there is no "itemInventory[10000]" As a matter of fact, to write "itemInventory[10000]" in the program we are working on would likely cause serious problems because we would be accessing the first memory location past the end of the array. Thus, we declare our array using the value 10,000, meaning that there are 10,000 integer memory locations to set aside BUT we use subscript values in the range 0 to 9999.

At this point we know that each individual array element is a unique memory location and that the array name along with a subscript enclosed in brackets represents that memory location. Further, each individual array element is of some type - the type included in the array declaration. In other words, when one writes "itemInventory[3456]", one is referring to a specific integer. Therefore, "itemInventory[3456]" can be used ANYWHERE in a program that an integer can be used. The same is true for array elements of any type. We will see later, for example, that if we declare an array to hold elements of some class type, the elements of that array can be used anywhere instances of the class can be used.

B. Working with the Individual Elements
Let's start with simple examples involving our inventory array. Above, we said that the item codes for the items would range from 1 to 10000. To make this problem and our coding life easier, let's change that to read that the item codes range from 0 to 9999. Remember, this means that the first inventory item has the item code '0', the second has the item code '1', the third has the item code '2', etc.

Suppose we wanted to state that there are 20 items in the inventory with item code 4. We could write this as:

itemInventory[4] = 20;

The code is the same as any other assignment statement, except for the subscript.

Or, suppose we wanted to add 1 to the first inventory item. We could now write this as:

itemInventory[0]++;

If we wanted to read in a value and store that value in the location holding the amount for item code 22, we could write:

cin >> itemInventory[22];

And, if later we wished to output the inventory count for that same item, we could write:

cout << itemInventory[22];

We can also use these elements in arithmetic expressions. Suppose, for example, that we wanted to find out the worth of our inventory for the item with item code 12. Remembering that we also have an array of item prices called 'itemPrices', we could calculate this using the code:

itemWorth = itemPrices[12] * itemInventory[12];
// the price of an individual item times the number of items with that code

Likewise, we can use array elements in relational expressions. For example if would be legal to write:

    if (itemInventory[342] < 2345)
    {
      // some code
    }

This would mean that "some code" would be executed if there were fewer than 2,345 items with the inventory code '342'.

To repeat, since the array, 'itemInventory', holds integers, we can use the individual elements of that array ANYWHERE integer elements can be used. And, the same can be said for any other array type.

One thing that has not been said yet is that we cannot in general use JUST the name of the array. It makes no sense, for example, to write:

itemInventory = 22;

or

cout << itemInventory;

Which inventory item gets the value 22? Or, which inventory item is to be output? We will see in a bit how to quickly output, for example, all the elements of an array

C. Variables as Indices
We are now ready to rewrite that ugly switch statement we saw above - the one with the 10,000 'cases' - to handle the 10,000 items in the inventory. The code for that statement included the line below to indicate that the inventory for item 9999 is being reduced by the amount sold ('itemSold'):

item9999 -= itemSold;

Remembering that item codes now start at 0 instead of 1 and that the item code for item 9999 would now be 9998, we can rewrite this as:

itemInventory[9998]-=itemSold;

This by itself does not gain us much. However, there is no reason why our subscript values must be constants. It is perfectly legal for subscripts to be variables or even expressions (for example, var1 + var2) - as long as those expressions evaluate to integers. Subscripts must evaluate to integers because it is, of course, impossible to talk about the 2.5th element of an array.

Using the previous declaration for itemInventory and assuming that the individual items have been loaded with the correct inventory values, it would be perfectly legal to write the code:

    int itemCode = 9998; // declare a variable and initialize its value to 9998
    int itemSold;
    cout << "Please enter the amount sold of the item with inventory number '9998'.
    cin >> itemSold;
    itemInventory[itemCode] -=itemSold;

The key here is the last line. Since 'itemCode' has the value 9998, this code is the equivalent of

itemInventory[9998]-=itemSold;

Now we go one step further and ask the user for the item code. (In a store this information would be received from the device that reads bar codes at the check-out counter.).

    int itemCode;
    int itemSold;

    cout << "Please enter the code for the item being sold.\n";
    cin >> itemCode;

    cout << "Please enter the amount sold.\n";
    cin >> itemSold;

    itemInventory[itemCode] -=itemSold;

The last line still has the same effect, but instead of the value of 'itemCode' being hard coded into the program, it is entered by the user. Since there are no longer 10,000 independent variables, these few lines can take the place of that monster 'switch' statement. And, if we put this code inside a while loop, we could handle purchases all day long.

There is one potential problem that we should take care of here. What if the user enters a negative number for the item code or a number greater than 9999. We would then be attempting to access and change memory that is NOT part of the array. C++ does not automatically perform what is called bounds checking - checking to see if an array index falls into a valid range. We must do this ourselves by not allowing the access to take place if the code is out of range:

    if ( (itemCode < 0) || (itemCode > 9999))
    {
       cout << "Invalid Item Code!!! \n";
    }
    else
    {
       itemInventory[itemCode] -=itemSold;
    }
    
Note that we are using a numeric constant here in a place where we should probably have a named constant. This whole code would be better written as:
    const   MAX_ITEMS = 10000
    
    int itemInventory[MAX_ITEMS];
    .
    .
    .
    if ( (itemCode < 0) || (itemCode > MAX_ITEMS - 1))
    {
       cout << "Invalid Item Code!!! \n";
    }
    else
    {
       itemInventory[itemCode] -=itemSold;
    }
    

Top of Section Main Menu Next Section