Suppose you pass either the name of an array or a pointer to an array to a function, as is shown in Program 1.
Program 1. Passing an array and a pointer to a function.
#include <iostream> using namespace std; // If a function does not have a return type (that is, it does not return a value), // this is indicated by replacing the return type with the keyword 'void' void f( int * ptr ) { cout << "The address assigned to the argument ptr is " << ptr << endl; ptr[0] = 582; return; } int main() { int array01[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; cout << "The address stored in 'array01' is " << array01 << endl; f( array01 ); int * array02 = new int[10]; cout << "The address stored in 'array02' is " << array02 << endl; f( array02 ); delete [] array02; return 0; } |
In both cases, the address of the first element of the array is changed. This allows us to define functions which could, for example, initialize arrays, as is shown in Program 2. One weakness with using arrays, though, is that there is no way of determining how large the array is, and therefore, we must pass that information to the function.
Program 2. Passing an array and a pointer to a function.
#include <iostream> using namespace std; void initializing( int * ptr, int n ) { for ( int i = 0; i < n; ++i ) { ptr[i] = 0; } return; } int main() { int array_size = 32; int * array = new int[array_size]; initializing( array, array_size ); delete [] array; return 0; } |
The flow of Program 2 is shown in Figure 1.
Figure 1. The flow of Program 2.
Notice that in Figure 1, when I refer to ptr[i], I don't use a pointer to point into the the array, because when I assign ptr[i] = 0;, I'm directly modifying the entry: ptr is a pointer, while ptr[i] is an integer in memory.
When we are passing a pointer to an array, we are passing by value, and therefore the actual value of the pointer cannot be changed. Examine Program 3 and indicate what is wrong. There are two problems with pointers which appear here.
Program 3. Passing an array and a pointer to a function.
#include <iostream> using namespace std; void resize( int *ptr, int n ) { delete [] ptr; ptr = new int[n]; return; } int main() { int * array = new int[10]; cout << "The address stored in 'array' is " << array << endl; resize( array, 1000 ); cout << "The address stored in 'array' is still " << array << endl; delete [] array; return 0; } |
Perhaps, at an initial glance, it looks reasonable: we want to resize the array, so we call resize which deallocates the memory allocated for the current array and then assigns ptr a new array of the specified size.
Unfortunately, this has two problems:
Thus, we can pass an array to a function and have the function change the values of the array and the changes will take place in the original memory allocated to the array by new[]. We must also explicitly pass the size of the array. As you may guess, this is a problem, and we will soon see how we can fix this with classes.
1. Write a function which finds the maximum entry in an array of integers. If the array size is zero, return 0.
2. Modify your function you wrote in Question 1 to find the maximum entry in an array of doubles. Note that there isn't much difference?
3. Write a function void reverse( int * ) which reverses the entries of an array. If the size is zero or one, nothing should be done.