0% found this document useful (0 votes)
2 views

lecture 3-5

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

lecture 3-5

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

Storage Class

Features of a storage class:


• Scope
• Lifetime
• Memory
• Default value

BITS Pilani, Pilani Campus


Scope

Scope of a variable
Program depends upon where it
has been defined

File 1 File 2 File K

Inside a Outside all


function functions

Inside a Outside all


block blocks

BITS Pilani, Pilani Campus


Features of Storage Class

Lifetime:
• During program execution
• During function execution

Memory:
• Function Stack
• Heap
• (Initialized & Uninitialized) Data Segment
• Code Segment

BITS Pilani, Pilani Campus


Storage Classes for Variables

• Auto • Static
• Register • Extern

4
BITS Pilani, Pilani Campus
Automatic Storage Class (1/2)

#include<stdio.h>
• Default storage class for block
int main()
{
• Keyword: auto
{ • Scope (Visibility): definition block
• Lifetime (Duration): definition block
auto int i=5;
• Initial Value: Garbage (“indeterminate”
} according to C standard)
{ • Memory: Function Stack
printf("\n%d",i);
} • Output:
Compilation error, i undeclared at printf

return 0;
}

BITS Pilani, Pilani Campus


Automatic Storage Class(2/2)

#include<stdio.h>
• local variable gets precedence over
int main()
non-local variable
{
int i=1;
• Output:
{
• 3
int i=2;
• 2
{
• 1
int i=3;
printf("\n%d",i);
}
printf("\n%d",i);
}
printf("\n%d",i);
return 0;
}

BITS Pilani, Pilani Campus


EXAMPLE
void function1(void); void function2(void)
void function2(void); {
main() int m = 100;
{ function1();
int m = 1000; printf("%d\n",m);
function2(); }
printf("%d\n",m); OUTPUT:
} 10
void function1(void) 100
{ 1000
int m = 10;
printf("%d\n",m);
}
Storage Classes for Variables

• Auto • Static
• Register • Extern

8
BITS Pilani, Pilani Campus
Register storage class

#include<stdio.h> • Keyword: register


int main() • Scope: definition block
{ • Lifetime: definition block
register int i; • Initial Value: Garbage
scanf(“%d”, &i); • Memory:
• CPU register, only if
return 0; • it is available
} • Microprocessor’s register size can accommodate
the size of variable
• Like automatic storage class (otherwise)

• Most compilers don’t allow access to the address of


a register variable.

• Output:
Compilation error

BITS Pilani, Pilani Campus


Storage Classes for Variables

• Auto • Static
• Register • Extern

10
BITS Pilani, Pilani Campus
Static Storage Class (1/3)
Static Local Variable
#include<stdio.h> • Keyword: static
int fun() • Scope: definition block
{ • Lifetime: program
static int count; • Initial Value: 0
count++; • Initialized only once in their lifetime
return count; • Memory: data segment
}

int main() • Output:


{ 1 2
printf("%d ", fun());
printf("%d ", fun());
return 0;
}

BITS Pilani, Pilani Campus


Example:

#include <stdio.h>

void weird( int x )


{ // weird
static int y; /* Persistent */
if ( x == 0 )
printf( "%d\n", y );
else if ( x == 1 )
y = 100;
else if ( x == 2 )
y++;
} //end weird

int main (void)


{ // main
weird(1); /* Set y in weird to 100 */
weird(0); /* Will display 100 */
weird(2); /* Increment y in weird */
weird(0); /* Will display 101 */
return 0;
} // end main

31
Static Storage Class (3/3)
Static Local Variable
#include<stdio.h> • Can be initialized using constant
int initializer(void) literals only
{
return 50;
} • Output:
Compilation error
int main()
{
static int i = initializer();
printf(" value of i = %d", i);
return 0;
} Note:
• Scope of Static Local variable is in
its definition block
• Scope of Static Global variable is in
the file where it has been defined

BITS Pilani, Pilani Campus


Static Storage Class (2/3)

=======
file1.c • Output:
======= In file1
void fun2(){ In file2
printf(“In file1”);
} • If a variable/function is declared
int main(){ static then it’s scope gets limited to
fun2(); its file only
fun1();
} • So, it is visible to functions in the
same file only
=======
file2.c • Variables/Functions with same name can
======= be used in other files as part of
static void fun2(){ multi-file compilation (very useful for
printf(“In file2”); library writers)
}

void fun1(){
fun2();
}

BITS Pilani, Pilani Campus


Storage Classes for Variables

• Auto • Static
• Register • Extern

15
BITS Pilani, Pilani Campus
extern Storage Class (single sourcefile)

•extern is the default storage class for a variable defined


outside a function’s body

•Storage for an extern variable:


• Is allocated when execution begins
• Exists for as long as the program is running

33
• If an extern variable is defined but not initialized:
• Is set to zero (0) once, when storage is allocated

• If an extern variable is simultaneously defined and


initialized:
• Is initialized once, when storage is allocated

• An extern variable is visible in all functions that follow


its definition (i.e., it is global)

34
Example:

#include <stdio.h>

float x = 1.5; /* Definition - extern class - global */

void disp (void)


{
printf("%f\n", x); /* Access global x */
}

int main (void)


{
printf("%f\n", x); /* Access global x */

disp();

return 0;
}

35
Extern Storage Class (1/3)

#include <stdio.h>
• Scope: program
extern int x; • Lifetime: program
• Initial Value: 0
int main() • Memory: data segment
{
printf("x: %d\n", x);
} • Output:
10
int x = 10;

BITS Pilani, Pilani Campus


EXTERNAL VARIABLES
int count;
main()
{
count =10;
.....
}
function()
{
int count =0;
....
count =count+1;
}

• When the function references the variable count, it will


be referencing only its local variable, not the global
one.
• The value of count in main will not be affected.
EXAMPLE
int fun1(void); fun2(void)
int fun2(void); {
int fun3(void); int x ;
int x; x = 1;
main() return(x);
{ }
x = 10; fun3(void)
printf("x =%d\n",x); {
printf("x =%d\n",fun1()); x = x + 10;
printf("x =%d\n",fun2()); }
printf("x =%d\n",fun3()); OUTPUT:
} x = 10
fun1(void) x = 20
{ x =1
x = x + 10; x = 30
}
EXTERNAL VARIABLES
• Once a variable has been declared as global, any function can use it and
change its value.
• Then subsequent functions can reference only that new value.
• Global variable is that it is visible only from the point of declaration
to the end of the program.
main()
{
y = 5;
....
}
int y;
func1()
{
y = y + 1;
}
As far as main is concerned, y is not defined. So, the compiler will issue an
• error message.
Global variables are initialized to zero by default . The
• statement y = y + 1 will assign 1 to y.
EXTERNAL DECLARATION
• The main cannot access the variable y as it has been declared after the
main function.
• This problem can be solved by declaring the variable with the storage
class extern.
main()
{
extern int y; /* external declaration */
....
}
func1()
{
extern int y; /* external declaration */
.....
}
int y; /* definition */
• Although the variable y has been defined after both the functions, the
external declaration of y inside the function informs the compiler that y is
an integer type defined somewhere else in the program.
The extern declaration does not allocate storage space for variables.

MULTIFILE PROGRAMS

• More than one source file is compiled separately and linked later to form
an executable object code.
This approach is very useful because any change in one file does not affect
• other files thus eliminating the need for recompilation of the entire
program.
• Multiple source files can share a variable declared as an external variable.
• Variables that are shared by two or more files are global variables and we
must declare them accordingly in one file and then explicitly define them
with extern in other file.
USE OF EXTERN IN A MULTIFILE PROGRAM

file1.c file2.c

main() int m; / * global variable * /


{ function2()
extern int m; {
int i; int i;
.... .....
} }
function1() function3()
{ {
int j; int count;
.... .....
} }
Extern Storage Class (2/3)

=======
file1.c • If a global variable/function is defined in a
======= file then it can be forward declared by using
extern int var; extern in other files
int main(void)
{ • var is defined in file2.c
var = 10; • var is declared in file1.c i.e. “extern int
printf(“%d “, var); var;” will declare “var” and not define it
return 0;
}
• Output:
======= 10
file2.c
=======
...
int var;
...

BITS Pilani, Pilani Campus


MULTIFILE PROGRAMS

• The extern specifier tells the compiler that the following variables types and
names have already been declared elsewhere and no need to create storage
space for them.
• It is the responsibility of the linker to resolve the reference problem.
• A function defined in one file and accessed in another must include a
function declaration.
• The declaration identifies the function as an external function whose
definition appears elsewhere.
• We place such declarations at the beginning of the file, before all functions.
• Although all functions are external, it would be good practice to explicitly
declare such functions with storage class extern.
Multi-file Compilation

1.Compile and link all files together


– Options:
• By including all the *.c files in driver C file
– All files treated as a single input source code file

2.Compile separately and link in the end


– Include appropriate *.h files, generate *.o files for individual *.c files
and link all of them to generate executable
– Each file is compiled separately so the compiler doesn’t have access
to contents of the other files when compiling a file

BITS Pilani, Pilani Campus


Extern and Static Storage Classes in
presence of Multi-File Compilation

• use extern to forward declare

• use static to reduce scope

BITS Pilani, Pilani Campus


Recursion
• Functions usually call one another in a
disciplined, hierarchical manner
• It’s useful to have functions call themselves.
• A recursive function is a function that calls itself
either directly or indirectly through another
function.
• A recursive function is called to solve a problem.
• The function actually knows how to solve only
the simplest case(s), or so-called base case(s).
Recursion
• If the function is called with a base case, the
function simply returns a result.
• If the function is called with a more complex
problem, the function divides the problem into
two conceptual pieces: a piece that the function
knows how to do and a piece that it does not know
how to do.
• To make recursion feasible, the latter piece must
resemble the original problem, but be a slightly
simpler or smaller version
Recursion
• Because this new problem looks like the original
problem, the function launches (calls) a fresh copy of
itself to go to work on the smaller problem—this is
referred to as a recursive call or the recursion step.
• The recursion step also includes the keyword return,
because its result will be combined with the portion of
the problem the function knew how to solve to form a
result that will be passed back to the original caller.
• The recursion step executes while the original call to
the function is paused, waiting for the result from the
recursion step.
Recursion
• The recursion step can result in many more such
recursive calls, as the function keeps dividing each
problem it’s called with into two conceptual pieces.
• For the recursion to terminate, each time the function
calls itself with a slightly simpler version of the
original problem, this sequence of smaller problems
must eventually converge on the base case.
• When the function recognizes the base case, returns a
result to the previous copy of the function, and a
sequence of returns ensues all the way up the line
until the original call of the function eventually
returns the final result to main.
Recursion
factorial
int factorial(int x) {
if (x <= 1)
return 1;
else
return x * factorial (x-1);

} // factorial
EXAMPLE
#include<stdio.h> int factorial(int x)
#include<conio.h> {
void main() int f;
{ if(x==1)
int a; return(1);
int factorial (int); else
printf("\nEnter the number:"); f=x*factorial (x-1);
scanf("%d",&a); return(f);
printf("The factorial of %d is }
%d",a,factorial(a));
} OUTPUT:
Enter the number:5
The factorial of 5! is120
Fibonacci Example
int fib(int number)
{
if (number == 0) return 0;
if (number == 1) return 1;
return (fib(number-1) + fib(number-2));
}
Fibonacci Numbers
FIBONACCI SERIES USING RECURSION

#include<stdio.h> int Fibonacci(int n)


int Fibonacci(int);
{
main()
if ( n == 0 ) return 0;
{
int n, i = 0, c; else if ( n == 1 ) return 1;
scanf("%d",&n);
else
printf("Fibonacci series\n");
return ( Fibonacci(n-1) +
for ( c = 1 ; c <= n ; c++)
Fibonacci(n-2) );
{
printf("%d\n", Fibonacci(i)); }
i++;
}
return 0;
}
Some Question
• Why recursion?
• Recursion vs Iteration (i.e, loop)?
• When to use recursion instead of loops?
• When to use loops instead of recursion?
Recursion v/s iteration
• Both iteration and recursion are based on a control
statement: Iteration uses a repetition statement;
recursion uses a selection statement.
• Both iteration and recursion involve repetition:
Iteration explicitly uses a repetition statement;
recursion achieves repetition through repeated
function calls.
• Iteration and recursion each involve a termination
test: Iteration terminates when the loop-continuation
condition fails; recursion when a base case is
recognized.
Recursion is expensive
• It repeatedly invokes the mechanism, and consequently
the overhead, of function calls.
• This can be expensive in both processor time and
memory space.
• Each recursive call causes another copy of the function
to be created; this can consume considerable memory.
• The amount of memory in a computer is finite, so only
a certain amount of memory can be used to store stack
frames on the function call stack.
• If more function calls occur than can have their stack
frames stored on the function call stack, a fatal error
known as a stack overflow occurs.

You might also like