Activity 4-2 - Functions that "Return" More than One Value
                       (Call-by-reference)


"A function cannot return more than one value using the return statement, but can use the call-by-reference to update many values"

In Lab3, we saw several examples of functions that returned one value.  Sometimes we may want to return more than one value from a function.  The return statement can be used to return one value only.   Instead, we will use the call-by-reference mechanism to update the arguments that are passed to a function.  Following is an example in which we have used this method to return a value to the main without using the return statement.  A call-by-reference parameter is marked by an & so that the compiler will distinguish it from other parameters.  To visualize this better think about the program that you wrote to solve a quadratic equation. Suppose, you wanted to call a function that would ask users to input the coefficients, a, b, and c.  You could have called a function as:

get_a_b_c(a,b,c);

Now, the declaration of this function will look like this:

void get_a_b_c(float& a, float& b, float& c);

Let's look at a program and see how this works.  In the following example, the get_input function obtains two values from the user, then returns (brings) them to the main function. In a sense, get_input "returns" two values.  This cannot be done with the return statement because the return statement returns exactly one value. If a function must produce more than one output value, then we must use call-by-reference parameters (one for each output value.)

Simple Example (please pay attention to the font color):

// P52.cpp This function illustrates how a function can return two values
#include<iostream>
using namespace std;

// This is the declaration for the function that reads the values for i and j
void get_input(int& i, int& j);

// This is the declaration for the function that adds 10 to i and 20 to j
void process(int& i, int j);

int main()
{
     int i, j;

     get_input(i , j);

     cout << "I am about to call function process, i = " << i << " j = " << j << endl;

     process(i,j);

     cout << "I just came back from function Process, i = " << i << " j = " << j << endl;

    return 0;
}

void get_input(int& i, int& j)
{
       cout << "Please enter two values for i and j separated by a single space, then press <Enter>:";
       cin >> i >> j;
       cout << endl;
       return;   // a void function, returns nothing
}

void process(int& i, int j)
{
      i = i +10;
      j = j +20;
      cout << "Inside function Process \n";
     cout << "I added 10 to i, and 20 to j, i = " << i << " and j = " << j << "\n";
}

Exercise 4.2
Cut and paste this program into a program called ex42.cpp, compile then run it.  Which one of the values, i or j, got updated upon return from the function process?
What would you do to get both values updated upon your return to the main? make the necessary changes and run the program to make sure it works correctly.

Using & we access the address of a variable,  thus, when we make a change in the value in a function, the change will be seen in the calling function as well, i.e., the
value gets updated.

It is worth noting that one may think that the use of & in all function calls sounds like a good idea.  The argument one may make is that "it is safe to use it all the time, so when the value needs to get updated, it is already there."  However, passing a variable using call-by-reference may result in unwanted and undesirable changes in the value, which may cause the program to produce incorrect results.  As a rule, you need to keep all parameters as call-by-value and only change those to call-by-reference that you need to get updated.

Exercise 4.3
In order to swap the value of two variables, one can use the following procedure:

temp = variable1;
variable1 = variable2;
variable2 = temp;

Write a C++ program that asks the user to input two integer values, then calls a void function swap to swap the values for the first and second variable.  Please display the two variables before you call swap and after you call that function.