EECS 258 - Laboratory Assignment 7

The objective of this laboratory assignment is to build upon your knowledge of functions and introduce some new concepts. We will focus on passing parameters in different ways, recursion and also introduce you to the concept of function overloading. This lab assignment has the following steps:

  1. Using Recursion
  2. In a previous lab we used an iterative function to calculate the factorial of a number. N factorial is often defined in terms of N-1 factorial, so it is easy to use recursion to implement this function. Review the function below for a recursive implementation of this function.

    int factorial(int value)
    {
       // Print the current value so you can see how the function is progressing
       cout << "Current Value: " << value << endl;
    
       // Base or Terminating Condition
       if( value == 1 ) 
       {
          cout << "Base Case" << endl;
          return 1;
       }
    
       // Recursive Call
       int returnValue =  value * factorial( value - 1 );
    
       // More tracing calls
       cout << "Returning Value: " << returnValue << endl;
       return returnValue;
    }

    Write a small main program and a set of automated unit tests using assert() like we did in lab last week to call this factorial function. Compile and run your program. Can you find a way to "break" the function with your tests? What inputs cause problems? Describe your findings below.

    Now see if you can find a way to improve the factorial function to prevent the problems you saw above. Compile and test your new version, and copy your revised program below.

  3. Pass by Reference
  4. View the program below carefully. See if you can trace the programs execution to determine what the value of MyValue is going to be in each of the assert() statements.

    // Author: Eric Akers
    // Date: Fall 2003  //tests added by David Janzen Fall 2005
    
    #include <iostream>
    using namespace std;
    void doMagic( int & value );
    void anotherFunction( int value );
    
    void doMagic(int & value)
    {
       value *= 2;
    }
    
    void anotherFunction(int value)
    {
       value ++;
    }
    
    int main( int argc, char * argv[] )
    {
       int myValue = 5;
       doMagic( myValue );
       assert(myValue == ?);
       anotherFunction( myValue );
       assert(myValue == ?);
       cout << "No errors encountered" << endl
    }

    Replace the ?'s in the assert() statments with your expectations. Compile and run this program. Did the tests all pass? If not, can you figure out what is happening to cause the problem? If not, ask your classmate or TA.

  5. Function Overloading
  6. Look at the following program below.

    //Author: Abishek Shivadas
    //Date:Fall 2003  //tests added by David Janzen Fall 2005
    
    #include 
    #include 
    using namespace std;
    
    float volume(float radius);
    float volume(float radius, float height);
    void run_tests();
    
    int main()
    {
       run_tests();
    }
    
    void run_tests()
    {
       float volume_solid = 0.0;
       { //test 1
         volume_solid = volume(1.5);
         assert(fabs(volume_solid - 14.137) < .001);
       }
       { //test 2
         volume_solid = volume(1.5, 5.0);
         assert(fabs(volume_solid - 35.342) < .001);
       }
    }
    
    float volume(float radius)
    {
       return 4.0 * 3.14159 * radius * radius * radius / 3.0;
    }
    
    float volume(float radius, float height)
    {
       return 3.14159 * radius * radius * height;
    }
    

    Copy the program into your xemacs editor, name it Function_overloading.cpp. Notice in the two tests that in order to see if two floating point values are the same, we use fabs() (floating point absolute value function) to see if they are really close. Compile and run the program and check to see if the tests pass. Notice that despite the fact that two functions have the same name they perform different functions. In C++, two or more functions can share the same name as long as their parameter declarations are different. In this situation, the functions that share the same name are said to be overloaded, and the process is said to be function overloading.

    Write two more tests, one for each of the two functions with different arguments. Run the program to see if your tests pass.

  7. Write a function
  8. Use a test-first approach and function overloading to implement several "abs" functions. Remember that a test-first approach involves writing one unit-test, then writing just enough code to make the test pass. Once the test passes, write another test and improve or add code as necessary. Keep repeating this process until you have written all your "abs" functions and you are happy that they work correctly. Try a variety of input data types and test your functions with automated unit tests as above. When finished, cut and paste your program below.

    Run the program and copy the output below.

  9. Submit Your Work
  10. This lab assignment will be submitted electronically to the TAs once you fill in the fields below and click on the "submit" button. You do NOT need to print a copy of this document to hand in.

    Your full name:
    Your kuid number:

    If you are ready to send the lab to the grader, click on the submit button. Otherwise, go back and fill in any missing pieces and then submit your work.