Function Call Example A Function Call Example (1) ch 3-25
A Function Call Example (2) ch 3-26
Alternative Function Declaration Recall: Function declaration is "information for compiler Compiler only needs to know: Return type Function name Parameter list Formal parameter names not needed: double totalcost(int, double); Still "should" put in formal parameter names Improves readability ch 3-27
Parameter ( 매개변수 ) vs. Argument ( 인수 ) Terms often used interchangeably Formal parameters/arguments In function declaration (prototype) In function definition s header Actual parameters/arguments In function call (invocation) Technically parameter is "formal" piece while argument is "actual" piece ch 3-28
Functions Calling Another Functions We re already doing this! main() is a function! Only requirement: Function s declaration ( 선언 ) must appear first Function s definition ( 정의, 구현 ) typically elsewhere After main()"s definition Or in separate file Common for functions to call many other functions Function can even call itself "Recursion" ch 3-29
Boolean Return-Type Functions Return-type can be any valid type Given function declaration/prototype: bool appropriate(int rate); And function s definition: bool appropriate (int rate) { return (((rate>=10)&&(rate<20)) (rate==0)); } Returns "true" or "false" Function call, from some other function: if (appropriate(entered_rate)) cout << "Rate is valid n"; ch 3-30
Declaring Void Functions Similar to functions returning a value Return type specified as "void" Example: Function declaration/prototype: void showresults( double fdegrees, double cdegrees); Return-type is "void" Nothing is returned ch 3-31
Declaring Void Functions Function definition: void showresults(double fdegrees, double cdegrees) { cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(1); cout << fdegrees << " degrees fahrenheit equals n" << cdegrees << " degrees celsius. n"; } Notice: no return statement Optional for void functions ch 3-32
Calling Void Functions Same as calling predefined void functions From some other function, like main(): showresults(degreesf, degreesc); showresults(32.5, 0.3); Notice no assignment, since no value returned Actual arguments (degreesf, degreesc) Passed to function Function is called to "do it s job" with the data passed in ch 3-33
More on Return Statements Transfers control back to "calling" function For return type other than void, MUST have return statement Typically the LAST statement in function definition return statement optional for void functions Closing } would implicitly return control from void function ch 3-34
Preconditions and Postconditions Similar to "I-P-O" discussion Comment at function declaration: void showinterest(double balance, double rate); //Precondition: balance ( 은행잔고 ) is nonnegative account balance // rate is interest rate ( 이자율 ) as percentage //Postcondition: amount of interest on given balance, // at given rate Often called Inputs & Outputs ch 3-35
main(): "Special" Recall: main() IS a function "Special" in that: One and only one function called main() will exist in a program Who calls main()? Operating system (OS) Tradition holds it should have return statement Value returned to "caller" Here: operating system Should return "int" or "void" ch 3-36
Recursive Function ( 재귀함수 ) A function that "calls itself" Said to be recursive ( 재귀 ) In function definition, call to same function C++ allows recursion As do most high-level languages Can be useful programming technique Has limitations Divide and Conquer ( 분할및정복 ) Basic design technique Break large task into subtasks Subtasks could be smaller versions of the original task! When they are recursion ch 3-37
Recursive void Function Example Consider task: Search list for a value Subtask 1: search 1 st half of list Subtask 2: search 2 nd half of list Subtasks are smaller versions of original task! When this occurs, recursive function can be used. Usually results in "elegant" solution ch 3-38
Recursive void Function: Vertical Numbers Task: display digits of number vertically, one per line Example call: writevertical(1234); Produces output: 1 2 3 4 ch 3-39
Vertical Numbers: Recursive Definition Break problem into two cases Simple/base case: if n<10 Simply write number n to screen Recursive case: if n>=10, two subtasks: 1- Output all digits except last digit 2- Output last digit Example: argument 1234: 1 st subtask displays 1, 2, 3 vertically 2 nd subtask displays 4 ch 3-40
writevertical Function Definition Given previous cases: void writevertical(int n) { if (n < 10) //Base case cout << n << endl; else { //Recursive step writevertical(n/10); cout << (n%10) << endl; } } ch 3-41
writevertical Trace Example call: writevertical(123); writevertical(12); // (123/10) writevertical(1); // (12/10) cout << 1 << endl; cout << 2 << endl; cout << 3 << endl; Arrows indicate task function performs Notice 1 st two calls call again (recursive) Last call (1) displays and "ends" ch 3-42
Recursion A Closer Look Computer tracks recursive calls Stops current function Must know results of new recursive call before proceeding Saves all information needed for current call E.g.) return address after function call To be used later Proceeds with evaluation of new recursive call When THAT call is complete, returns to "outer" computation ch 3-43
Recursion Big Picture Outline of successful recursive function: One or more cases where function accomplishes its task by: Making one or more recursive calls to solve smaller versions of original task Called "recursive case(s)" One or more cases where function accomplishes its task without recursive calls Called "base case(s)" or stopping case(s) ch 3-44
Infinite Recursion Base case MUST eventually be entered If it doesn t infinite recursion Recursive calls never end! Recall writevertical example: Base case happened when down to 1-digit number That s when recursion stopped ch 3-45
Infinite Recursion Example Consider alternate function definition: void newwritevertical(int n) { newwritevertical(n/10); cout << (n%10) << endl; } Seems "reasonable" enough Missing "base case"! Recursion never stops ch 3-46
Stacks for Recursion A stack Specialized memory structure Like stack of plates in buffet Place new on top Remove from top when needed Called "last-in/first-out (LIFO)" memory structure Recursion uses stacks Each recursive call placed on stack When one completes, last call is removed from stack ch 3-47
Memory Map Memory Map of a process 0x0000 0000 Text Code (Execution code) BSS (Global variables, static local variables) Heap (dynamic memory allocation) Heap grows downward on repeated dynamic memory allocations Stack grows upward on repeated function calls (including recursive function calls) frame for function2() (parameters, local variables) frame for function1() (parameters, local variables) frame for main() (parameters, local variables) create new frame for each function call 0xFFFF FFFF Stack ch 3-48
Stack Overflow Size of stack is limited Memory is finite Long chain of recursive calls continually adds to stack All are added before base case causes removals If stack attempts to grow beyond limit: Stack overflow error Infinite recursion always causes this ch 3-49
Recursion vs. Iteration Recursion not always "necessary" in some programming languages, recursion is not allowed Any task accomplished with recursion can also be done without it Nonrecursive: called iterative, using loops Recursive: based on function call that requires additional operations (prepare stack frame, copy arguments and return address, prepare local variables, copy return value, etc.) runs slower, uses more storage elegant solution; simple in algorithm; less coding ch 3-50
Recursive Functions that Return a Value Recursion not limited to void functions Can return value of any type Same technique, outline: 1. One+ cases where value returned is computed by recursive calls Should be "smaller" sub-problems 2. One+ cases where value returned computed without recursive calls Base case ch 3-51
Recursion Example: Powers Recall predefined function pow(): result = pow(2.0,3.0); Returns 2 raised to power 3 (8.0) Takes two double arguments Returns double value Let s write recursively For simple example ch 3-52
Function Definition for power() int power(int x, int n) { // x: base, n: exponent if (n<0) { cout << "Illegal argument"; exit(1); } else if (n>0) { return (power(x, n-1)*x); } else { return (1); } } ch 3-53
Calling Recursive Function power() Example calls: power(2, 0); returns 1 power(2, 1); returns (power(2, 0) * 2); returns 1 Value 1 multiplied by 2 & returned to original call Larger example: power(2,3); power(2,2)*2 power(2,1)*2 power(2,0)*2 1 Reaches base case Recursion stops Values "returned back" up stack ch 3-54
Tracing Function power():
Fibonacci Sequence Fibonacci Series ch 3-56
Recursive function fibonacci(n) int fibonacci(int n) { if ((n == 0) (n == 1)) return n; else return (fibonacci(n-1) + fibonacci(n-2)); } int main() { /* Testing Fibonacci */ for (int i=0; i<=10; i++) { cout << "Fibonacci(" << setw(2) << i << ") = " << setw(10) << fibonacci(i) << endl; } cout << "Fibonacci(" << 20 << ") = " << setw(10) << fibonacci(20) << endl; cout << "Fibonacci(" << 30 << ") = " << setw(10) << fibonacci(30) << endl; cout << "Fibonacci(" << 40 << ") = " << setw(10) << fibonacci(40) << endl; } ch 3-57
Ignore details Thinking Recursively Forget how stack works Forget the suspended computations Yes, this is an "abstraction" principle! And encapsulation principle! Let computer do "bookkeeping" Programmer just think "big picture" ch 3-58
Thinking Recursively: power Consider power() again Recursive definition of power: power(x, n) returns: power(x, n 1) * x Just ensure "formula" correct And ensure base case will be met ch 3-59
Recursive Design Techniques Don t trace entire recursive sequence! Just check 3 properties: 1. No infinite recursion 2. Stopping cases return correct values 3. Recursive cases return correct values ch 3-60
Recursive Design Check: power() Check power() against 3 properties: 1. No infinite recursion: power(x,n) returns power(x,n-1)*x 2 nd argument decreases by 1 each call Eventually must get to base case of 1 2. Stopping case returns correct value: power(x,0) is base case Returns 1, which is correct for x 0 3. Recursive calls correct: For n>1, power(x,n) returns power(x,n-1)*x Plug in values correct ch 3-61
Scope Rules Local variables Declared inside body of given function Available only within that function Can have variables with same names declared in different functions Scope is local: "that function is the scope of the local variable" Local variables preferred Maintain individual control over data Need to know basis Functions should declare whatever local data needed to "do their job" ch 3-62
Display 3.8 Local Variables //Computes the average yield on an experimental pea growing patch. #include <iostream> using namespace std; double estimateoftotal(int minpeas, int maxpeas, int podcount); //Returns an estimate of the total number of peas harvested. //The formal parameter podcount is the number of pods. //The formal parameters minpeas and maxpeas are the minimum //and maximum number of peas in a pod. int main( ) { int maxcount, mincount, podcount; double averagepea, yield; cout << "Enter minimum and maximum number of peas in a pod: "; cin >> mincount >> maxcount; cout << "Enter the number of pods: "; cin >> podcount; cout << "Enter the weight of an average pea (in ounces): "; cin >> averagepea; ch 3-63
// Display 3.8 Local Variables (2) yield = estimateoftotal(mincount, maxcount, podcount) * averagepea; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(3); cout << "Min number of peas per pod = " << mincount << endl << "Max number of peas per pod = " << maxcount << endl << "Pod count = " << podcount << endl << "Average pea weight = " << averagepea << " ounces" << endl << "Estimated average yield = " << yield << " ounces" << endl; } return 0; ch 3-64
double estimateoftotal(int minpeas, int maxpeas, int podcount) { double averagepea; } averagepea = (maxpeas + minpeas)/2.0; return (podcount * averagepea); ch 3-65
Procedural Abstraction ( 추상화 ) Need to know "what" function does, not "how" it does it! Think "black box" Device you know how to use, but not it s method of operation Implement functions like black box User of function only needs: declaration Does NOT need function definition Called Information Hiding Hide details of "how" function does it s job ch 3-66
Global Constants ( 전역상수 ) and Global Variables ( 전역변수 ) Global: declared "outside" function body Global to all functions in that file Local: declared "inside" function body Local to that function Global declarations typical for constants: const double TAXRATE = 0.05; Declare globally so all functions have scope Global variables? Possible, but SELDOM-USED Dangerous: no control over usage! ch 3-67
Display 3.9 Global Named Constant //Computes the area of a circle and the volume of a sphere. //Uses the same radius for both calculations. #include <iostream> #include <cmath> using namespace std; const double PI = 3.14159; double area(double radius); //Returns the area of a circle with the specified radius. double volume(double radius); //Returns the volume of a sphere with the specified radius. int main( ) { double radiusofboth, areaofcircle, volumeofsphere; cout << "Enter a radius to use for both a circle n" << "and a sphere (in inches): "; cin >> radiusofboth; ch 3-68
// Display 3.9 Global Names Constant (2) areaofcircle = area(radiusofboth); volumeofsphere = volume(radiusofboth); cout << "Radius = " << radiusofboth << " inches n" << "Area of circle = " << areaofcircle << " square inches n" << "Volume of sphere = " << volumeofsphere << " cubic inches n"; } return 0; double area(double radius) { return (PI * pow(radius, 2)); } double volume(double radius) { return ((4.0/3.0) * PI * pow(radius, 3)); } ch 3-69
Blocks Declare data inside compound statement Called a "block" Has "block-scope" Note: all function definitions are blocks! This provides local "function-scope" Loop blocks: for (int ctr=0; ctr<10; ctr++) { sum += ctr; } Variable ctr has scope in loop body block only ch 3-70
Nested Scope Same name variables declared in multiple blocks Very legal; scope is "block-scope" No ambiguity Each name is distinct within its scope ch 3-71
Summary 3-1 Two kinds of functions: "Return-a-value" and void functions Functions should be "black boxes" Hide "how" details Declare own local data Function declarations should selfdocument Provide pre- & post-conditions in comments Provide all "caller" needs for use ch 3-72
Summary 3-2 Local data Declared in function definition Global data Declared above function definitions OK for constants, not for variables Parameters/Arguments Formal: In function declaration and definition Placeholder for incoming data Actual: In function call Actual data passed to function ch 3-73
Homework 3 3.1 Estimation of PI (π) using rand() function a area of an inner circle with radius a => πa 2 area of square with width of 2a => (2 a) 2 = 4 a 2 Using random number function, generate coordinators x, y in the range of a ~ 0 ~ +a while a N_total generation of random points, when the point (x, y) is within the circle (i.e., r=sqrt(x 2 + y 2 ) < a), increase the N_Circle. N_Circle / N_total = area of circle / area of square πa 2 / 4 a 2 so, π can be estimated as N _ circle 4 N _ total Write a pseudo code and c++ program that calculates the estimation of π with repeated trials of randomly generated coordinates (x, y), at given a=100, 10,000 and 1,000,000, and N_total = 100, 10,000, and 1,000,000. Print out the estimations of π, with precision of 10 digits after the decimal point, in the format of table, shown below. ch 3-74
N_total Radius a 100 10,000 1,000,000 100 10,000 1,000,000 3.2 Programming Project 3-4. (p. 166) Write a pseudo code and a C++ program that calculates the gravitational attractive force between two bodies with mass m1 and m2 separated by distance d. ch 3-75
3.3 Calculation of power(base, exponent) using recursive function. 1) Write an algorithm in pseudo code that calculates the power(base, exponent) in recursive structure. In recursive structure, power(base, exponent) is calculated as follows: power(base, exponent) = base power (base, exponent -1), where exponent 0 power(base, 0) = 1 <Example> power(2.5, 3.0) = 15.625 power(2.5, 0.0) = 1 2) Write a C++ program that inputs two double integers from standard input (cin) using the argc and argv in argument passing to main() function, assigns to base and exponent, respectively, calculates the power (base, exponent) using the recursive function, and displays the result. The recursive function should print out the base and exponent values at each recursive call. ch 3-76