Call-by-reference parameters

Call-by-value parameters are not sufficient for all the tasks you might want a function to perform. In C, we used pointers as parameters when we wished to modify the argument in the calling code (we can do the same in C++). However, this method required lots of nasty syntax that had to be just right. // need the * to define the parameters as a pointer void MinMax (int array[], int* minp, int *maxp); int main ( ) { int a[ ] = {2, 3, 5, 12, 7, 6, 1, 42, 9, 3, -1}; int minInt, maxInt; // need the ampersand, &, to pass the address of // minInt and maxInt, but not for the array MinMax (a, &minInt, &maxInt); cout << "Max value is " << maxInt << endl; cout << "Min value is " << minInt << endl; return 0; } void MinMax (int theArray[], int *minp, int* maxp) { // need the * to dereference the pointer *minp = theArray[0]; *maxp = theArray[0]; int i = 0; // more dereferencing in this code while (theArray[i] != -1) { if (theArray[i] > *maxp) *maxp = theArray[i]; if (theArray[i] < *minp) *minp = theArray[i]; } } In C++, there's a better way -- call-by-reference parameters.

A "reference" is an "alias" for another variable which already exists. The most common use of references is "call-by-reference" function paramters

Using call-by-reference parameters, the corresponding argument in a function call must be a variable (not an expression) and this argument variable is substituted for the formal parameter. Any changes to the parameter in the function body changes the argument in the calling code. Think of the call-by-reference parameter as an "alias" or "another name" for the actual argument. Any change to the reference parameter within the function body is actually a change to the argument.

The call-by-reference parameter is indicated using the ampersand, & in both the function prototype and the function definition. No special syntax is needed in the function call. Compare this code with the pointer version above.

// need the ampersand, &, to define the parameter as "call-by-reference" void MinMax (int array[], int& min, int& max); int main ( ) { int a[ ] = {2, 3, 5, 12, 7, 6, 1, 42, 9, 3, -1}; int minInt, maxInt; MinMax (a, minInt, maxInt); cout << "Max value is " << maxInt << endl; cout << "Min value is " << minInt << endl; return 0; } // no deferencing means no *s in our code void MinMax (int theArray[], int& min, int& max) { min = theArray[0]; max = theArray[0]; int i = 0; while (theArray[i] != -1) { if (theArray[i] > max) max = theArray[i]; if (theArray[i] < min) min = theArray[i]; i++; } }

What about arrays?

When we pass an array to a function, we pass the name of the array as in the following code. void Initialize (int array[ ], int size, int value); int main ( ) { int scores[40]; int ages [100]; Initialize( scores, 40, -1); Initialize( ages, 100, 0); // code to use these arrays return 0; } void Intialize (int a[], int size, int value) { for (int i = 0; i < size; i++) a[i] = value; }
Is this pass by value?
Is this pass by reference?
Is this some other mechanism?

Exercise

Self-test exercise, page 143 (slightly modified) illustrates that a function may have both call-by-value and call-by-reference parameters.

What is the output from the following code? This is a typical exam question.

#include <iostream> using namespace std; void FigureMeOut(int& x, int y, int& z); int main ( ) { int a = 10, b = 20, c = 30; FigureMeOut(a, b, c); cout << a << " " << b << " " << c << endl; return 0; } void FigureMeOut( int& x, int y, int& z) { cout << x << " " << y << " " << z << endl; x = 1; y = 2; z = 3; cout << x << " " << y << " " << z << endl; }


Last Modified: Monday, 28-Aug-2006 10:16:00 EDT