## Lecture Goals

• 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

## Parameters (Review)

Example:
`void raise_salary(Employee& e, double by)  // function definition{  double new_salary = e.get_salary() * ( 1 + by / 100);   e.set_salary(new_salary);}int main(){  Employee harry("Hacker, Harry", 45000.00);   raise_salary(harry, 5); // function call   cout << "New salary: " << harry.get_salary() << "\n";   return 0;}`
• When the function starts, its parameter variables are initialized with the expressions in the function call.
• A reference parameter is not a new variable but a reference to the existing variable.
• Passing variables by constant reference improves performance, but prevents the function from changing the value of the parameter.
 parameter variable reference parameter constant reference parameter new variable, copying reference to an existing variable constant reference to a value input parameter may be input and should be output parameter input parameter can modify the parameter (bad style) should modify the parameter cannot modify the parameter can be bound to any expression must be bound to the variable can be bound to any expression

[raisesal.cpp]

## 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 (local) 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 (file scope).
• Sometimes global variables cannot be avoided (cin and cout), 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.

## From Pseudocode to Code

Example: Write a function that turns a number into a text string, for example 274 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 - description of the function.
• Writing the function (declaration and comments):
`/**   Turns a number into its English name.   @param n a positive integer < 1000000 (e.g. 274)   @return the name of n (e.g. "two hundred seventy four")*/string int_name(int n);`
• Break the problem into sub-tasks (special cases) and design subprograms (declarations and comments).
`/**   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 1000, 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;}`
• 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;}`
• When a function invokes itself, it must give a simpler assignment to the second copy of itself.

## Walkthroughs

• Before entrusting a subprogram to a computer, it is a good idea to put it through a dry run or walkthrough.
• 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(416) c r 416 ""
• When your function calls another function, you can either start another card, or assume that it performs correctly.
 int_name(416) c r 416 ""

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

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

 int_name(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 the assert macro.

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.
• 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);}`
• [futval0.cpp]
• 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.