// you’re reading...

C++ Glossary

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 topic in 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
  • 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 (A-1)



Example of (A-1)

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 this, you can code the function as follows (A-2):
    • Note that this code includes a prompt to the user
      • If the user enters a non-negative value, the value is assigned to the array
        • Otherwise, the loop terminates
      • If the user enters only valid values
        • The loop terminates after it reads limit values
    • The last thing the loop does is increment i, so after the loop terminates, i is one greater than the last array index, hence it’s equal to the number of filled elements
      • The function then returns that value



Example of (A-2)

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;
}




Showing the Array and Protecting It with const



Building a function to display the array contents is simple

  • You pass the name of the array and the number of filled elements to the function, which then uses a loop to display each element



But there is another consideration—guaranteeing that the display function doesn’t alter the original array

  • Unless the purpose of a function is to alter data passed to it, you should safeguard it from doing so
    • That protection comes automatically with ordinary arguments because C++ passes them by value, and the function works with a copy
  • But functions that use an array work with the original
    • After all, that’s why the fill_array() function is able to do its job



To keep a function from accidentally altering the contents of an array argument

  • You can use the keyword const when you declare the formal argument (A-3)
    • The declaration states that the pointer ar points to constant data
      • This means that you can’t use ar to change the data
        • That is, you can use a value such as ar[0], but you can’t change that value
  • Note that this doesn’t mean that the original array needs be constant; it just means that you can’t use ar in the show_array() function to change the data
    • Thus, show_array() treats the array as read-only data
  • Suppose you accidentally violate this restriction by doing something like the following in the show_array() function (A-4)
    • In this case, the compiler will put a stop to your wrongful ways
      • Borland C++, for example, gives an error message like this (edited slightly) (A-5)
        • Other compilers may choose to express their displeasure in different words
      • The message reminds you that C++ interprets the declaration const double ar[] to mean const double *ar
        • Thus, the declaration really says that ar points to a constant value
          • We’ll discuss this in detail when we finish with the current example
  • Meanwhile, here is the code for the show_array() function (A-6)



Example of (A-3)

void show_array(const double ar[], int n);



Example of (A-4)

ar[0] += 10;



Example of (A-5)

Cannot modify a const object in function show_array(const double *,int)



Example of (A-6)

void show_array(const double ar[], int n)
{
	using namespace std;
	for (int i = 0; i < n; i++)
	{
		cout << "Property #" << (i + 1) << ": $";
		cout << ar[i] << endl;
	}
}




Modifying the Array



The third operation for the array in this example is multiplying each element by the same revaluation factor

  • You need to pass three arguments to the function:
    • The factor
    • The array
    • And the number of elements
  • No return value is needed, so the function can look like this (A-7)
    • Because this function is supposed to alter the array values, you don’t use const when you declare ar



Example of (A-7)

void revalue(double r, double ar[], int n)
{
	for (int i = 0; i < n; i++)
		ar[i] *= r;
}




Putting the Pieces Together



Now that you’ve defined a data type in terms of how it’s stored (an array) and how it’s used (three functions), you can put together a program that uses the design

  • Because you’ve already built all the array-handling tools
    • You’ve greatly simplified programming main()
  • Most of the remaining programming work consists of having main() call the functions you’ve just developed
  • (A-8) shows the result
    • It places a using directive in just those functions that use the iostream facilities



Example of (A-8)

// arrfun3.cpp -- array functions and const
#include <iostream>
const int Max = 5;
 
// function prototypes
int fill_array(double ar[], int limit);
void show_array(const double ar[], int n); // don’t change data
void revalue(double r, double ar[], int n);
 
int main()
{
	using namespace std;
	double properties[Max];
 
	int size = fill_array(properties, Max);
	show_array(properties, size);
	cout << "Enter reassessment rate: ";
	double factor;
	cin >> factor;
	revalue(factor, properties, size);
	show_array(properties, size);
	cout << "Done.\n";
	return 0;
}
 
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;
}
 
// the following function can use, but not alter,
// the array whose address is ar
void show_array(const double ar[], int n)
{
	using namespace std;
	for (int i = 0; i < n; i++)
	{
		cout << "Property #" << (i + 1) << ": $";
		cout << ar[i] << endl;
	}
}
 
// multiplies each element of ar[] by r
void revalue(double r, double ar[], int n)
{
	for (int i = 0; i < n; i++)
		ar[i] *= r;
}



Here are two sample runs of the program in (A-8):

Output


Output Second



Recall that fill_array() prescribes that input should quit when the user enters five properties or enters a negative number, whichever comes first

  • The first output example illustrates reaching the five-property limit
    • And the second output example illustrates that entering a negative value terminates the input phase




Program Notes



We’ve already discussed the important programming details related to the real estate example, so let’s reflect on the process

  • You began by thinking about the data type and designed appropriate functions to handle the data
    • Then, you assembled these functions into a program
      • This is sometimes called bottom-up programming because the design process moves from the component parts to the whole
        • This approach is well suited to OOP, which concentrates on data representation and manipulation first
  • Traditional procedural programming, on the other hand, leans toward top-down programming
    • In which you develop a modular grand design first and then turn your attention to the details
  • Both methods are useful, and both lead to modular programs


Discussion

No comments for “More Array Function Examples”

Post a comment