## Lecture Goals

• To be able to program functions and procedures
• To become familiar with the concept of parameter passing
• To recognize when to use value and reference passing
• To appreciate the importance of function comments

## Functions as Black Boxes

• A function is a piece of code assigned to a name. We have used a number of functions that were provided by the C++ system library.
• sqrt(x) - computes the square root of a floating point number x
• getline(cin, s) - reads a line from the cin stream
• Functions can be thought of as black boxes - you don't need to know the internals of the code.
• Example:
`int main(){ cout << "Enter a positive number: ";  double x;  cin >> x;  x = sqrt(x); // sqrt is running  cout << "The result is " << x << "\n";  return 0;}`
• The execution of main() is temporarily suspended while the function sqrt is running.
• The sqrt function becomes active and computes the output or return value - using some method that will yield the concrete result.
• The return value is transferred back to main, which resume the computation using the return value.
• Many functions have input values or parameters that are transferred or passed into the function.
• The x in y = sqrt(x);
• Both the x and the y in z = pow(x,y);
• Could be an expression as in sqrt(b * b - 4 * a * c);
 function parameter sqrt(x) variable sqrt(2.5) constant sqrt(x+1.02) expression
 function number of parameters sqrt(x) 1 pow(x,y) 2 harry.get_salary() 0

 member-function implicit parameter implicit parameter type harry.get_salary() harry Employee t.add_seconds(10) t Time s.substr(0,num) s string
• Many functions have output or return values. Each function returns a value of a particular type.
 function return value sqrt(x) double type c.substr(0, num) string type t.get_seconds() int type getline(cin,s) no return value
• Each function takes values of particular types.
• You cannot compute sqrt("Harry");
• You cannot assign string s = sqrt(5.5); ?????????????
 function requirements for parameters fabs(w) the parameter w must be double type, constant or variable t.second_from(t1) the parameter t1 must be an object from Time class (constant or variable) getline(cin,s) the first parameter must be cin, the second parameter must be a variable of  the type string

## Writing Functions (Function Definition)

• Let us compute the value of a saving account with an initial balance of \$1000 after 10 years with the interest rate of p percent (compound interest).
• To create a function, we must supply its return type, name, and a list of parameters (types and  names).
`double future_value(double p)`
• For the duration of the function, the parameter is stored in a parameter variable (in this example, p).
• The body of the function is delimited by braces (just like main()):
`double future_value(double p){   . . . }`
• Code is included to perform the computation. The result is returned to the caller function.
`double future_value(double p){  double b = 1000 * pow(1 + p / 100, 10);   return b;}`

## Writing Functions

Syntax 5.1: Function Definition

`return_type function_name(parameter1, ..., parametern){   statements}`
 Example: `double abs(double x){ if (x >= 0) return x; else return -x;}` Purpose: Define a functions and supply its implementation.

## Writing Functions (Hard Wired Values)

• The future_value function is flawed because the starting amount of the investment and the number of years are hard-wired.
• Hard-wiring prevents reuse of functions:
• Computing the balance after 20 years.
• Computing the balance with a different initial balance.
• We avoid hard-wiring values into functions by passing them in as additional parameters.
• Functions are more valuable when they are reusable.
`double future_value(double initial_balance, double p, int n){  double b = initial_balance * pow(1 + p / 100, n);   return b;}`
`double balance = future_value(1000, rate, 10);`

• We must comment every function, even if it seems silly.
• There is no universal standard for comment layout, but our textbook uses the javadoc style.
• An @param entry explaining each parameter
• An @return entry describing the return value
• Comments do not explain the implementation, but the idea.
• Writing comments first, before writing the function code, to test your understanding of what you need to program.
` /**   Computes the value of an investment with compound interest.   @param initial_balance - the initial value of the investment   @param p the interest rate per period in percent   @param n the number of periods the investment is held   @return the balance after n periods*/double future_value(double initial_balance, double p, int n){  double b = initial_balance * pow(1 + p / 100, n);   return b;}`

## Return Values

• When the return statement is processed, the function exits immediately. We put the exceptional cases at the beginning.
`double future_value(double initial_balance, double p, int n){  if (n < 0) return 0;   if (p < 0) return 0;   double b = initial_balance * pow(1 + p / 100, n);   return b;}`
• It is important that every branch of a function return a value.
`double future_value(double initial_balance, double p, int n){  if (p >= 0)       return initial_balance * pow(1 + p / 100, n);   /* Error */}`
• The last statement of every function ought to be a return statement.
• Functions that returns a truth (boolean) value is called a predicate.
• The function approx_equal(x, y) tests whether two floating point numbers x and y are approximately equal (approximation relative error).
`bool approx_equal(double x, double y){  const double EPSILON = 1E-14;   if (x == 0) return fabs(y) <= EPSILON;   if (y == 0) return fabs(x) <= EPSILON;   return fabs(x - y) / max(fabs(x), fabs(y)) <= EPSILON;}`

Syntax 5.3: return statement

` return expression;`
 Example: ` return pow(1 + p / 100, n);` Purpose: Exit a function, returning the value of the expression as the function result.

## Parameters

• When a function starts, its parameter variables are initialized with the expressions in the function call.
`b = future_value(total / 2, rate, year2 - year1);`
• [Picture]
• It is entirely legal to modify the values of the parameter variables later.
`double future_value(double initial_balance, double p, int n){  p = 1 + p / 100;   double b = initial_balance * pow(p, n);   return b;}`
• Many programmers consider this practice bad style.

## Side Effects

• An externally observable effect of a function is called a side effect.
• Displaying characters on the screen (including error messages).
• Updating variables outside the functions.
• Terminating the program.
• A function should leave no trace of its existence except for returning a value.
• Functions that print values become worthless in certain situations.
• Graphics programs that have no output streams.
• Programs where the user's language is not English.
• Programs that don't want to print the value!
• Ideally, a function computes a single value and has no other side effect.

## Procedures

• A function without a return value is called a procedure.
`print_time(now);`
• The missing return value is indicated by the keyword void.
`void print_time(Time t){  cout << t.get_hours() << ":";   if (t.get_minutes() < 10) cout << "0";   cout << t.get_minutes() << ":";   if (t.get_seconds() < 10) cout << "0";   cout << t.get_seconds();}`
• Since a procedure does not have a return value, it must have a side effect.
• Ideally, a procedure has only one side effect, such as  setting variables or  performing an output, and  returns no value.

## Reference Parameters

• The parameter variables we have looked at so far are called value parameters.
• Value parameters are separate variables from the ones in main() (or another calling function).
• Modification of value parameters does not affect the original value.
• A reference parameter does not create a new variable, but refer to an existing variable.
• Any change in a reference parameter is actually a change in the variable to which it refers.
• Reference parameters are indicated using an & between the parameter's type and name.
`void raise_salary(Employee& e, double by){  double new_salary = e.get_salary() * ( 1 + by / 100);   e.set_salary(new_salary);}`

Syntax 5.4: Reference Parameters

` type_name& parameter_name`
 Example: ` Employee& e int& result` Purpose: Define a parameter that is bound to a variable in the function call, to allow the function to modify that variable.

## Reference Parameters (raisesal.cpp)

Syntax 5.5: Constant Reference Parameters

` const type_name& parameter_name`
 Example: ` const Employee& e` Purpose: Define a parameter that is bound to a variable in the function call, to avoid the cost of copying the variable into the parameter variable.
• Reference parameters are more efficient than value parameters because they do not make copies of the parameters.
• Passing variables by constant reference improves performance, but prevents the function from changing the value of the parameter.
• Objects make good constant reference parameters because they tend to have several attributes that need to be copied. Passing numbers by constant reference is generally not worth the effort.