## Chapter 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
• To be able to determine the scope of variables
• To minimize the use of side effects and global variables
• To develop strategies for decomposing complex tasks into simpler ones
• To document the responsibilities of functions and their callers with preconditions

## Functions as Black Boxes

• A function is a piece of code assigned to a name.
• sqrt() - computes the square root of a floating point number
• getline() - reads a line from the stream
• Functions can be thought of as black boxes - you don't need to know the internals of the code.
• 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);
• Many functions have output or return values.
• The y in y = sqrt(x);
• Each function takes values of particular types. Each function returns a value of a particular type.
• You cannot compute sqrt("Harry");
• You cannot assign string s = sqrt(5.5);

## Writing Functions (Function Definition)

Let us compute the value of a saving account with an initial balance of \$1,000 after 10 years with the interest rate of p percent.
• To create a function, we must supply its name, return type, 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)

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 in futval.cpp 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 this book 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 pre 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 (Syntax 5.2: return Statement)

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.

## Return Values

• When the return statement is processed, the function exits immediately.
`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 */}`
• Functions that returns a truth value is called a predicate.
`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;}`

## 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);`
• 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. Commonly, procedures return a status 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);}`

## Reference Parameters (Syntax 5.4: Reference Parameters)

Syntax 5.4 : Reference Parameters

` type_name& parameter_name`
 Example: ` Employee& eint& 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 (Syntax 5.5: Constant Reference Parameters)

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.

## Variable Scope and Global Variables (Variable Scope)

• You can have variables with the same name in different functions.
• The part within a program in which a variable is visible is known as the scope of the variable.
• The scope of a variable extends from its definition to the end of the block in which it was defined.
• Example:
`double future_value(double initial_balance, double p, int n){  double r = initial_balance * pow(1 + p / 100, n);   return r;}int main(){  cout << "Please enter the interest rate in percent: ";   double r;   cin >> r;   double balance = future_value(10000, r, 10);   cout << "After 10 years the balance is" << balance      << "\n";   return 0;}`
• Global variables are variables that are defined outside functions.
• A global variable is visible to all functions that are defined after it.
• Sometimes global variables cannot be avoided (cin, cout, and cwin), but you should make every effort to avoid global variables in your program.

## Stepwise Refinement

• One of the most powerful strategies for problem solving is the process of stepwise refinement.
• To solve a difficult task, break it down into simpler tasks; then keep breaking down the simpler tasks into even simpler ones, until you are left with tasks that you know how to solve.
• How do you get coffee?
• Ask someone else to do it.
• Make coffee.
• OK, how do you make coffee?
• Make instant coffee.
• Brew Coffee.
• How do you make instant coffee?
• Start by boiling water.
• Etc.

## From Pseudocode to Code

Write a function that turns a number into a text string, for example 273 turns into "two hundred seventy four".
• Before starting to program, we need to have a plan.
• Any time you need something more than once, it's a good idea to turn that into a function..
• Rather than writing the entire function, begin by writing the comments.
• Writing the function
`/**   Turns a number into its English name.   @param n a positive integer < 1,000,000   @return the name of n (e.g. "two hundred seventy four"*/string int_name(int n);`
• Break the problem into sub-tasks and design subprograms.
`/**   Turns a digit into its English name   @param n an integer between 1 and 9   @return the name of n ("one" ... "nine")*/string digit_name(int n);/**   Turns a number between 10 and 19 into its English name.   @param n an integer between 10 and 19   @return the name of n ("ten"..."nineteen")*/string teen_name(int n);/**   Gives the English name of a multiple of 10   @param n an integer between 2 and 9   @return the name of 10 * n ("twenty"..."ninety")*/string tens_name(int n);`
• What is missing?
• For hundreds, we show the digit name then write "hundred".
• For 100 - 999, we can put calls to functions above together to write number.
• For numbers over 1,000, we call functions above to write the number of thousands, print "thousand", then call the above functions again to write the rest of the number.
• When algorithms are complicated, we first write them as pseudocode.
• Pseudocode is somewhere between C++ and English.
`string int_name(int n){ int c = n; /* the part that needs to be converted */  string r; /* the return value */  if (c >= 1000)  {   r = name of thousands in c + "thousand"      remove thousands from c  }  if (c >= 100)  {   r = r + name of hundreds in c + "hundreds"      remove hundreds from c  }  if (c >= 20)  {   r = r + name of tens in c      remove tens from c  }  if (c >= 10)  {   r = r + name of c      c = 0  }  if (c > 0)      r = r + name of c;  return r;}`

## From Pseudocode to Code (intname.cpp)

• Pseudocode can be easier to understand than a verbal description.
• It's best not to muddy the pseudocode with minor details.
• The pseudocode did not take into account spaces between the words.
• Note that the helper functions needed to be declared before the int_name function.
• The int_name function calls itself (called recursion):
`if (c >= 1000){  r = int_name(c / 1000) + " thousand";   c = c % 1000;}`

## Walkthroughs

• Before entrusting a subprogram to a computer, it is a good idea to put it through a dry run or walkthourgh.
• Take out an index card and write down the name of the function you want to study.
• Write down the names of the function variables in a table, since you will update them as you walk through the code.
 int_name(n = 416) c r 416 ""
• When your function calls another function, you can either start another card, or assume that it performs correctly.
 int_name(n = 416) c r 416 ""

 digit_name(n = 4) Returns "four"
• As the function progresses, update the variables by crossing out old values and writing down the new ones.

 int_name(n = 416) c r 416 "" 16 "four hundred"

 int_name(n = 416) c r 416 "" 16 "four hundred" 0 "four hundred sixteen"

## Preconditions

• What should a function do when called with an inappropriate value (e.g. sqrt(-1))?
• A function can fail safely. For example, the digit_name function simply returns an empty string when it is called with an unexpected value.
• A function can terminate. Many functions in the cmath library will terminate if given an illegal value.
• The most brutal method is to print a message and terminate the entire program.
• C++ has a very sophisticated mechanism called an exception.
• Whenever possible, it is desirable to avoid termination of the program (although that is hard).
• We will discuss using assert().

## Preconditions (Syntax 5.6 : Assertions)

Syntax 5.6 : Assertions

` assert(expression);`
 Example: ` assert(x >= 0);` Purpose: If the expression is true, do nothing. If the expression is false, terminate the program, displaying the file name, line number, and expression.

## Preconditions

• To use assert() you must #include<cassert>.
• assert() is really a macro - a special instruction to the compiler that inserts complex code into the program.
` double future_value(double initial_balance, double p, int n){  assert(p >= 0);   assert(n >= 0);   return initial_balance * pow(1 + p / 100, n);}`
• As a programmer, you must fully document any preconditions that the function must meet. That is, the legal values for function input.
`/**   Computes the value of an investment with compound interest.   @param initial_balance the initial value of the investment   @param p the interest rate in percent; must be >= 0   @param n the number of periods the investment is held; must be >= 0   @return the balance after n periods*/`
• If a function call does not satisfy the preconditions, the function is free to do anything.
• Function causes the program to terminate.
• Return a "safe" default value.