Chapter 7 8 Functions 1 Example Power Square




















































- Slides: 52

Chapter 7 -8 Functions 1

Example: Power, Square Root and Absolute values of a number #include <cmath> … float num; float power, square. Root, absolute; cout << "Please input a float number: "; cin >> num; power = pow ( num , 2 ); cout << "The power is " << power << endl; if ( num > 0 ) { square. Root = sqrt ( num ); cout << "The square root is " << square. Root << endl; } else cout << num << " is negative. No squre root!" << endl; absolute = fabs ( num ); cout << "The absolute value is " << absolute << endl; 2

Math Functions in <cmath> �Need to use #include <cmath> or #include <math. h> float pow ( float base, float exponent ); float sqrt ( float num ); float fabs ( float num ); �They are functions! �These are function prototypes! 3

What other functions have you learned? �bool cin. eof(); �int string. length(); �string. substr(); �smanip setprecision(int n); �smanip setw(int n); How to define and use your own function? 4

Example: MAX of 2 numbers #include <iostream> using namespace std; int Max ( int num 1, int num 2 ); int main() { int num 1, num 2, max. Result; cin >> num 1 >> num 2; // function prototype (function declaration) // function max. Result = Max ( num 1, num 2 ); cout << "The max is " << max. Result << endl; call return 0; } int Max ( int num 1, int num 2 ) { int result; if ( num 1 > num 2 ) result = num 1; else result = num 2; // function heading function definition return result; } 5

Review: Element of a function Return Data Type Function Body Function Name Parameter List int Max ( int num 1, int num 2 ) { int result; if ( num 1 > num 2 ) result = num 1; else result = num 2; return result; } 6

Function Prototype �C++ programmer usually place all supporting functions after the main function. �C++ rule: identifiers must be declared before use! �Place a function prototype before the main function as a declaration. �Two ways to declare a function: int max ( int num 1, int num 2 ); OR int max ( int, int ); Add a semicolon to the function heading, and you get the function prototype! 7

Function Prototype Common Practice! #include <iostream> using namespace std; int max ( int num 1, int num 2 ); int max ( int num 1, int num 2 ) { int result; if ( num 1 > num 2 ) result = num 1; else result = num 2; int main() { … max. Result = max ( num 1, num 2 ) … } int max ( int num 1, int num 2 ) { int result; if ( num 1 > num 2 ) result = num 1; else result = num 2; return result; = return result; } int main() { … max. Result = max ( num 1, num 2 ) … } } 8

Review: Two Types of Functions �Void Function �Return data type is void �Don’t need a return statement in the function �Function call format: function. Name(parameters); �Value-Return Function �Return data type is some real data type (int, float, string) �Need a return statement to return a value to the caller function �Function call format: var = function. Name(parameters); OR use function. Name(parameters)as a variable. 9

Formal parameters vs. Actual parameters (Arguments) � Formal parameters appears in a function heading. int max ( int num 1, int num 2 ); Used in the callee function. � Actually parameters (Arguments) appear in a function call. result = max ( 2, 3 ); � During a function call, an argument can be a literal, variable, or expression. result = pow( 3, 2 ); result = fabs ( num ); result = sqrt ( num / 2 + 1 ); � A function is not required to have arguments. eof(); Used in the caller function. 10

Void Function #include <iostream> #include <string> using namespace std; const int HEIGHT = 10; void Print. Line(int height); int main() { int height = HEIGHT; while ( height > 0 ) { Print. Line(height); height --; } return 0; } Formal parameter: height Actual parameter: height They can have the same name! void Print. Line(int height) { string space. Line = ""; string dollar. Line = ""; int count = 0; while ( count < height - 1 ) { space. Line += " "; count ++; } count = 0; while ( count < 2 * ( HEIGHT - height ) + 1 ) { dollar. Line += "$"; count ++; } cout << space. Line << dollar. Line << endl; } 11

Value-Return Function Formal parameter: pay. Rate, hour Actual parameter: rate, hour They can have different names! #include <iostream> using namespace std; float gross. Pay(float pay. Rate, float hour); int main() { float hours; float rate; float salary; cout << "Please enter your pay rate “ << “(per hour): "; cin >> rate; cout << "Please enter your working “ << “hours: "; cin >> hours; salary = Gross. Pay(rate, hours); cout << "Your salary is " << salary << “. ” << endl; float Gross. Pay(float pay. Rate, float hour) { float salary; if (hour <= 40) salary = hour * pay. Rate; else { salary = ( hour - 40 ) * pay. Rate * 1. 5 + 40 * pay. Rate; cout << endl << "You have " << ( hour - 40 ) << " hours overtime. " << endl; } return salary; } return 0; } 12

Function Names �Meaningful names �Names for functions and methods with a return type of void should generally be verb phrases such as Compute. Pay() and Print. Orders(). �Names for functions and methods with other return types should generally be nouns or noun phrases such as Average() and Monthly. Salary(). �Capitalize the first letter of each word! �Formal and actual parameters can have the same name �They are different variables in different scopes �Normally they have different names 13

Activation Record �There is one activation record for each function call. �An activation record contains: �Local variables of the function called �Return address �Parameters for the function called Locals Return Address Parameters

Activation Record for Gross. Pay int main() { float hours; float rate, salary; cout << "Please enter your pay rate “ << “(per hour): "; cin >> rate; cout << "Please enter your working “ << “hours: "; cin >> hours; salary = Gross. Pay(rate, hours); cout << "Your salary is " << salary << “. ” << endl; return 0; } hours ? rate ? salary ? Input values: 45 10 475 float Gross. Pay(float pay. Rate, float hour) { float salary; if (hour <= 40) salary = hour * pay. Rate; else { salary = ( hour - 40 ) * pay. Rate * 1. 5 + 40 * pay. Rate; cout << endl << "You have " << ( hour - 40 ) << " hours overtime. " << endl; } return salary; } 10 45 pay. Rate hour salary 10 45 ? 475

Scope of Variables �The region of code where it is legal to reference (use) an identifier. �Local Scope �Global Scope �Class Scope (Later in this semester. ) 16

Statement Block �Between a pair of matching braces �e. g. The body of a function int main() { int alpha = 10; // A block for if statement if (alpha > 3) { int num; cin >> num; alpha += num; } return 0; } 17

Local Scope int main() { int alpha = 10; �The scope of an identifier declared inside a block extends from the point of declaration to the end of that block. // A code block if (alpha > 3) { int num; cin >> num; alpha += num; } cout << "num = “ << num; // Run time error! return 0; } 18

Nested Local Scope �local identifiers have name precedence! �The scope of an identifier does not include any nested block that contains locally declared identifier of the same name! int main () { int num = 0; string name = “Kyle”; while ( num < 5 ) { string name = “Alice”; cout << name << num << endl; num ++; } cout << endl << name; return 0; } What is the output? Alice 0 Alice 1 Alice 2 Alice 3 Alice 4 Kyle 19

Global Scope �The scope of an identifier declared outside all functions (and classes) extends from the point of declaration to the end of the entire source file. Programming Rules: No global variables! 20

Scope of a Function Name �A function name has global scope. �Function definitions cannot be nested within function definitions! int main () { int num = 0; string name = “Kyle”; while ( num < 5 ) { void Print. Alice ( int count ) { string name = “Alice”; cout << name << count << endl; } num ++; } cout << endl << name; return 0; } // Can we do that? // NO! 21

Scope of Function Parameters �Formal parameters � Local scope � Same as local variable � Cannot reference it outside the function � Receive values on function call �Actual parameters (no global variables) � Local scope � Cannot reference it inside the called function 22

Example: Gross. Pay #include <iostream> using namespace std; formal parameters float Gross. Pay(float pay. Rate, float hour); int main() { int hour; float rate; float salary; scope cout << "Please enter your pay rate “ << “(per hour): "; cin >> rate; cout << "Please enter your working “ << “hours: "; cin >> hour; actual parameters salary = Gross. Pay(rate, hour); cout << "Your salary is " << salary << “. ” << endl; return 0; } float Gross. Pay(float pay. Rate, float hour) { float salary; if (hour <= 40) salary = hour * pay. Rate; else { salary = ( hour - 40 ) * pay. Rate * 1. 5 + 40 * pay. Rate; cout << endl << "You have " << ( hour - 40 ) << " hours overtime. " << endl; } return salary; } scope 23

Example: Using a flag float Do. It(int num, char op); int main() { int base; float result; char choice; cout << “Enter a number: ”; cin >> base; cout << “C for Cube and S for Square Root: ”; cin >> choice; // --------------// Precondition: op is ‘C’ or ‘S’ // Postcondition: the cube of // num is computed when op is // ‘C’, and square root of num // is computed when op is ‘S’. // parameters: in, in // ---------------float Do. It(int num, char op) { if (op == ‘C’) result = pow(num, 3); else result = sqrt(num); while (choice != ‘C’ && choice != ‘S’) { cout << “C for Cube and S for Square Root: ”; cin >> choice; } result = Do. It(base, choice); return result; } cout << “The result: ” << result; return 0; } // What is wrong? // Result not declared in the // function! 24

Example: Using a flag int Do. It(int num, char op); int main() { int base; float result; char choice; cout << “Enter a number: ”; cin >> base; cout << “C for Cube and S for Square: ”; cin >> choice; while (choice != ‘C’ && choice != ‘S’) { cout << “C for Cube and S for Square: ”; cin >> choice; } result = Do. It(base, choice); cout << “The result: ” << result; return 0; } // ---------------// Precondition: op is ‘C’ or ‘S’ // Postcondition: the cube of // num is computed when op is // ‘C’, and square root of num // is computed when op is ‘S’. // parameters: in, in // ---------------float Do. It(int num, char op) { float result; if (op == ‘C’) result = pow(num, 3); else result = sqrt(num); return result; } // The two variables // result have the same // name, but different! 25

Programming Ground Rules � All functions, including the main function, should be no more than 30 lines long, from the left brace to the right brace, inclusive. � Every function and method, except the main function, must have a comment which describes � what it does and � whether the parameters are input, output, or input and output. � Be sure to document the purpose of any parameter which isn't obvious from its name alone. � Thus function and method headers must have the following format: //----------------------------// A few lines describing what the function or method does. // params: (in/out/inout, . . . ) //----------------------------result_type function_name(type 1 param 1, type 2 param 2, . . . ) 26

Function Parameters �IN parameters: � The value of the actual parameter is passed into the function and assigned to the formal parameter. �OUT parameters: � The value of formal parameter is passed out of the function and assigned to the actual parameter. �In. Out � Both In and Out. 27

Example: IN Parameter #include <iostream> using namespace std; float Gross. Pay(float pay. Rate, float hour); int main() { int hour; float rate; float salary; cout << "Please enter your pay rate “ << “(per hour): "; cin >> rate; cout << "Please enter your working “ << “hours: "; cin >> hour; salary = Gross. Pay(rate, hour); cout << "Your salary is " << salary << “. ” << endl; return 0; } The value of rate and hour in the main function is passed to pay. Rate and hour in the gross. Pay function. Can we write a function to input rate and hour? How to pass the values back to the main function? 28

Example: OUT Parameter float Gross. Pay(float pay. Rate, float hour); void Get. Input(float& pay. Rate, float& hours. Worked); int main() { float hour, rate, gross; // Call function get. Input() to get two values Get. Input(rate, hour); // Call function gross. Pay to get one value gross = Gross. Pay(rate, hour); // display result cout << "Your salary is " << gross << endl; } return 0; 29

Function definition of Get. Input // // // ------------------------The function inputs pay. Rate and hours. Worked and pass both values back to the calling function. Parameters: (out, out) ------------------------- void Get. Input(float& pay. Rate, float& hours. Worked) { cout << "Enter pay rate: "; cin >> pay. Rate; cout << "Enter hours: "; cin >> hours. Worked; } // // return; // in void functions, using return is optional. The function does input with prompt, but OUT parameters! How can it pass two values back? Out Parameters: & Statement return can pass only one value back! 30

Function definition of Gross. Pay // ------------------------// The function computes and returns the gross pay // based on the pay rate and hours. Hours over // 40 will be paid 1. 5 times the regular pay rate. // Parameters: (in, in) // ------------------------float Gross. Pay(float pay. Rate, float hour) { if (hour > REG_HOURS) pay. Rate = (hour - REG_HOURS) * OVER_TIME * pay. Rate + REG_HOURS * pay. Rate; else pay. Rate = hour * pay. Rate; return pay. Rate; } // No local variable // pay. Rate is used to store the result 31

Reference and Value Parameters float Gross. Pay(float pay. Rate, float hour); void Get. Input(float& pay. Rate, float& hours. Worked); �Value parameter: No & Data. Type identifier, … The value of actual parameter is passed to the formal parameter �Reference Parameter: With & Data. Type& identifier, … The address of actual parameter is passed to the formal parameter � Does the actual parameter change its value when the corresponding formal parameter changes its value? � Value parameter (no &): NO � Reference parameter (&): YES 32

Reference and Value Parameters �Function call using value parameters: gross = Gross. Pay(rate, hour); float main Memory rate 22. 5 hour 50 Gross. Pay(float pay. Rate, float hour); Gross. Pay pay. Rate 22. 5 hour 50 �Function call using reference parameters: Get. Input(rate, hour); Memory 7000 main rate 22. 5 7004 50 hour void Get. Input(float& pay. Rate, float& hours. Worked); Get. Input 70 &pay. Rate 00 70 &hours. Worked 04 33

Trace Functions with OUT parameters Input: 10 45 Get. Input(rate, hour); // Reference parameters gross = Gross. Pay(rate, hour); // Value parameters main() rate ? hour ? ? gross Get. Input() 10 pay. Rate hours. Worked 45 450 &rate &hour Gross. Pay() pay. Rate hour salary 10 45 ? 450 34

Example: In. Out Parameter int main() { float score, highest, lowest; int score. Count = 0; cin >> score; while (!cin. eof()) { if (score. Count == 0) { highest = score; lowest = score; } else { if (score > highest) highest = score; if (score < lowest) lowest = score; } score. Count ++; cin >> score; } cout << “Highest: “ << highest << “n. Lowest: “ << lowest; return 0; } // Task: Use a function to update highest and lowest. 35

Example: In. Out Parameter void Update. Max. Min ( float, float& ); int main() { float score, highest, lowest; int score. Count = 0; cin >> score; while (!cin. eof()) { if (score. Count == 0) { highest = score; lowest = score; } else Update. Max. Min ( score, highest, lowest ); score. Count ++; // // // ----------------The function uses the value of num to update the values of max and min. Parameters: ( In, In. Out ) ---------------- void Update. Max. Min( float num, float& max, float& min ) { if (num > max) max = num; } if (num < min) min = num; cin >> score; } cout << "Highest: " << highest << "n. Lowest: " << lowest; return 0; } 36

Example: In. Out Parameter �Function call: Update. Max. Min ( score, highest, lowest ); �Function Definition: void Update. Max. Min( float num, float& max, float& min ) main Memory update. Max. Min score 20 num highest 20 10 max &highest lowest 2 min &lowest 37

Trace Functions with In. Out parameters Input: 45 40 50 update. Max. Min ( score, highest, lowest ); //Function call void update. Max. Min( float num, float& max, float& min ) //Function definition 38

Value Parameter and Reference Parameter � What can the actual parameter be for a value parameter? A VALUE! Literal value (magic number) Variable (initialized!) Expression (with all variables initialized) � What can the actual parameter be for a reference parameter? AN ADDRESS! Literal value: NO Expression: NO Variable: YES initialized or uninitialized 39

Actual Parameter � Does the actual parameter change its value when the corresponding formal parameter changes its value? Value Parameter NO! Reference Parameter YES! 40

Function Calls �Main function call another function A �A function can also call another function B main A B Caller Callee 41

Decompose the program by functions �Modularity �Any function or method (including the main function) can have at most 30 lines. �A function should implement ONE basic functionality. � Functions and methods which focus on computation should not produce output using cout statements. �Check: �Can I replace the loop body with a function? �Can I use a function to get valid input? �Can I use a function to do some particular computation? �Is there any activity that is repeated multiple times in the program? 42

Design Function Interface �What parameters should be passed? �How? In, Out, or In. Out? �In: pass by value. Recommended! �Out: pass by reference. �In. Out: pass by reference. If possible, try to avoid passing reference parameters! Because it might cause unexpected values changes of the caller’s variables. 43

Example: Bad Functions float Get. Rate(float rate) { cout << “Enter the rate: ”; cin >> rate; return rate; } // Bad: Why use parameter? float Get. Rate() { float rate; cout << “Enter the rate: ”; cin >> rate; return rate; } // Good: Use local variable! float Gross. Pay(float rate, float hour) { float pay = rate * hour; cout << “The pay is “ << pay; return pay; } // Bad: No output in calculation functions! void Power ( int& base, int& exponent, int& result ) { result = 1; while ( exponent > 0 ) { result = result * base; exponent --; } } // Bad: No need to use reference parameter! 44

Example: Print a chess board Pseudo Code: while height is not 8 yet if line# is odd, then print an odd row otherwise, print an even row Print an odd row: while cell height is not enough while cell width is not enough if cell# is odd print N spaces otherwise, print N ‘@’ Do we need two print row functions? Use a flag to indicate odd or even row! Print an even row: while cell height is not enough while cell width is not enough if cell# is odd print N ‘@’ otherwise, print N spaces 45

Example: Print a chess board Pseudo Code: while height is not 8 yet if row# is odd, then print an odd row otherwise, print an even row The function print. Row is too long! Print a row: while cell height is not enough while cell width is not enough if cell# is odd print N spaces if row# is even, or print N ‘@’ if row# is odd otherwise, print N ‘@’ if row# is even, or print N spaces if row# is odd replace the circled code with function print. Line! Further pass the flag to print. Line. 46

Example: Print a chess board const const int BOARD_WIDTH = 8; int CELL_WIDTH = 10; int CELL_HEIGHT = 4; char FILL = '@'; char EMPTY = ' '; int main() { int count = 0; while ( count < BOARD_WIDTH ) { print. Row ( count ); count ++; } return 0; } void print. Row ( int row. Num ) { int count. Height = 0; while ( count. Height < CELL_HEIGHT ) { print. Line ( row. Num ); count. Height ++; } } void print. Line ( int row. Num) { int count. Width = 0; int count. Cell = 0; while ( count. Width < BOARD_WIDTH ) { count. Cell = 0; if ( count. Width % 2 == 0 ) while ( count. Cell < CELL_WIDTH ) { if ( row. Num % 2 == 0) cout << EMPTY; else cout << FILL; count. Cell ++; } else while ( count. Cell < CELL_WIDTH ) { if ( row. Num % 2 == 0) cout << FILL; else cout << EMPTY; count. Cell ++; } Can it be further count. Width ++; decomposed? } cout << endl; 47 }

Summary �Function definition �Function prototype �Void functions vs. value-return functions �Formal parameters vs. actual parameters �Scope of variables �Scope of function parameters �Scope of function names �Parameter passing: In, Out and In. Out �Value parameters vs. reference parameters �Program decomposition 48

More about getting input �cin. get() �cin. ignore() �getline(cin, string) 49

cin. get(char&) �the >> operator skips any leading whitespace or new line in the input stream. �What if we want to read the whitespace? char ch 1, ch 2, ch 3; //Input: a b c cin >> ch 1 >> ch 2 >> ch 3; //OR cin. get(ch 1); cin. get(ch 2); cin. get(ch 3); //ch 1 = ‘a’, ch 2 = ‘b’, ch 3=‘c’ //ch 1 = ‘a’, ch 2 = ‘ ’, ch 3=‘c’ 50

cin. ignore() �cin. ignore(200, ‘n’): �skip the next 200 input characters OR �skip characters until a newline character is read �whichever comes first! string str; cin. ignore(20, 'n'); cin >> str; cout << endl << str; If the input is “This is a test to see which string will be input. ”, what do you think is the input? 51

getline(cin, string) �How to read a complete line of input? �getline(cin, string) will read everything until it reaches a newline character. 52