functions and recursion
DESCRIPTION
Lecture notes on functions and recursion in C++TRANSCRIPT
2/14/2013
1
CS 101: Introduction to C tiComputing
Dr. Samit BhattacharyaDept. of Comp. Sc. & Engg.,IIT Guwahati, Assam, India
Topics to be covered
• Flo chart basic idea• Flowchart – basic idea
• Conditional statements
• Iteration and loops
• FunctionsFunctions
2/14/2013
2
Functions in C
Example
#include <stdio.h>
i tN Li () {C programming is easyBut you still fail!
Guess what the output is
printNewLine() {
printf(“\n”);
}
main() {
printf(“C programming is easy”);
printNewLine();
But, you still fail!
We have used a function in the program. The function’s name is printNewLine().This function serves to display a new line
printf(“But, you still fail!”);
}
2/14/2013
3
Example
#include <stdio.h>
printNewLine() {
During the execution, the program starts in main function. When reach statement printNewLine(), the statement(s) defined within the function will
printf(“\n”);
}
main() {
printf(“C programming is easy”);
printNewLine();
i tf(“B t till f il!”)
the statement(s) defined within the function will be executed. When it finishes, it will return back to the main function and execute the next statement.
printf(“But, you still fail!”);
}
Why Function• Divide and conquer
– Manageable program development– Manageable program development
• Software reusability– Use existing functions as building blocks for new programs– Abstraction - hide internal details (library functions)
• Avoid code repetition
2/14/2013
4
Function Definition• Format
return-value-type function-name( parameter-list ){
declarations and statements}
– Function-name: any valid identifier– Return-value-type: data type of the result (default int)
• void – indicates that the function returns nothing
– Parameter-list: comma separated list, declares parameters• A type must be listed explicitly for each parameter unless, the
parameter is of type int
Function Definition• Format
return-value-type function-name( parameter-list ){{
declarations and statements}
– Declarations and statements: function body (block)• Variables can be declared inside blocks (can be nested)• Functions can not be defined inside other functions
Returning control– Returning control• If nothing returned
– return;– or, until reaches right brace
• If something returned – return expression;
2/14/2013
5
Function Prototypes
• Function prototype F ti– Function name
– Parameters – what the function takes in– Return type – data type function returns (default int)– Prototype only needed if function definition comes after
use in program– The function with the prototypep yp
int maximum( int, int, int );• Takes in 3 ints• Returns an int
Example#include <stdio.h>
Void printNewLine(); Function prototypemain() {
printf(“C programming is easy”);
printNewLine();
printf(“But, you still fail!”);
}
printNewLine() { Function Definition or
Function call
p () {printf(“\n”);
}Function Implementation
2/14/2013
6
Header Files
• Header filesC t i f ti t t f lib f ti– Contain function prototypes for library functions
– <stdlib.h> , <math.h> , etc– Load with #include <filename>
#include <math.h>• Custom header files
Create file with functions– Create file with functions – Save as filename.h– Load in other files with #include "filename.h"– Reuse functions
Function Calling
• Call by valueC f t d t f ti– Copy of argument passed to function
– Changes in function do not effect original– Use when function does not need to modify argument
• Avoids accidental changes
• Call by reference – Passes original argumentPasses original argument– Changes in function effect original– Only used with trusted functions
• For now, we focus on call by value
2/14/2013
7
Storage Classes
• Storage class specifiersSt d ti h l bj t i t i– Storage duration – how long an object exists in memory
– Scope – where object can be referenced in program– Linkage – specifies the files in which an identifier is
known
Storage Classes
• Automatic storageObj t t d d d t d ithi it bl k– Object created and destroyed within its block
– auto: default for local variables auto double x, y;
– register: tries to put variable into high-speed registers• Can only be used for automatic variables
register int counter = 1;register int counter 1;
2/14/2013
8
Storage Classes
• Static storage– Variables exist for entire program execution– Default value of zero– static: local variables defined in functions
• Keep value after function ends• Only known in their own function
– extern: default for global variables and functionsg• Known in any function
Scope Rules
• File scope– Identifier defined outside function, known in all functions– Used for global variables, function definitions, function
prototypes
• Function prototype scope– Used for identifiers in parameter listUsed for identifiers in parameter list
2/14/2013
9
Scope Rules
Scope Rules
• Block scope Id tifi d l d i id bl k– Identifier declared inside a block
• Block scope begins at declaration, ends at right brace– Used for variables, function parameters (local variables of
function)– Outer blocks "hidden" from inner blocks if there is a
variable with the same name in the inner block
2/14/2013
10
Scope Rules
• Function scope– Can only be referenced inside a function body– Used only for labels with goto statements (start:, case: ,
etc.)
2/14/2013
11
Scope Rules
What is the output?
2/14/2013
12
Recursion
• C offers two approaches to repetitive programming –loops and recursionloops and recursion
• We define recursion when a function calls itself
The Nature of Recursion1. One or more simple cases of the problem (called the
stopping cases or base case) have a simple non-recursivesolution.
2. The other cases of the problem can be reduced (usingrecursion) to problems that are closer to stopping cases.
3. Eventually the problem can be reduced to stopping casesonly, which are relatively easy to solve.
In general:if (stopping case)
solve itelse
reduce the problem using recursion
2/14/2013
13
Four Criteria1. A recursive function calls itself
– This action is what makes the solution recursive
2 E h i ll l id ti l b t ll bl2. Each recursive call solves an identical, but smaller, problem– A recursive function solves a problem by solving another problem that is
identical in nature but smaller in size
3. A test for the base case enables the recursive calls to stop– There must be a case of the problem (known as base case or stopping case)
that is handled differently from the other cases (without recursively calling itself)I th b th i ll t d th bl i l d di tl– In the base case, the recursive calls stop and the problem is solved directly
4. Eventually, one of the smaller problems must be the base case– The manner in which the size of the problem diminishes ensures that the base
case is eventually is reached
Four Questions for Constructing Recursive Solutions
1 How can you define the problem in terms of a smaller1. How can you define the problem in terms of a smaller problem of the same type?
2. How does each recursive call diminish the size of the problem?
3. What instance of the problem can serve as the base case?case?
4. As the problem size diminishes, will you reach this base case?
2/14/2013
14
Factorial Function – Iterative Definition
n! = n * (n-1) * (n-2) * … * 2 * 1 for any integer n>0( ) ( ) y g0! = 1
Iterative Definition in C:fval = 1;for (i = n; i >= 1; i--)for (i n; i 1; i )
fval = fval * i;
• To define n! recursively, n! must be defined in terms
Factorial Function – Iterative Definition
yof the factorial of a smaller number
• Observation (problem size is reduced):n! = n * (n-1)!
• Base case: 0! = 1• We can reach the base case by subtracting 1 from n if n• We can reach the base case, by subtracting 1 from n if n
is a positive integer
2/14/2013
15
Recursive Definition:
Factorial Function – Iterative Definition
n! = 1 if n = 0n! = n*(n-1)! if n > 0
// Computes the factorial of a nonnegative integer.// Precondition: n must be greater than or equal to 0.
Factorial Function – Iterative Definition
// Postcondition: Returns the factorial of n; n is unchanged.
int fact(int n){
if (n ==0) return (1);
else return (n * fact(n-1));
}This fact function satisfies the four criteria of a recursive solution
2/14/2013
16
Recursive Factorial
Review• All recursive functions have two critical elements:
– The recursive function call either solves one part of the problem OR …The recursive function call either solves one part of the problem OR …– … the call reduces the size of the problem
• The statement that solves the problem is called the base case. Every recursive function must have a base case
• The rest of the function is called the general case• The rest of the function is called the general case, which reduces the size of the problem
2/14/2013
17
Review1. Determine the base case2 Determine the general case2. Determine the general case3. While paying close attention to logic, design a
function that combines the base case with the general case
Each recursive call must reduce the size of theEach recursive call must reduce the size of the problem and move it toward the base case. The base case must not include a recursive call, but must include a return
Tracing a Recursive Function
• To trace a recursive function, the box method canbe used– The box method is a systematic way to trace the actions
of a recursive function– Illustrates how compilers implement recursion
2/14/2013
18
The Box Method (for a valued function)
1. Label each recursive call in the body of the recursive function• For each recursive call, we use a different label to distinguish
different recursive calls in the body• These labels help us to keep track of the correct place to which we
must return after a function call completes• After each recursive call, we return to the labeled location, and
substitute that recursive call with returned valued
if (n ==0) return (1);
else return (n * fact(n-1) )
A
The Box Method (continued)2. Each time a function is called, a new box represents its local
environment. Each box contains: – the values of the arguments – the function local variables– A placeholder for the value returned from each recursive call from
the current box (label in step 1)– The value of the function itself
2/14/2013
19
The Box Method (continued)3. Draw an arrow from the statement that initiates the recursive process
to the first box– Then draw an arrow to a new box created after a recursive call,
put a label on that arrow
printf(“%d”, fact (3));
The Box Method (continued)
4. After a new box is created, we start to execute the body of the function
5. On exiting a function, cross off the current box and follow its arrow back to the box that called the function– This box becomes the current box– Substitute the value returned by the just-terminated function call
into the appropriate item in the current box– Continue the execution from the returned point
2/14/2013
20
Box Trace of fact(3)
Box Trace of fact(3)
2/14/2013
21
Box Trace of fact(3)
Multiplying Rabbits – The Fibonacci Sequence
• Rabbits give birth so often. If rabbits did not die, their population would be quickly get out of handquickly get out of hand
• Let us assume that:– Rabbits never die– A rabbit reaches sexual maturity exactly two months after birth (at the
beginning of its third month of life)– Rabbits are always born male-female pairs– At the beginning of every month, each sexually mature male-female pair
gives birth to exactly one male-female pairgives birth to exactly one male female pair
• Question: – Suppose we start with a single newborn male-female pair in the first month– What will be the number rabbit pairs in month n?
2/14/2013
22
Multiplying Rabbits – First Seven Months
Month 1: 1 pairMonth 2: 1 pair
– since it is not yet sexually matureMonth 3: 2 pairs
– 1 original pair + a newborn pair from the original pair because it is now sexually mature
Month 4: 3 pairs– 2 pairs alive in month 3 + a newborn pair from original pair
Month 5: 5 pairs– 3 pairs alive in month 4 + 2 new newborn pairs from 2 pairs alive in month 33 pairs alive in month 4 2 new newborn pairs from 2 pairs alive in month 3
Month 6: 8 pairs– 5 pairs alive in month 5 + 3 new newborn pairs from 3 pairs alive in month 4
Month 7: 13 pairs– 8 pairs alive in month 6 + 5 new newborn pairs from 5 pairs alive in month 5
Recursive Solution
Observation:– All of the pairs alive in month n-1 cannot give birth atAll of the pairs alive in month n 1 cannot give birth at
the beginning of month n– Only, all of the pairs alive in month n-2 can give birth– The number pairs in month n is the sum of the number
of pairs alive in month n-1 plus the number rabbits alive in month n-2
Recurrence relation for the number of pairs in month n:Recurrence relation for the number of pairs in month n:
rabbit(n) = rabbit(n-1) + rabbit(n-2)
2/14/2013
23
Recursive Solution• Two base cases are necessary because there are two smaller
problems.problems.– rabbit(1) = 1 rabbit(2) = 1
Recursive Solution:rabbit(n) = 1 if n is 1 or 2rabbit(n) = rabbit(n-1) + rabbit(n-2) if n > 2
• The series of numbers rabbit(1), rabbit(2), rabbit(3), … is known as Fibonacci Sequence
Recursive Solution in C// Computes a term in the Fibonacci sequence.// Precondition: n is a positive integer.// Postcondition: Returns the nth Fibonacci
number.int rabbit(int n){
if (n <= 2)return 1;
else // n > 2, so n-1 > 0 and n-2 > 0return (rabbit(n-1) + rabbit(n-2));
} // end rabbit
• This rabbit function computes Fibonacci sequence
2/14/2013
24
Recursive Calls for rabbit(7)
Limits of Recursion• Because recursion involves function calls, recursive
algorithms cost overheadalgorithms cost overhead
• Algorithms that include deep recursion (includes a large number of recursive function calls) may use too much memory
• However, it is still better to design some algorithms (especially those dealing with data structures)