User defined functions

We assume for your prior programming experience in CMSC 201 that you are familiar with writing functions. This includes
  1. Functions that return a value
  2. Functions that do not return a value (void functions)
  3. Functions with parameters (including structs and arrays)
  4. Functions with no parameters
  5. Functions that call other functions
Functions provide a form of "procedural abstraction". The user of a function need not know how a function works in order to use it. The term abstraction conveys the idea that you are hiding the details of the code contained in the function. This is often referred to as treating the function like a black box.

Documentation about what a function does is contained in the function header comment which is found the header file that contains the function's prototype. In this course, we have a requirement that all function header comments contain pre- and post-conditions. This information assists the user in understand what the function does. Thinking about pre- and post-conditions are important when designing your functions.

Pre-Conditions and Post-Conditions

A pre-condition is a statement of what the function assumes to be true when it is called. The function should not be called and cannot be expected to perform correctly unless all pre-conditions are met. Pre-conditions always include some statement about the state of the arguments to the function.

A post-condition is a statement that describes the effect of the function (assuming all preconditions are met). For functions that return a value, the post-condition will always describe the value returned. For functions that change the value of some argument(s), the post-condition will describe the changes.

Examples from text page 115.
Right Wrong
//------------------------------------------------------ // Function: ShowInterest // PreCondition: // balance is a nonnegative savings account balance // rate is the interest rate expressed as a percent // such as 5 for 5% // PostCondition: // the amount of interest for the given balance at the // given rate is displayed to cout. // if the parameters are invalid, "No Interest" is displayed //------------------------------------------------------- void ShowInterest( double balance, double rate ) { if (balance >= 0 && rate >=0) { // code to calculate and display interest } else { cout << "No Interest\n"; } } //------------------------------------------------------ // Function: ShowInterest // PreCondition: // passes in the balance and rate <-------- WRONG // PostCondition: // the amount of interest for the given balance at the // given rate is displayed to cout <-------- OK // // // //------------------------------------------------------- void ShowInterest( double balance, double rate ) { // code to calculate and display interest }
//------------------------------------------------------- // Function: Area // PreCondition: // radius is positve // PostCondition: // returns the area of a circle with given radius // returns 0.0 if radius is invalid //------------------------------------------------------- double Area( double radius ) { const double PI = 3.14159; if ( radius > 0 ) return 2 * PI * radius * radius; else return 0.0; } //------------------------------------------------------- // Function: Area // PreCondition: // passes in the double radius <-------- WRONG // PostCondition: // returns the double area <-------- OK, not great // //------------------------------------------------------- double Area( double radius ) { const double PI = 3.14159; return 2 * PI * radius * radius; }
What do we do if the pre-conditions are not met? There are a couple of basic methods for handling pre-conditions which are not met. All pre-conditions which are not met must be handled in some manner.
  1. Handle the invalid pre-condition if possible as in the examples above
  2. Return a status (via return value or reference parameter) indicating that an error occurred.
  3. Alert the caller by throwing an exception (later this semester)
  4. As a last resort, abort the program execution using the assert() or exit( ) function
Of these, alerting the caller is preferred. However, until we learn proper exception handling, we are stuck with the other options. As the function designer, you must choose which method to use.

Unless exiting via exit( ), or your function's purpose is to input data,
DO NOT output a message to the user and/or prompt the user for new input.

Exercises

Write the function header comment (including pre- and post-conditions) and function prototype for the following functions. Then write the code.
  1. A function named FindMax that searches an array of integers and returns the index of the first occurrence of the maximum value in the array.
  2. A function named PrintGreeting that outputs a user-supplied message to the standard output.
  3. A function named FindSmallest that returns the smallest of three integers.
  4. A function named Volume that returns the volume of a sphere with a given radius. The formula for the volume of a sphere is given on page 121 of the text.
  5. A function named Speed that returns the speed of a vehicle in miles per hour, given the distance traveled and the time to travel that distance.


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