p134-159

## call by value

 `double finalScore(double midterm, double exam) { double result1 = 0.5*midterm + 0.5*exam; double result2 = 0.4*midterm + 0.6*exam; // the final score is the max of result1 and result2 if(result1 >= result2) return result1; else return result2;}`
Let's assume `x = 50, y = 70`.
When you call `finalScore(x, y)` in `main`
1. The value of `x` is copied to function `finalScore`'s local variable `midterm`.
2. The value of `y` is copied to function `finalScore`'s local variable `exam`.
3. The codes in `finalScore`'s function body will be executed. and the result will be returned.
Key concept
• `midterm,exam` are local variables of `finalScore`.
• The values of `x,y` are copied to `midterm,exam`.
This implies
• You can't change the value of the variables by ordinary function calls because the values are copied to other local variables. Change in other local variables won't affect the original variables.
• You original variables won't be accidentally corrupted(changed) by other functions.
Example1
What is the output of the following program?
 ```#includeusing namespace std;void increase(int); int main() { int x = 1; cout << "Before calling the increase function, x is " << x << ".\n"; increase(x); cout << "After calling the increase function, x is " << x << ".\n"; return 0; } void increase(int x) { x++;}```
Output. The `x` is not increased!
 `Before calling the increase function, x is 1.After calling the increase function, x is 1.`
Example2
The user tries to write a function to ask for a postitive input. Here is his code
 ```#include using namespace std;void positiveInput(int num); int main() { int x = 0; positiveInput(x); cout << "x is " << x << endl; return 0; } void positiveInput(int num) { do { cout << "Please input a positive number : "; cin >> num; if(num <= 0) { cout << "You can't input negative number.\n"; } } while (num <= 0);}```
Here is the output. The `x` is unchanged!
 ```Please input a positive number : -19You can't input negative number.Please input a positive number : -100You can't input negative number.Please input a positive number : 5 x is 0 ```

### Call by reference

Here are the new codes for the above examples
Example1
What is the output of the following program?
 ```#includeusing namespace std;void increase(int& x); int main() { int x = 1; cout << "Before calling the increase function, x is " << x << ".\n"; increase(x); cout << "After calling the increase function, x is " << x << ".\n"; return 0; } void increase(int& x) { x++;}```
Output. The `x` is really increased by 1.
 `Before calling the increase function, x is 1.After calling the increase function, x is 2.`
Example2
 ```#include using namespace std;void positiveInput(int& num);int main() { int x = 0; positiveInput(x); cout << "x is " << x << endl; return 0;}void positiveInput(int& num) { do { cout << "Please input a positive number : "; cin >> num; if(num <= 0) { cout << "You can't input negative number.\n"; } } while (num <= 0); } ```
Here is the output. `x` is changed!
 ```Please input a positive number : -19You can't input negative number.Please input a positive number : -100You can't input negative number.Please input a positive number : 5 x is 5 ```
Syntax
 ```type& variableName ``` The ampersand sign, & comes right after the type. or ```type amp;variableName ``` The ampersand sign, & comes right before the variableName. They are used in parameter list. Example `int increase(int& num);` `void askForInput(double &income, char &gender);`
• Every variable is in a memory location. Each memory location has a unique address.
• The ampersand & in the parameter list indicates variables are called by reference
• that means, the address of the parameters are copied. (in call by value, the value of the parameters are copied).
• in a function body, anything says to do to a parameter is actually done to the memory location (which has an address) associated with that formal parameter.
• so whatever the function instructs the computer to do on the parameters is actually done to the original variables
Comparison
call by value
call by reference
no & in the formal parameters
use & in the formal parameters
value of the variable is passed to the function
the address of the memory location of the variable is passed to the function
changes made to the local variable
changes made to the variable in the memory location.
no change can be made to the original variable
changes can be made the the original  variable because the original variable is the variable in the memory location.

Mixed Parameter list
• You can mix different types in a formal parameter list.
• You can also mix call by reference and call by value parameters.
Example
 ```#include using namespace std;const double TAXRATE = 0.25;// returns the taxdouble tax(double& income, bool married); int main() { double charlesIncome, charlesTax; double amyIncome, amyTax; charlesTax = tax(charlesIncome, false); cout << "Charles' taxable income: " << charlesIncome <> income1; cout << "Please enter your spouse's income: "; cin >> income2; income = income1+income2; } else { // single cout << "Please enter your income: "; cin >> income; } return income*TAXRATE;}```
Output
 ```Please enter your income: 100000 Charles' taxable income: 100000 Charles' tax: 25000 Please enter your income: 45000 Please enter your spouse's income: 62333 Amy's taxable income: 107333 Amy's tax: 26833.3 ```

• C++ allows you to give 2 or more different definitions to the same function name.
• you can reuse names that have strong intuitive appeal across a variety of situations
• example, you can have 3 functions called `max`, one that computes the largest of 2 number, another that computes the largest of 3 numbers, and yet another that computes the largest of four numbers.
• Give two(or more) function definitions for the same function name is called overloading the function name.
Example
 ```#includeusing namespace std;// returns the average of the two numbers n1 and n2double ave(double n1, double n2); // returns the average of the three numbers n1, n2 and n3 double ave(double n1, double n2, double n3); int main() { cout << "The average of 2.0, 2.5, 3.0 is " << ave(2.0, 2.5, 3.0) << endl; cout << "The average of 4.5 and 5.5 is " << ave(4.5, 5.5) << endl; return 0;}double ave(double n1, double n2) { return (n1+n2)/2;}double ave(double n1, double n2, double n3) { return (n1+n2+n3)/3;}```
Output
 `The average of 2.0, 2.5, 3.0 is 2.5The average of 4.5 and 5.5 is 5`
• The compiler can tell which function definition to use by checking the number and types of arguments in a function call. Example:
`ave(2.0, 2.5, 3.0)` matches ```double ave(double n1, double n2, double n3)```.
`ave(4.5, 5.5)` matches ```double ave(double n1, double n2)``` .
• Any two function name must use different numbers of formal parameters or have one or more parameters of different types(or both). Example:
`int tax(int income, bool married)void tax(int income, char gender)`
• You cannot overload a function name by giving two definitions that differ only in the type of the value returned.
• You cannot overload a function name based solely on `const` or solely on call-by-values versus call-by-function (although some compilers, like VC++, allow you to do that).
Example1(the program can't be compiled)
 ```#includeusing namespace std;// returns the average of the two numbers n1 and n2double ave(double n1, double n2); // returns the average of the three numbers n1, n2 int ave(double n1, double n2); int main() { cout << "The average of 2.0, 2.5 is " << ave(2.0, 2.5) << endl; cout << "The average of 4.5 and 5.5 is " << ave(4.5, 5.5) << endl; return 0; } double ave(double n1, double n2) { return (n1+n2)/2; } int ave(double n1, double n2) { return static_cast(n1+n2)/2; // type casting } ```
How the computer determines which function definition to use?
1. Exact match: if the number and types of arguments exactly match a definition, then that is the definition used.
2. Match using automatic type conversion: If there is no exact match but there is a match using automatic type conversion, then the match is used. If two matches are found, then there is an ambiguous and an error message will be issued.
Automatic type conversion
Examples are :
• `short` to `int`
• `float` to `double`
• `bool` to `int`
• `char` to `int`
• `int` to `double`
• `double` to `int`
What is the output of the following program?
 `#includeusing namespace std;void f(int n);void f(int n, double m);void f(double n, int m);void f(char n, double m);int main() { int a = 1; double b = 3.2; char c = 'X'; f(a,b); f(c,b); f(b,a); f(a); f(b); f(c); return 0;}void f(int n) { cout << "f(int n):" << " n is " << n << endl;}void f(int n, double m) { cout << "f(int n, double m)" << endl;}void f(double n, int m) { cout << "f(double n, int m)" << endl;}void f(char n, double m) { cout << "f(char n, double m)" << endl;}`
Output
 `f(int n, double m)f(char n, double m)f(double n, int m)f(int n): n is 1f(int n): n is 3f(int n): n is 88`
• the first 4 function calls are exact matches.
• the last 2 use type conversions.
The following function calls will cause compiling error(why?)
• `f(a,c)`
• `f(c,c)`
• `f(a,b)`