Recursion and Implementation of Functions CS2301 System Programming

































































- Slides: 65
Recursion and Implementation of Functions CS-2301 System Programming C-term 2009 (Slides include materials from The C Programming Language, 2 nd edition, by Kernighan and Ritchie and from C: How to Program, 5 th and 6 th editions, by Deitel and Deitel) CS-2301 D-term 2009 Recursion and Function Implementation 1
Definition • Recursive Function: – a function that calls itself • Directly or indirectly • Each recursive call is made with a new, independent set of arguments • Previous calls are suspended • Allows very simple programs for very complex problems CS-2301 D-term 2009 Recursion and Function Implementation 2
Simplest Example int factorial(int x) { if (x <= 1) return 1; else return x * factorial (x-1); } // factorial CS-2301 D-term 2009 Recursion and Function Implementation 3
Simplest Example (continued) int factorial(int x) { if (x <= 1) return 1; else return x * factorial (x-1); } // factorial • This puts the current execution of factorial “on hold” and starts a new one • With a new argument! CS-2301 D-term 2009 Recursion and Function Implementation 4
Simplest Example (continued) int factorial(int x) { if (x <= 1) return 1; else return x * factorial (x-1); } // factorial • When factorial(x-1) returns, its result it multiplied by x • Mathematically: – x! = x (x-1)! CS-2301 D-term 2009 Recursion and Function Implementation 5
Recursion (continued) • There is an obvious circularity here – factorial calls factorial, etc. • But each one is called with a smaller value for argument! – Eventually, argument becomes ≤ 1 – Invokes if clause to terminate recursion CS-2301 D-term 2009 Recursion and Function Implementation 6
Simplest Example int factorial(int x) { if (x <= 1) This if statement “breaks” the recursion return 1; else return x * factorial (x-1); } // factorial CS-2301 D-term 2009 Recursion and Function Implementation 7
Questions? CS-2301 D-term 2009 Recursion and Function Implementation 8
More Interesting Example Towers of Hanoi • Move stack of disks from one peg to another • Move one disk at a time • Larger disk may never be on top of smaller disk CS-2301 D-term 2009 Recursion and Function Implementation 9
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, int c, int b); int main() { int n; printf ("How many disks? "); scanf ("%d", &n); printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0) { move (disks-1, a, c, b); printf ("Move one disk from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 10
Tower of Hanoi Program s et g POST: the– function displays the n i individual moves necessary to a m n d o n i from needle a to sna disks k void move (int disks, int a, funct move e s i v f d on c, mo using needle b as a The ber oneedle int c, int b); i temporary storage needle nct u num */ f s ke o v n int main() { i int n; void move (int disks, int a, printf ("How many disks? "); int c, int b) { scanf ("%d", &n); if (disks > 0){ printf ("n"); move (disks-1, a, c, b); printf ("Move one disk move (n, 1, 3, 2); from %d to %dn", a, c); move (disks-1, b, a, c); return 0; } // if (disks > 0 } // main return; /* PRE: n >= 0; a, b, and c } // move represent some order of the distinct integers 1, 2, 3 #include <stdio. h> CS-2301 D-term 2009 Recursion and Function Implementation 11
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, T int c, int b); he func tion mo v the amain() int ction is { e – where int n; printf ("How many disks? "); scanf ("%d", &n); printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 12
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, int c, int b); int main() { F int n; irst move all b t printfdis("How one of ks to temany udisks? "); the mporar scanf ("%d", &n); y peg printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 13
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, int c, int b); int main() { int n; Next("How , move many disks? "); printf the rem scanfdi("%d", sk to th &n); a e destin ining printf ("n"); a tion pe g move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 14
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, int c, int b); int main() { int n; printf ("How many disks? "); scanf. Fin ("%d", ally, m &n); ove dis printfte("n"); ks m from peg 1, 3, 2); inatio move (n, n porary to dest return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 15
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, c, int b); Notint i ce that move t w i c e, but w{ calls itself int main() ith one diint sks en; fewer ach tim e many disks? "); printf ("How scanf ("%d", &n); printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 16
Why Recursion? • Not often used by programmers with ordinary skills in some areas, but … • … some problems are too hard to solve without recursion – Most notably, the compiler! – Tower of Hanoi problem – Most problems involving linked lists and trees • (Later in the course) CS-2301 D-term 2009 Recursion and Function Implementation 17
Recursion vs. Iteration • Some simple recursive problems can be “unwound” into loops • But code becomes less compact, harder to follow! • Hard problems cannot easily be expressed in non-recursive code • Tower of Hanoi • Robots or avatars that “learn” • Advanced games CS-2301 D-term 2009 Recursion and Function Implementation 18
Recursion is so important … • … that all modern computer architectures specifically support it • Stack register • Instructions for manipulating The Stack • … most modern programming languages allow it • But not Fortran and not Cobol CS-2301 D-term 2009 Recursion and Function Implementation 19
Personal Observation • From my own experience, programming languages and environments that do not support recursion … • … are usually not rich enough to support a diverse portfolio of programs • I. e. , a wide variety of applications in many different disciplines CS-2301 D-term 2009 Recursion and Function Implementation 20
Questions? CS-2301 D-term 2009 Recursion and Function Implementation 21
Data Storage in Memory • Variables may be automatic or static • Automatic variables may only be declared within functions and compound statements (blocks) • Storage allocated when function or block is entered • Storage is released when function returns or block exits • Parameters and result are (somewhat) like automatic variables • Storage is allocated and initialized by caller of function • Storage is released after function returns to caller. CS-2301 D-term 2009 Recursion and Function Implementation 22
Static Data • Static variables may be declared within or outside of functions • Storage allocated when program is initialized • Storage is released when program exits • Static variables outside of functions may be visible to linker • Compiler sets aside storage for all static variables at compiler or link time • Values retained across function calls • Initialization must evaluate to compile-time constant CS-2301 D-term 2009 Recursion and Function Implementation 23
Static Variable Examples int j; //static, visible to linker & all functs static float f; // not visible to linker, visible to // to all functions in this program int fcn (float a, int b) { // nothing inside of {} is visible to linker int i = b; //automatic double g; //automatic static double h; //static, not visible to // linker; value retained from call to call body – may access j, f, a, b, i, g, h } // int fcn( … ) CS-2301 D-term 2009 Recursion and Function Implementation 24
Static Variable Examples (continued) int j; //static, visible to linker & all functs static float f; // not visible to linker, visible to // to all functions in this program De cla int fcn (float a, int b) { rati f u nct on o // nothing inside of {} is visible to linker uts ion st ide : – at int i = b; //automatic a ic lwa any v s ys s double g; //automatic isib tora tati le t ge c static double h; //static, not visible to cla o li s nke s: – // linker; value retained from call to call r not body – may access j, f, a, b, i, g, h } // int fcn( … ) CS-2301 D-term 2009 Recursion and Function Implementation 25
is t l u (continued) a f e d ot – : n on : – i s t s c all functs int j; //static, visible to linkerun& la c c f i t e to e a g static float f; // not visible to linker, visible r d a i om e r s k to lin In athis ut // to all functions in program s c to i at ible t s vis int fcn (float a, int b) { Static Variable Examples // nothing inside of {} is visible to linker int i = b; //automatic double g; //automatic static double h; //static, not visible to // linker; value retained from call to call body – may access j, f, a, b, i, g, h } // int fcn( … ) CS-2301 D-term 2009 Recursion and Function Implementation 26
Static Variable Examples (continued) int j; //static, visible to linker & all functs static float f; // not visible to linker, visible to // to all functions in this program int fcn (float a, int b) { // nothing inside of {} is visible to linker int i = b; //automatic double g; //automatic static double h; //static, not visible to // linker; value retained from call to call body – may access j, f, a, b, i, g, h } // int fcn( … ) CS-2301 D-term 2009 Recursion and Function Implementation No Vtae: v fro lueaoluf e acmr o hoif h osnse s a is reccall lsorret a ursto ionnexetainineed s t d 27
Extern Variables int j; //static, visible to linker & all functs static float f; // not visible to linker, visible to // to all functions in this program extern float p; // static, defined in another program ex int fcn (float a, int b) { te rn // nothing inside of {} is visible tostalinker tic storag e cl ano var int i = b; //automatic i a a the r C ble d ss: – a double g; //automatic ef p static double h; //static, not visible to rogra ined in m // linker; value retained from call to call body – may access j, f, a, b, i, g, h , p } // int fcn( … ) CS-2301 D-term 2009 Recursion and Function Implementation 28
Questions? CS-2301 D-term 2009 Recursion and Function Implementation 29
Automatic Variables, Arguments, & Results • Allocated on The Stack • Definition – The Stack – A last-in, first-out data structure provided by the operating system for each running program – For temporary storage of automatic variables, arguments, function results, and other stuff • Used by all modern programming languages – Even assembly languages for modern processors – … but not Fortran or Cobol! CS-2301 D-term 2009 Recursion and Function Implementation 30
Automatic Variables • Allocated when function or compound statement is entered • Released when function or compound statement is exited • Values not retained from execution to next CS-2301 D-term 2009 Recursion and Function Implementation 31
Arguments and Results • Arguments are values calculated by caller of function • Placed on The Stack by caller for use by function • Function may assign new value to argument, but … • …caller never looks at argument values again! • Result is storage allocated by caller • On The Stack • Assigned by return statement of function • For use by caller • Arguments & result are removed by caller • After function returns, after caller has absorbed return value CS-2301 D-term 2009 Recursion and Function Implementation 32
Typical Implementation of The Stack • Linear region of memory • Stack Pointer “growing” downward • Each time some information is pushed onto The Stack, pointer moves downward • Each time info is popped off of The Stack, pointer moves back upward CS-2301 D-term 2009 Recursion and Function Implementation 33
Typical Memory for Running Program (Windows & Linux) 0 x. FFFF stack (dynamically allocated) SP address space heap (dynamically allocated) static data 0 x 0000 CS-2301 D-term 2009 program code (text) Recursion and Function Implementation PC 34
Typical Memory for Running Program (Windows & Linux) 0 x. FFFF stack (dynamically allocated) SP address space heap (dynamically allocated) static data 0 x 0000 CS-2301 D-term 2009 program code (text) Recursion and Function Implementation He ap in c to be our disc se uss e PC 35 d la ter
How it works • Imagine the following program: – int factorial(int n){ … /* body of factorial function */ … } // factorial • Imagine also the caller: – int x = factorial(100); • What does compiled code look like? CS-2301 D-term 2009 Recursion and Function Implementation 36
Compiled code: the caller int x = factorial(100); • Put the value “ 100” somewhere that factorial function can find • Put the current program counter somewhere so that factorial function can return to the right place in calling function • Provide a place to put the result, so that calling function can find it CS-2301 D-term 2009 Recursion and Function Implementation 37
Compiled code: factorial function • Save the caller’s registers somewhere • Get the argument n from the agreed-upon place • Set aside some memory for local variables and intermediate results • Do whatever factorial was programmed to do • Put the result where the caller can find it • Restore the caller’s registers • Transfer back to the program counter saved by the caller CS-2301 D-term 2009 Recursion and Function Implementation 38
Question: Where is “somewhere”? • So that caller can provide as many arguments as needed (within reason)? • So that called routine can decide at run-time how much temporary space is needed? • So that called routine can call any other routine, potentially recursively? CS-2301 D-term 2009 Recursion and Function Implementation 39
Answer: The Stack • Calling function • Push space for result, and arguments onto stack • Push return address and Jump to called function • Called function • Push registers and automatic storage space onto stack • Do work of the routine, store result in space pushed above • Pop registers and automatic storage off stack • Jump to return address left by calling routine CS-2301 D-term 2009 Recursion and Function Implementation 40
Typical Address Space (Windows & Linux) 0 x. FFFF stack (dynamically allocated) SP Memory address space heap (dynamically allocated) static data 0 x 0000 CS-2301 D-term 2009 program code (text) Recursion and Function Implementation PC 41
Note • Through the magic of operating systems, each running program has its own memory – Complete with stack & everything else • Called a process Windows, Linux, Unix, etc. CS-2301 D-term 2009 Recursion and Function Implementation 42
Note (continued) • Not necessarily true in small, embedded systems • Real-time & control systems • Mobile phone & PDA • Remote sensors, instrumentation, etc. • Multiple running programs share a memory • Each in own partition with own stack • Barriers to prevent each from corrupting others CS-2301 D-term 2009 Recursion and Function Implementation 43
Shared Physical Memory 0 x 0000 FFFF stack Process 3 stack Physical Process 2 memory stack Process 1 OS Kernel 0 x 0000 CS-2301 D-term 2009 Recursion and Function Implementation 44
Questions? CS-2301 D-term 2009 Recursion and Function Implementation 45
Why a Stack? • Engineering reason – Computer architectures without stacks are not “rich” enough to support demands of modern computing • Multiple running programs at the same time • Complex interactions among running programs • Modern computer languages • Mathematical reason – To support recursive programs • Not often used by programmers with ordinary skills , but … • Some problems are too hard to solve without recursion • Most notably, the compiler! CS-2301 D-term 2009 Recursion and Function Implementation 46
Why a Stack? • Engineering reason – Computer architectures without stacks are not “rich” enough to support demands of modern computing • Multiple running programs at the same time • Complex interactions among running programs • Modern computer languages • Mathematical reason – To support recursive programs • Not often used by programmers with ordinary skills, but … • Some problems are too hard to solve without it • Also, advanced games and robotics with “intelligent” objects CS-2301 D-term 2009 Recursion and Function Implementation 47
Tower of Hanoi Program & Use of Stack #include <stdio. h> void move (int disks, int a, int c, int b); int main() { int n; printf ("How many disks? "); scanf ("%d", &n); printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 48
Implementation on The Stack … SP CS-2301 D-term 2009 n Recursion and Function Implementation Stack entry for main 49
Implementation on The Stack (continued) … SP CS-2301 D-term 2009 n return address disks = n a=1 c=3 b=2 Recursion and Function Implementation Stack entry for main Args for call to move 50
Implementation on The Stack (continued) … SP CS-2301 D-term 2009 n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=1 c=2 b=3 Recursion and Function Implementation Stack entry for main Args for call to move Args for 2 nd call to move 51
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=1 c=2 b=3 Stack entry for main Args for call to move Args for 2 nd call to move Args for subsequent calls to move go here CS-2301 D-term 2009 Recursion and Function Implementation 52
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=1 c=2 b=3 Stack entry for main Args for call to move Args for 2 nd call to move Eventually, disks = 0, so no more calls to move All existing calls return CS-2301 D-term 2009 Recursion and Function Implementation 53
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 Stack entry for main Args for call to move Leaving stack like this again CS-2301 D-term 2009 Recursion and Function Implementation 54
Tower of Hanoi Program #include <stdio. h> void move (int disks, int a, int c, int b); int main() { int n; printf ("How many disks? "); scanf ("%d", &n); printf ("n"); move (n, 1, 3, 2); return 0; } // main /* PRE: n >= 0; a, b, and c represent some order of the distinct integers 1, 2, 3 CS-2301 D-term 2009 POST: the function displays the individual moves necessary to move n disks from needle a to needle c, using needle b as a temporary storage needle */ void move (int disks, int a, int c, int b) { if (disks > 0){ move (disks-1, a, c, b); printf ("Move one disk " "from %d to %dn", a, c); move (disks-1, b, a, c); } // if (disks > 0 return; } // move Recursion and Function Implementation 55
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 Stack entry for main Args for call to move now moves one disk from peg 1 to peg 3, and then calls move again! CS-2301 D-term 2009 Recursion and Function Implementation 56
Implementation on The Stack (continued) … SP CS-2301 D-term 2009 n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=3 c=2 b=1 Recursion and Function Implementation Stack entry for main Args for call to move disks back from peg 3 to peg 2 57
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=3 c=2 b=1 Stack entry for main Args for call to move back Args for subsequent calls to move back go here CS-2301 D-term 2009 Recursion and Function Implementation 58
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 return address disks = n-1 a=3 c=2 b=1 Stack entry for main Args for call to move Args for 2 nd call to move Eventually, disks = 0, so no more calls to move All existing calls return CS-2301 D-term 2009 Recursion and Function Implementation 59
Implementation on The Stack (continued) … SP n return address disks = n a=1 c=3 b=2 Stack entry for main Args for call to move Leaving stack like this again, but with all disks moved to peg 3 CS-2301 D-term 2009 Recursion and Function Implementation 60
Implementation on The Stack … SP n Stack entry for main move returns back to main CS-2301 D-term 2009 Recursion and Function Implementation 61
Fundamental Principle • Stack provides a simple mechanism for implementing recursive functions • Arbitrary numbers of intermediate functions • Eventually, something must break the circularity of recursion • Or stack will grow until it overflows memory! CS-2301 D-term 2009 Recursion and Function Implementation 62
Note on Recursive Functions • Some simple recursive functions can be “unwound” into loops – e. g. , int factorial(int n) { return (n <= 1) ? 1 : (n * factorial(n-1)); } //factorial is equivalent to int factorial(int n) { int product = 1; for (int k=1; k <= n; k++) product *= k; return product } //factorial CS-2301 D-term 2009 Recursion and Function Implementation 63
Note on Recursive Functions (continued) • Other recursive functions are much too difficult to understand if unwound • E. g. , Tower of Hanoi • Keeping track of which disk is on which peg requires superhuman intellect, very complex code! CS-2301 D-term 2009 Recursion and Function Implementation 64
Questions? CS-2301 D-term 2009 Recursion and Function Implementation 65

































































