Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 8 September 24, 2009.

Similar presentations


Presentation on theme: "1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 8 September 24, 2009."— Presentation transcript:

1 1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 8 September 24, 2009

2 Constant Reference Parameters Reference arguments inherently "dangerous" – Caller’s data can be changed – Often this is desired, sometimes not To "protect" data, & still pass by reference: – Use const keyword void sendConstRef(const int &par1, const int &par2); Makes arguments "read-only" by function No changes allowed inside function body 4-2 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

3 Parameters and Arguments Confusing terms, often used interchangeably True meanings: – Formal parameters In function declaration and function definition – Arguments Used to "fill-in" a formal parameter In function call (argument list) – Call-by-value & Call-by-reference Simply the "mechanism" used in plug-in process 4-3 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

4 Mixed Parameter Lists Can combine passing mechanisms Parameter lists can include pass-by-value and pass-by-reference parameters Order of arguments in list is critical: void mixedCall(int & par1, int par2, double & par3); – Function call: mixedCall(arg1, arg2, arg3); arg1 must be integer type, is passed by reference arg2 must be integer type, is passed by value arg3 must be double type, is passed by reference 4-4 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

5 Overloading Same function name Different parameter lists Two separate function definitions Function "signature" – Function name & parameter list – Must be "unique" for each function definition Allows same task performed on different data 4-5 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

6 Overloading Example: Average Function computes average of 2 numbers: double average(double n1, double n2) { return ((n1 + n2) / 2.0); } Now compute average of 3 numbers: KFM Changed slide… double average(double n1, double n2, double n3) { return ((n1 + n2 + n3) / 3.0); } Same name, two functions 4-6 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

7 Overloaded Average() Cont’d Which function gets called? Depends on function call itself: – avg = average(5.2, 6.7); Calls "two-parameter average()" – avg = average(6.5, 8.5, 4.2); Calls "three-parameter average()" Compiler resolves invocation based on signature of function call – "Matches" call with appropriate function – Each considered separate function 4-7 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

8 Overloading Pitfall Only overload "same-task" functions – A mpg() function should always perform same task, in all overloads – Otherwise, unpredictable results C++ function call resolution: – 1 st : looks for exact signature – 2 nd : looks for "compatible" signature 4-8 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

9 Overloading Resolution 1 st : Exact Match – Looks for exact signature Where no argument conversion required 2 nd : Compatible Match – Looks for "compatible" signature where automatic type conversion is possible: 1 st with promotion (e.g., int  double) – No loss of data 2 nd with demotion (e.g., double  int) – Possible loss of data 4-9 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

10 Overloading Resolution Example Given following functions: – 1. void f(int n, double m); 2. void f(double n, int m); 3. void f(int n, int m); – These calls: f(98, 99);  Calls #3 f(5.3, 4);  Calls #2 f(4.3, 5.2);  Calls ??? Avoid such confusing overloading 4-10 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

11 Automatic Type Conversion and Overloading Example double mpg(double miles, double gallons) { return (miles/gallons); } Example function calls: – mpgComputed = mpg(5, 20); Converts 5 & 20 to doubles, then passes – mpgComputed = mpg(5.8, 20.2); No conversion necessary – mpgComputed = mpg(5, 2.4); Converts 5 to 5.0, then passes values to function 4-11 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

12 Default Arguments Allows omitting some arguments Specified in function declaration/prototype – void showVolume(int length, int width = 1, int height = 1); Last 2 arguments are defaulted – Possible calls: showVolume(2, 4, 6); //All arguments supplied showVolume(3, 5); //height defaulted to 1 showVolume(7); //width & height defaulted to 1 4-12 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

13 Default Arguments Example: Display 4.1 Default Arguments (1 of 2) 4-13 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

14 Default Arguments Example: Display 4.1 Default Arguments (2 of 2) 4-14 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

15 Testing and Debugging Functions Many methods: – Lots of cout statements In calls and definitions Used to "trace" execution – Compiler Debugger Environment-dependent – assert Macro Early termination as needed – Stubs and drivers Incremental development 4-15 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

16 The assert Macro Assertion: a true or false statement Used to document and check correctness – Preconditions & Postconditions Typical assert use: confirm their validity – Syntax: assert( ); No return value Evaluates assert_condition Terminates if false, continues if true Predefined in library – Macros used similarly as functions 4-16 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

17 An assert Macro Example Given Function Declaration: void computeCoin(int coinValue, int& number, int& amountLeft); //Precondition: 0 < coinValue < 100 0 <= amountLeft <100 //Postcondition: number set to max. number of coins Check precondition: – assert ((0 < currentCoin) && (currentCoin < 100) && (0 <= currentAmountLeft) && (currentAmountLeft < 100)); – If precondition not satisfied  condition is false  program execution terminates! 4-17 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

18 An assert Macro Example Cont’d Useful in debugging Stops execution so problem can be investigated 4-18 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

19 assert On/Off Preprocessor provides means #define NDEBUG #include Add "#define" line before #include line – Turns OFF all assertions throughout program Remove "#define" line (or comment out) – Turns assertions back on 4-19 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

20 Stubs and Drivers Separate compilation units – Each function designed, coded, tested separately – Ensures validity of each unit – Divide & Conquer Transforms one big task  smaller, manageable tasks But how to test independently? – Driver programs 4-20 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

21 Driver Program Example: Display 4.9 Driver Program (1 of 3) 4-21 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

22 Driver Program Example: Display 4.9 Driver Program (2 of 3) 4-22 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

23 Driver Program Example: Display 4.9 Driver Program (3 of 3) 4-23 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

24 Stubs Develop incrementally Write "big-picture" functions first – Low-level functions last – "Stub-out" functions until implementation – Example: double unitPrice(int diameter, double price) { return (9.99);// not valid, but noticeably // a "temporary" value } – Calls to function will still "work" 4-24 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

25 Fundamental Testing Rule To write "correct" programs Minimize errors, "bugs" Ensure validity of data – Test every function in a program where every other function has already been fully tested and debugged – Avoids "error-cascading" & conflicting results 4-25 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

26 26 Recursive Functions First – take a look at what C++ (or any programming language) is doing when it hits a function call. “stacking” of current environment.

27 27 Recursive Functions Work well on recursively defined data structures – see example with a list Calculate its length

28  2003 Prentice Hall, Inc. All rights reserved. 28 3.12Recursion Recursive functions –Functions that call themselves –Can only solve a base case If not base case –Break problem into smaller problem(s) –Launch new copy of function to work on the smaller problem (recursive call/recursive step) Slowly converges towards base case Function makes call to itself inside the return statement –Eventually base case gets solved Answer works way back up, solves entire problem

29  2003 Prentice Hall, Inc. All rights reserved. 29 3.12Recursion Example: factorial n! = n * ( n – 1 ) * ( n – 2 ) * … * 1 –Recursive relationship ( n! = n * ( n – 1 )! ) 5! = 5 * 4! 4! = 4 * 3!… –Base case (1! = 0! = 1)

30  2003 Prentice Hall, Inc. All rights reserved. Outline 30 fig03_14.cpp (1 of 2) 1 // Fig. 3.14: fig03_14.cpp 2 // Recursive factorial function. 3 #include 4 5 using std::cout; 6 using std::endl; 7 8 #include 9 10 using std::setw; 11 12 unsigned long factorial( unsigned long ); // function prototype 13 14 int main() 15 { 16 // Loop 10 times. During each iteration, calculate 17 // factorial( i ) and display result. 18 for ( int i = 0; i <= 10; i++ ) 19 cout << setw( 2 ) << i << "! = " 20 << factorial( i ) << endl; 21 22 return 0; // indicates successful termination 23 24 } // end main Data type unsigned long can hold an integer from 0 to 4 billion.

31  2003 Prentice Hall, Inc. All rights reserved. Outline 31 fig03_14.cpp (2 of 2) fig03_14.cpp output (1 of 1) 25 26 // recursive definition of function factorial 27 unsigned long factorial( unsigned long number ) 28 { 29 // base case 30 if ( number <= 1 ) 31 return 1; 32 33 // recursive step 34 else 35 return number * factorial( number - 1 ); 36 37 } // end function factorial 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 The base case occurs when we have 0! or 1!. All other cases must be split up (recursive step).

32 Recursive void Function: Vertical Numbers Task: display digits of number vertically, one per line Example call: writeVertical(1234); Produces output: 1 2 3 4 13-32 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

33 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 13-33 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

34 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; } } 13-34 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

35 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" 13-35 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

36 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 To be used later – Proceeds with evaluation of new recursive call – When THAT call is complete, returns to "outer" computation 13-36 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

37 Recursion Big Picture Outline of successful recursive function: – One or more cases where function accomplishes it’s 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 it’s task without recursive calls Called "base case(s)" or stopping case(s) 13-37 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

38 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 13-38 Copyright © 2010 Pearson Addison-Wesley. All rights reserved.

39 39 A Recursive Power Function Takes a base and exponent (>= 0) and computes the base raised to the exponent. Exercise 3.40 in D&D book. See ~mccoy/Class/cisc181/examples/ rec-power.cc

40  2003 Prentice Hall, Inc. All rights reserved. 40 3.13 Example Using Recursion: Fibonacci Series Fibonacci series: 0, 1, 1, 2, 3, 5, 8... –Each number sum of two previous ones –Example of a recursive formula: fib(n) = fib(n-1) + fib(n-2) C++ code for Fibonacci function long fibonacci( long n ) { if ( n == 0 || n == 1 ) // base case return n; else return fibonacci( n - 1 ) + fibonacci( n – 2 ); }

41  2003 Prentice Hall, Inc. All rights reserved. 41 3.13 Example Using Recursion: Fibonacci Series f( 3 ) f( 1 ) f( 2 ) f( 1 )f( 0 )return 1 return 0 return + +

42  2003 Prentice Hall, Inc. All rights reserved. 42 3.13 Example Using Recursion: Fibonacci Series Order of operations –return fibonacci( n - 1 ) + fibonacci( n - 2 ); Do not know which one executed first –C++ does not specify –Only &&, || and ?: guaranteed left-to-right evaluation Recursive function calls –Each level of recursion doubles the number of function calls 30 th number = 2^30 ~ 4 billion function calls –Exponential complexity

43  2003 Prentice Hall, Inc. All rights reserved. Outline 43 fig03_15.cpp (1 of 2) 1 // Fig. 3.15: fig03_15.cpp 2 // Recursive fibonacci function. 3 #include 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 unsigned long fibonacci( unsigned long ); // function prototype 10 11 int main() 12 { 13 unsigned long result, number; 14 15 // obtain integer from user 16 cout << "Enter an integer: "; 17 cin >> number; 18 19 // calculate fibonacci value for number input by user 20 result = fibonacci( number ); 21 22 // display result 23 cout << "Fibonacci(" << number << ") = " << result << endl; 24 25 return 0; // indicates successful termination The Fibonacci numbers get large very quickly, and are all non-negative integers. Thus, we use the unsigned long data type.

44  2003 Prentice Hall, Inc. All rights reserved. Outline 44 fig03_15.cpp (2 of 2) fig03_15.cpp output (1 of 2) 26 27 } // end main 28 29 // recursive definition of function fibonacci 30 unsigned long fibonacci( unsigned long n ) 31 { 32 // base case 33 if ( n == 0 || n == 1 ) 34 return n; 35 36 // recursive step 37 else 38 return fibonacci( n - 1 ) + fibonacci( n - 2 ); 39 40 } // end function fibonacci Enter an integer: 0 Fibonacci(0) = 0 Enter an integer: 1 Fibonacci(1) = 1 Enter an integer: 2 Fibonacci(2) = 1 Enter an integer: 3 Fibonacci(3) = 2

45  2003 Prentice Hall, Inc. All rights reserved. Outline 45 fig03_15.cpp output (2 of 2) Enter an integer: 4 Fibonacci(4) = 3 Enter an integer: 5 Fibonacci(5) = 5 Enter an integer: 6 Fibonacci(6) = 8 Enter an integer: 10 Fibonacci(10) = 55 Enter an integer: 20 Fibonacci(20) = 6765 Enter an integer: 30 Fibonacci(30) = 832040 Enter an integer: 35 Fibonacci(35) = 9227465

46  2003 Prentice Hall, Inc. All rights reserved. 46 3.14Recursion vs. Iteration Repetition –Iteration: explicit loop –Recursion: repeated function calls Termination –Iteration: loop condition fails –Recursion: base case recognized Both can have infinite loops Balance between performance (iteration) and good software engineering (recursion)


Download ppt "1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 8 September 24, 2009."

Similar presentations


Ads by Google