Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
8 views

Recursion and Storage Classes

Uploaded by

Ulugbek Kushakov
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Recursion and Storage Classes

Uploaded by

Ulugbek Kushakov
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 27

LECTURE 09

Recursion and Storage


Classes

1
Contents
 Storage Classes
 Recursion
 Recursion Vs. Iteration
 Function with Empty Parameter Lists
 Inline Functions
 Reference and Reference Parameter

2
Storage Classes
 A storage class defines the scope (visibility) and
life-time of variables and/or functions within a C+
+ Program. These specifiers precede the type
that they modify. There are following storage
classes, which can be used in a C++ Program.
 auto
 register
 static
 extern
 mutable

3
Storage Classes
The auto keyword allows the compiler to automatically
infer the type of a variable based on its initializer.
 The register keyword hints to the compiler that the
variable should be stored in a CPU register for faster
access (if possible). It's mostly deprecated in modern C+
+ compilers, as they optimize variable storage
automatically.
 The static keyword gives a variable a persistent lifetime
and ensures that its value is retained across function
calls. It can be used for both local and global variables.
 The extern keyword is used to declare a variable or
function that is defined in another file or outside the
current scope. It tells the compiler that the variable
exists, but the definition is elsewhere.

4
1. #include <iostream>
2. using namespace std;
3. // Function declaration
4. void func(void);
5.
6. static int count = 10; /* Global variable */
7.
8. main() {
9. while(count--) {
10. func();
11. }
12.
13. return 0;
14. }
OUTPUT
15. // Function definition
16. void func( void ) {
17. static int i = 5; // local static variable
18. i++;
19. cout << "i is " << i ;
20. cout << " and count is " << count << endl;
21. }

5
Recursion
A recursive function is defined as a function that calls itself to
solve a smaller version of its task until a final call is made which
does not require a call to itself. Every recursive solution has two
major cases, they are:
Base Case: program is simple enough to be solved directly
without making any further calls to the same function.
Recursive Case:
1. The problem at hand is divided into simpler sub parts.
2. The function calls itself but with sub parts of the problem
obtained in the first step.
3. result is obtained by combining the solutions of simpler sub

6
parts.
Recursion
void recurse()
{
... .. ...
recurse();
... .. ...
}
int main()
{
... .. ...
recurse();
... .. ...
}

7
Recursion
 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)

8
1. #include <iostream>
2. using namespace std;

3. unsigned long factorial( unsigned long ); // function prototype


4. int main()
5. {
6. // Loop 10 times. During each iteration, calculate
7. // factorial( i ) and display result.
8. for ( int i = 0; i <= 10; i++ )
9. cout<< i << "! = " << factorial( i ) << endl;
10.
11. return 0; // indicates successful termination
12. } // end main
13. // recursive definition of function factorial
14. unsigned long factorial( unsigned long number )
15. {
OUTPUT
16. // base case
0! = 1
17. if ( number <= 1 ) 1! = 1
18. return 1; 2! = 2
19. 3! = 6
20. // recursive step 4! = 24
5! = 120
21. else
6! = 720
22. return number * factorial( number - 1 );
7! = 5040
23. 8! = 40320
24. } // end function factorial 9! = 362880 9
10! = 3628800
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 );
}

10
Example Using Recursion:
Fibonacci Series

f( 3 )

return f( 2 ) + f( 1 )

return f( 1 ) + f( 0 ) return 1

return 1 return 0

11
1. #include <iostream>
2. using namespace std;
3. unsigned long fibonacci( unsigned long ); // function prototype
4. int main()
5. {
6. unsigned long result, number;
7. // obtain integer from user
8. cout << "Enter an integer: ";
9. cin >> number;
10. // calculate fibonacci value for number input by user
11. result = fibonacci( number );
12. // display result
13. cout << "Fibonacci(" << number << ") = " << result << endl;
14. return 0; // indicates successful termination  Enter an integer: 4
15. } // end main  Fibonacci(4) = 3
16. // recursive definition of function fibonacci  Enter OUTPUT
an integer: 5
 Fibonacci(5) = 5
17. unsigned long fibonacci( unsigned long n ) Enter an integer: 0
 Enter an integer: 6
18. { 
Fibonacci(0) = 0
Fibonacci(6) = 8
19. // base case  Enter an integer: 10
20. if ( n == 0 || n == 1 ) 
Enter an integer: 1
Fibonacci(10) = 55
Fibonacci(1) = 1
21. return n;  Enter an integer: 20
22.  Fibonacci(20) = 6765

Enter an integer: 2
23. // recursive step Enter an integer: 30

Fibonacci(2) = 1
Fibonacci(30) = 832040
24. else  Enter an integer: 35
25. return fibonacci( n - 1 ) + fibonacci( n - 2 ); 
Enter an integer: 3
Fibonacci(35) = 9227465 12
26. } 
Fibonacci(3) = 2
Advantages and Disadvantages
Recursion
 Advantages of C++ Recursion
 It makes our code shorter and cleaner.
 Recursion is required in problems concerning data
structures and advanced algorithms, such as Graph
and Tree Traversal.
 Disadvantages of C++ Recursion
 It takes a lot of stack space compared to an iterative
program.
 It uses more processor time.
 It can be more difficult to debug compared to an
equivalent iterative program.

13
Recursion 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)

14
Empty Parameter Lists
 Empty parameter list
 Specified by writing either void or nothing at
all in parentheses
 For example:
void print();
void print(void);
Specifies that function print does not take
arguments and does not return a value

15
1. #include <iostream>
2. using namespace std;
3. void function1(); // function prototype
4. void function2( void ); // function prototype
5. int main()
6. {
7. function1(); // call function1 with no arguments
8. function2(); // call function2 with no arguments
9. return 0; // indicates successful termination
10. } // end main
11. // function1 uses an empty parameter list to specify that
12. // the function receives no arguments
13. void function1()
14. {
15. cout << "function1 takes no arguments" << endl;
16. } // end function1
OUTPUT
17. // function2 uses a void parameter list to specify that
function1 takes no arguments
18. // the function receives no arguments
function2 also takes no arguments
19. void function2( void )
20. {
21. cout << "function2 also takes no arguments" << endl;
22. } // end function2
23.

16
Inline Functions
 To eliminate the cost of calls to small functions C++ proposes a new
feature called inline function. An inline function is a function that is
expanded in line when it is invoked that is compiler replaces the
function call with the corresponding function code.
 Keyword inline before function
 Reduce function-call overhead

 Compiler can ignore inline

 Good for small, often-used functions


 Example
inline double cube( const double s )
{ return s * s * s; }
 const tells compiler that function does not modify s

17
Remember that inline keyword merely send a request not a command, to
compiler. The compiler may ignore this request if the function
definition is too long or too complicated and compile the function as
normal function.

Some of the situations where inline expansion may not work are:

1. For functions returning values , if a loop, a switch or a goto exists.


2. If function contains static variables.
3. If inline functions are recursive.
1. #include <iostream>
2. using namespace std;
3. // Definition of inline function cube. Definition of function
4. // appears before function is called, so a function prototype
5. // is not required. First line of function definition acts as
6. // the prototype.
7. inline double cube( const double side )
8. {
9. return side * side * side; // calculate cube
10.
11. } // end function cube
12. int main()
13. {
14. cout << "Enter the side length of your cube: ";
15. double sideValue;
16. cin >> sideValue;
OUTPUT
17. // calculate cube of sideValue and display result
Enter the side length of
18. cout << "Volume of cube with side " your cube: 3.5
19. << sideValue << " is " << cube( sideValue ) << endl; Volume of cube with side 3.5
20. return 0; // indicates successful termination is 42.875

21. } // end main


22.

19
1. #include <iostream>
2. using namespace std;

3. inline void displayNum(int num) {


4. cout << num << endl;
5. }

6. int main() {
7. // first function call
8. displayNum(5);

9. // second function call


10. displayNum(8);

11. // third function call


12. displayNum(666);
OUTPUT

13. return 0; 5
14. } 8
666

20
References and Reference
Parameters
 Call by value
 Copy of data passed to function
 Changes to copy do not change original
 Prevent unwanted side effects
 Call by reference
 Function can directly access data
 Changes affect original

21
References and Reference
Parameters
 Reference parameter
 Alias for argument in function call
 Passes parameter by reference
 Use & after data type in prototype
 void myFunction( int &data )
 Read “data is a reference to an int”

 Function call format the same


 However, original can now be changed

22
1. #include <iostream>
2. using namespace std;
3. int squareByValue( int ); // function prototype
4. void squareByReference( int & ); // function prototype
5.
6. int main()
7. {
8. int x = 2;
9. int z = 4;
10.
11. // demonstrate squareByValue
12. cout << "x = " << x << " before squareByValue\n";
13. cout << "Value returned by squareByValue: "
14. << squareByValue( x ) << endl;
15. cout << "x = " << x << " after squareByValue\n" << endl;
16. // demonstrate squareByReference
17. cout << "z = " << z << " before squareByReference" << endl;
18. squareByReference( z );
19. cout << "z = " << z << " after squareByReference" << endl;
20.
21. return 0; // indicates successful termination
22. } // end main
23.

23
24. // squareByValue multiplies number by itself, stores the
25. // result in number and returns the new value of number
26. int squareByValue( int number )
27. {
28. return number *= number; // caller's argument not modified
29.
30. } // end function squareByValue
31. // squareByReference multiplies numberRef by itself and
32. // stores the result in the variable to which numberRef
33. // refers in function main
34. void squareByReference( int &numberRef )
35. {
36. numberRef *= numberRef; // caller's argument modified
37.
38. } // end function squareByReference
OUTPUT

 x = 2 before squareByValue
 Value returned by squareByValue: 4
 x = 2 after squareByValue

 z = 4 before squareByReference
 z = 16 after squareByReference

24
References and Reference
Parameters
 References as aliases to other variables
 Refer to same variable
 Can be used within a function
int count = 1; // declare integer variable count
Int &cRef = count; // create cRef as an alias for count
++cRef; // increment count (using its alias)
 References must be initialized when
declared
 Otherwise, compiler error

25
1. #include <iostream>
2. using namespace std;

3. int main()
4. {
5. int x = 3;
6. // y refers to (is an alias for) x
7. int &y = x;
8.
9. cout << "x = " << x << endl << "y = " << y << endl;
10. y = 7;
11. cout << "x = " << x << endl << "y = " << y << endl;
12.
13. return 0; // indicates successful termination
14.
15. } // end main
OUTPUT

x = 3
y = 3
x = 7
y = 7

26
1. #include <iostream>
2. using namespace std;

3. int main()
4. {
5. int x = 3;
6. int &y; // Error: y must be initialized
7.
8. cout << "x = " << x << endl << "y = " << y << endl;
9. y = 7;
10. cout << "x = " << x << endl << "y = " << y << endl;
11.
12. return 0; // indicates successful termination
13.
14. } // end main

OUTPUT
Borland C++ command-line compiler error message:
Error E2304 Fig03_22.cpp 11: Reference variable 'y' must be
initialized­in function main()

Microsoft Visual C++ compiler error message:


D:\cpphtp4_examples\ch03\Fig03_22.cpp(11) : error C2530: 'y' : 27
references must be initialized

You might also like