There are many situations in which it's natural to ask for
- functions that have arrays as arguments, or
- functions that return arrays, or
- both!
This class is just going to look at functions that
operate on arrays, and the few new concepts that arise with them.
In reality, there's nothing new at all! It's just that the
consequences of the following fact:
It is the pointers to the arrays that get manipulated in our programs,
not the arrays themselves.
Computing averages with two function calls
We'll look at this from the perspective of our simple program for
computing averages. Here's that program.
Essentially we'd like the bulk of the program to consist of two function
calls:
- We need to call function
readints() which creates an array A and read N integers from input
int* A = readints(N, "numbers.txt");
- Then we need to call function
sum() and use it to compute the average:
double average = sum(A,N) / double(N);
In defining these two functions, we'll see how arrays get passed in and out of
functions.
Function readints(): How to return arrays
Prototype
The prototype of the first function is as follows:
int* readints(int N, string filename);
This function should return an array of N
ints, populated with values read in from filename.
Definition
The basics of the function should be fairly straightforward. The important
thing is to understand what happens! So, here's the function definition:
int* readints(int N, string filename) {
// Create the array
int* B = new int[N];
// Open the file
ifstream fin(filename);
// Read values into the array
for( int i = 0; i < N; i++ )
fin >> B[i];
fin.close();
// Return pointer to array
return B;
}
Pictorial depiction
And here's a pictorial depiction of what goes on.
Note:
- What gets returned from the function is a pointer, not an
actual array.
- The array of
ints still exists when the function call
returns, because memory allocated with new has no scope or
lifetime.
In summary:
- A function can create arrays with
new.
- Then it can return the arrays by returning a pointer to the block of memory allocated by the call to
new.
Function sum(): How arrays are passed (and modified)
Prototype
Arrays can be passed into functions by passing a pointer to the block of memory
that comprises the array. So, the prototype of the function sum() is as follows:
int sum(int* A, int N);
Note about the pointer A:
- As far as pass-by-value is concerned, the pointer is what
gets passed, so your function gets a copy of the pointer.
- However, the copy points to the same array in memory, so when
you modify the array in the function you modify the same array you have
back in the calling function.
Note about N:
- Notice that when we pass an array to a function
we always have to pass the length of the array along with it, otherwise we have
no idea how many elements are in the array pointed to by
A.
Definition
So, getting back to our example, we need to implement the function int
sum(int* A, int N);. Hopefully the definition of this function looks straightforward.
int sum(int* A, int N)
{
int total = 0;
for(int i = 0; i < N; i++)
total = total + A[i];
return total;
}
Pictorial depiction
The question is this: What really goes on when we run it? Hopefully the
pictures below, which illustrate what goes on in a sample run of the above
function, will make clear to you what really goes on when arrays are passed to
functions.
In summary,
- If you modify any element within an array passed to a function, you're
actually modifying the same array that the caller of the function is looking
at.
exit(1)
Q: If you want to exit the program, and you're not in
main(), you
can't just do "return 0;". Why?
A: Because it would only return from the current function.
So there is a function "exit" that you can call to exit from anywhere. In
particular, consider the following statement:
exit(0); // requires #include <cstdlib>
It will exit the program, no matter where you are.
Note
- You must #include <cstdlib> to use it.
- The function exit() takes an int argument which is the value the program
will return to the operating system.
Problems
- A
contains predicate.
Write function
bool contains(string *A, int N, string s);
that tells you whether or not the string s is
contained in the array A.
- A
getarray function.
Write a function
int* getarray(int N, int x);
that allocates and returns a pointer to an array of
N ints, each initialized to the
value x.
- A
shiftleft function.
Write a function
double shiftleft(double *A, int N, double x);
that shifts all the elements in array A to the left by 1
position, puts the value x in the rightmost
position in the array, and returns the value that had
previously been in the leftmost position.
-
An average function for arrays of doubles.