1 of 21

Storage Classes

*

1

2 of 21

Storage Classes

  • Variables or identifiers consume memory
  • Some variables are used only within a small portion of the program.
    • Eg: Some are used only within a function.
    • Some are used only within a loop structure.
    • Some are used only within a block.
  • Then, why these should exist throughout the program?
  • But, some might be required throughout the program. Perhaps some global information you need should be accessible and available throughout the program.
  • Some times you want to use again and again same names for identifiers (like j, k, etc) but are actually distinct. Eg: j used in one function and j used in some other function might be different.

*

2

3 of 21

Storage Classes

void f_1(int j, int k)

{

int total = 0;

…..;

……;

}

float f_2(int k)

{

int total = 1;}

*

3

These two total are different

These two k are different

So, it is good to do : when f_1( ) is called total in f_1 can be created and destroyed when f_1( ) is over.

4 of 21

Storage Classes

int total_no_stud;

int main( )

{ …;

a = find_average( … );

b = find_max( … );

… ;

}

float find_average( … )

{ …;

avg = total/total_no_stud;

…;

}

*

4

float find_max( … )

{

…;

for(j =0; j< total_no_stud; j++) {

…;

}

…;

}

total_no_stud should be same in both functions, since it is a global information.

5 of 21

Storage Classes

  • Various categories of identifiers are required.
  • These categories are determined by
    1. Where the identifier is declared
    2. Keywords used as prefixes in the declaration.
  • These categories are broadly called as storage classes.

*

5

6 of 21

Storage Classes

  • C provides 4 storage classes, viz.,
    1. auto
    2. register
    3. extern
    4. static
  • An identifier storage class determines its storage duration, scope, and linkage.
  • We will see what these mean, etc.

*

6

7 of 21

auto

  • An identifier declared within a block with keyword auto
    • auto is default and hence can be omitted.
  • These are created when the block is entered and destroyed when the block is over.
  • Can be accessed only within the block in which they are declared.

*

7

8 of 21

auto

  • int main( ) {

int a; /* auto int a; */

a = 50;

{

int a;

a = 100;

printf(β€œ%d\n”, a);

}

printf(β€œ%d\n”, a);

a ++;

printf(β€œ%d\n”, a);

}

*

8

$ ./a.out

100

50

51

$

9 of 21

auto ( Let us remove interior declaration)

  • int main( ) {

int a;

a = 50;

{

int a;

a = 100;

printf(β€œ%d\n”, a);

}

printf(β€œ%d\n”, a);

a ++;

printf(β€œ%d\n”, a);

}

*

9

$ ./a.out

100

100

101

$

10 of 21

Scope means where the identifier can be referenced in a program

  • int main( ) {

int a;

a = 50;

{

int a;

a = 100;

printf(β€œ%d\n”, a);

}

printf(β€œ%d\n”, a);

a ++;

printf(β€œ%d\n”, a);

}

*

10

Scope of this a is the main function

Scope of this a is within the interior braces

Interior a, if declared, hides the exterior a.

In this case, exterior a is invisible from interior block.

11 of 21

Storage duration

  • This is the period during which that identifier exists in memory.
  • Identifiers declared with auto and register are of automatic storage duration. These are created when the block declaring them are entered and exit when that block is over.
  • Some times, an identifier may exist in memory, but it may not be accessible.
    • Then, one way to access these elements are through addresses.
    • This, we discuss along with pointers, later.
  • This fact, often we say that, the identifier is invisible.

*

11

12 of 21

register

  • register storage class is very much similar to auto
  • Eg: register int counter = 1;
  • This specifies that counter needs to be allocated space in a high speed hardware register. So that accessing it would be very fast.
  • But, compiler may ignore this, and treat it as an ordinary automatic variable. Since, registers are of limited number and sometimes it may not be possible to allocate a register for the variable.
  • Also, often explicitly stating register is unnecessary. Now a days, smart compilers can recognize a frequently used variable and can automatically place it in a register.

*

12

13 of 21

Static storage duration

  • Keywords extern and static are used to declare that the identifier is of static storage duration.
  • Identifiers of static storage duration exist from the point at which the program begins till the end of the program.
  • Functions also are of static storage. (names of functions exists throughout the program).

*

13

14 of 21

Static storage duration

  • There are two types of identifiers with static storage duration:
    • 1. Global variables and function names
    • 2. Local variables declared with the storage class specifier static.
  • Global variables and function names are of storage class extern by default.
  • Global variables are created by placing their declaration outside any function definition.

*

14

15 of 21

Global variables

  • Global variables and functions can be referenced by any function that follows their declaration or definition in the file.
  • This is one reason for using function prototypes.
  • When we include stdio.h in a program that calls printf, the function prototype is placed at the start of the file to make the name printf known to the rest of the file.

*

15

16 of 21

Global Variables

  • Global variables should be used only when they are needed.
  • Because any function can access the global variables, errors can commonly occur.

*

16

17 of 21

Static variables

  • Local variables declared with keyword static like

static int count = 1;

are local to the function in which they are declared but retains its value even after the function is exited.

  • All numeric variables of static storage duration are initialized to zero if they are not explicitly initialized.
  • But initialization is done only for the first time (not on subsequent function calls)

*

17

18 of 21

static

void f_1(void);

int main( )

{

f_1();

f_1();

f_1();

}

void f_1(void)

{

static int count = 1;

printf(β€œ%d\n”, count);

count ++;

}

*

18

$./a.out

1

2

3

$

19 of 21

static

void f_1(void);

int main( )

{

f_1();

f_1();

f_1();

}

void f_1(void)

{

static int count;

count = 0;

printf(β€œ%d\n”, count);

count ++;

}

*

19

$./a.out

0

0

0

$

20 of 21

Static

  • static local variables are useful to monitor recursive calls

int fib(int n)

{

static int counter = 0;

counter ++;

printf(β€œIn fib with counter = %d \n”, counter);

if (n==0) return 1;

else return n*fib(n-1);

}

*

20

What is the output if we call fib(4) ?

And now ?

21 of 21

extern and static

  • Keywords extern and static have special meaning when explicitly applied to external identifiers.
  • This is an advanced topic and will be discussed along with linkage, etc., later.

*

21