Because cookies acts as the address of the first element, cookies + 4 acts as the address of the fifth element. This statement sums the fifth, sixth, seventh, and eighth elements of the array. Note in the output how the third call to the function assigns a different address to arr than the first two calls did. And yes, you can use &cookies[4] instead of cookies + 4 as the argument; they both mean the same thing.
Note
To indicate the kind of array and the number of elements to an array-processing function, you pass the information as two separate arguments:
void fillArray(int arr[], int size); // prototype
Don’t try to pass the array size by using brackets notation:
void fillArray(int arr[size]); // NO -- bad prototype
More Array Function Examples
When you choose to use an array to represent data, you are making a design decision. But design decisions should go beyond how data is stored; they should also involve how the data is used. Often you’ll find it profitable to write specific functions to handle specific data operations. (The profits here include increased program reliability, ease of modification, and ease of debugging.) Also when you begin integrating storage properties with operations when you think about a program, you are taking an important step toward the OOP mind-set; that, too, might prove profitable in the future.
Let’s examine a simple case. Suppose you want to use an array to keep track of the dollar values of your real estate. (If necessary, suppose you have real estate.) You have to decide what type to use. Certainly, double is less restrictive in its range than int or long, and it provides enough significant digits to represent the values precisely. Next, you have to decide on the number of array elements. (With dynamic arrays created with new, you can put off that decision, but let’s keep things simple.) Let’s say that you have no more than five properties, so you can use an array of five doubles.
Now consider the possible operations you might want to execute with the real estate array. Two very basic ones are reading values into the array and displaying the array contents. Let’s add one more operation to the list: reassessing the value of the properties. For simplicity, assume that all your properties increase or decrease in value at the same rate. (Remember, this is a book on C++, not on real estate management.) Next, fit a function to each operation and then write the code accordingly. We’ll go through the steps of creating these pieces of a program next. Afterward, we’ll fit them into a complete example.
Filling the Array
Because a function with an array name argument accesses the original array, not a copy, you can use a function call to assign values to array elements. One argument to the function will be the name of the array to be filled. In general, a program might manage more than one person’s investments, hence more than one array, so you don’t want to build the array size into the function. Instead, you pass the array size as a second argument, as in the previous example. Also it’s possible that you might want to quit reading data before filling the array, so you want to build that feature in to the function. Because you might enter fewer than the maximum number of elements, it makes sense to have the function return the actual number of values entered. These considerations suggest the following function prototype:
int fill_array(double ar[], int limit);
The function takes an array name argument and an argument specifying the maximum number of items to be read, and the function returns the actual number of items read. For example, if you use this function with an array of five elements, you pass 5 as the second argument. If you then enter only three values, the function returns 3.
You can use a loop to read successive values into the array, but how can you terminate the loop early? One way is to use a special value to indicate the end of input. Because no property should have a negative value, you can use a negative number to indicate the end of input. Also the function should do something about bad input, such as terminating further input. Given these considerations, you can code the function as follows:
int fill_array(double ar[], int limit)
{
using namespace std;
double temp;
int i;
for (i = 0; i < limit; i++)
{
cout << "Enter value #" << (i + 1) << ": ";
cin >> temp;
if (!cin) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; input process terminated.\n";
break;
}
else if (temp < 0) // signal to terminate
break;
ar[i] = temp;
}
return i;
}