CS 150 - Intro to Programming - Fall 2001
Lab Exercise 8

Topics:

Part 1 - Reference Parameters

A. In this part of the lab we will implement a function that uses reference parameters.One of the main uses for reference parameters is to return a value from a function. In the simplest case where a function return only one value, this can be accomplished either by a function that returns a value or we can add an extra reference parameter to the parameter list and return the value that way. In the case where we want to return (or change) more than one value ( swap(x.y) for example), our only choice is to use reference parameters. To illustrate this, we will first implement a function that returns a value - then we will modify the function to have a return value of type void and instead, return the value using a reference parameter. Write two functions, called valHypotenuse and refHypotenuse. The prototypes for the two functions are:

double valHypotenuse(double a, double b);          //function returning a value
void refHypotenuse(double a, double b, double& x); //function using reference parameter to return value

The purpose of both of the functions is the same - to compute the hypotenuse of a triangle, given the length of the other two sides. The first version is a value returning function that "returns" the answer to the calling statement (x = valHypotenuse(a,b);) , whereas the second version returns the answer in the reference parameter x (refHypotenuse(a,b,x);). Write a C++ program (yourLastNameLab8Part1a.cpp) that implements each function as given above and write a main function to test them both. Call each function with least three test cases. A test case should look something like this:

//assume all variables have been declared
//test case one
x = 0;
a = 3;
b = 4;
x = valHypotenuse(a,b);
cout << "Call by value: a = " << a << " b = " << b << " hypotenuse = " << x << endl;
//could also call like this since it returns a value
//cout << "Call by value: a = " << a << " b = " << b << " hypotenuse = " << valHypotenuse(a,b) << endl;

x = 0; //reset x to ensure next call really changes the value
refHypotenuse(a,b,x); //note call on single line - no return value - also do not use & in function call
cout << "Call by reference: a = " << a << " b = " << b << " hypotenuse = " << x << endl;
//test case two
//test case three

(Note: you do not need to prompt the user for input - simply assign values to the variables and call the function). Use the same set of values for both function call and ensure they are each returning the same answers. Finally enable the debugger and use it to trace the execution of the program - note how the function changes the value of the reference parameter.

B. Consider a function called rightShift which accepts four(4) integer parameters, and shifts their values to the right by one - the last value "wraps around" to become the first value. For example (4, 5, 6, 7) becomes (7, 4, 5, 6) - (13, 67, 45, 1) becomes (1, 13, 67, 45). In this problem, our only option is to use reference parameters since we need to change the value of four variables.

The function to implement rightShift should have exactly four parameters, and will not return a value. An example call to rightShift would be:

w=4; x=5; y=6; z=7;
rightShift(w, x, y, z);

after which the values of w, x, y, and z would be shifted as described above (w=7, x=4, y=5, z=6).
(Note: you do not need to prompt the user for input - simply assign values to the variables and call the function).

Write a C++ program (yourLastNameLab8Part1b.cpp) that implements and tests the function rightShift. You will need a main, a function prototype and the function body.

IMPORTANT -- Follow the design process outlined in lab 7.



Part 2 - Function overloading

Function overloading allows us to use the same name for two or more different functions as long as the number or type of parameters is different.

A. Convert the program from lab7-Part3 so that the largest and smallest function works for floating point numbers as well as integers (yourLastNameLab8Part2a.cpp). This means that you will have to overload the functions - i.e. for each function (smallest, largest), you will have two functions with the same name, the function prototypes will have the same name but the type of the parameters will be different. You will also have two function bodies that differ in the type of parameters as well as their implementation. Write a main function (driver) that will test your functions - you should include before and after print statements (as shown above) to show the result of each function call. Your main should follow the model shown below for calls to your functions: Run the program and verify that it is working. Enable the debugger and run the program again - verify that the correct function get called.

int a, b, c, d;
double w, x, y, z;

//assign values for a, b, c
//print before message for min
d = min(a,b,c);
//print after message for min

//assign values for a, b, c
//print after message for max
d = max(a,b,c);
//print after message for max

//assign values for x, y, z
//print before message for min
z = min(w,x,y)
//print after message for min

//assign values for x, y, z
//print before message for max
z = max(w,x,y)
//print after message for max

Next consider what happens if I mix data types when calling largest or smallest?? For example assume a, b and c are ints and x, y and z are doubles, what happens when we execute this z = largest(a,x,y) or c = smallest(x,a,b); Try 2 calls similar to these and note the results by adding comments to the source code stating your conclusion about the call and what happens - enable the debugger for clues. Comment out your tests before going on.

B. Create a C++ program (yourLastNameLab8Part2b.cpp) and add a function called averager, which accepts two integer parameters and returns their average as an integer value. Also add an appropriate main() to test averager and ensure that it is working correctly.




What to turn in

Remember to: