STORAGE CLASSES


Variables in C language are not only data types but are also of storage class.
They provide information about locality and visibility of variables. Depending upon the declaration of variables they are of two types.

  1. Global variables: These are the variables which are declared before the main function and they can be used in any function with in the program.
  2. Local variables: These are the variables which are declared with in the main function and they can be used with in that function only.
EX:
int d;
void main()
{
	char c,e;
}

In the above example variable d is globally declared and can be used in any function where as c and e are declared locally and can be used with in that function only.

Storage classes

To fully define a variable one needs to mention not only its ‘type’ but also its ‘storage class’. In other words, not only do all variables have a data type, they also have a ‘storage class’.

We have not yet mentioned storage classes yet, though we have written several programs in C.We were able to get away with this because storage classes have defaults. If we don’t specify the storage class of a variable in its declaration, the compiler will assume a storage class depending on the context in which the variable is used. Thus variables have certain default storage classes.

From C compiler’s point of view, a variable name identifies some physical location within the computer where the string of bits representing the variable’s value is stored. There are basically two kinds of locations in a computer where such a value may be kept: Memory and CPU registers. It is the variable’s storage class that determines in which of these two locations the value is stored.

Moreover, a variable’s storage class tells us:
(a) Where the variable would be stored.
(b) What will be the initial value of the variable, if initial value is not specifically assigned (i.e. the default initial value).
(c) What is the scope of the variable i.e. in which functions the value of variable would be available.
(d) What is the life of the variable i.e. how long would the variable exist.

There are four storage classes available in ‘C’:

  1. Automatic Storage class.
  2. Register Storage class.
  3. Static Storage class.
  4. External Storage class.


Automatic Storage class: The features of a variable defined to have an automatic storage class are as under:
Storage : Memory
Default initial value : unpredictable value which is often called a garbage value.
Scope : Local to the block in which the variable is defined.
Life : Till the control remains within the block in which the Variable is defined.
Keyword : Auto
The variables are declared inside a function block are automatic variables. A variable declared inside a function block without a storage class name, by default is an auto variable.
Example: program that shows the default values of automatic variables.

main ()
{ 
	auto int i,j;
	printf("\n %d %d",i ,j);
}

The output of the above program would be ….
1432    2313
Where 1432 and 2313 are the garbage values of i and j. When you run this program you may get different values, since garbage values are unpredictable. So always make it a point that you initialize the automatic variables properly, otherwise you are likely to get unexpected results.
Example: program that shows the scope and lifetime of an automatic variable.

main()
{  
	auto int =1;
	{
		auto int i=2;
		{
			auto int i=3;
			printf( "\n %d",i);
		}
		printf("%d", i); 
	}
	printf( "%d", i);
}

The output of the above program would be:
3   2   1
Explanation: In the above program the compiler treats the three i’s as totally different variables, since they are defined in different blocks. Once the control comes out of the innermost block the variable i with the value 3 is lost, and hence the i in the second printf () refers to i with value 2. Similarly, when the control comes out of the next innermost block, the third printf () refers to the i with value 1.

Register storage class

The features of a variable defined to be of register storage class are as under:
Storage : CPU registers.
Default initial value : unpredictable value which is often called a garbage value.
Scope : Local to the block in which the variable is defined.
Life : Till the control remains within the block in which the Variable is defined.
Keyword : register.

We can also keep some variables in the CPU registers instead of memory. The keyword register tells the compiler that the variable list followed by it is kept on the CPU registers, since register access is faster than the memory access. So, the variables that are declared with storage class register are known as register variables.
Example:

main()
{ 
	register int i; 
	for(i=1 ; i<=10; i++ )
		printf( " %d ", i);
}

In the above example the space for variable i will be allocated in registers.
Here, even though we have declared the storage class of i as register, we cannot say for sure that the value of i would be stored in a CPU register. Why? Because the number of CPU registers are limited (14 in case of a micro computer), and they may be busy doing some other task. What happens in such a event…. the variable works as if its storage class is auto.
We cannot use register storage class for all types of variables. For example, the following declarations are wrong:
register float a;
register long c;
register double a;

This is because CPU registers in a microcomputer are usually 16 bit registers and therefore cannot hold a float value or a double value, which require 4 and 8 bytes respectively for storing a value. However, if you use the above declarations you won’t get any error messages. All that would happen is the compiler would treat the variables to be of auto storage class.

Static Storage class

The features of a variable defined to have a static storage class are as under:
Storage : Memory.
Default initial value : Zero.
Scope : Local to the block in which the variable is defined.
Life : Value of the variable persists between different function Calls.
Keyword : static.

The static variable may be of an internal or external type, depending upon where it is declared. If declared outside the function of the body it will be static global. In case it is declared in the body or block it will be auto variable. A static variable is initialized only once, it is never reinitialized.
Example: program that shows the difference between automatic and static storage classes.

main ()                  main()
{                        {
increment ();            increment();
increment ();            increment();
increment ();            increment();
}                        }
increment ()             increment ()
{                        {
auto int i=1;            static int i=1;
printf ( "%d \n", i);    printf( " %d\n", i);
i=i+1;                   i=i+1;
}                        }

The output of the programs would be: 
1	1
1	2
1   3


Explanation: In the above example, when variable i is auto, each time increment () is called it is re-initialized to one. When the function terminates, i vanishes and its new value of 2 is lost. The result: no matter how many times we call increment (), i is initialized to 1 every time.
On the other hand if i is static, it is initialized to only one once. It is never initialized again. During the first call to increment (), i is incremented to 2.Because I is static, the value persists. The next time increment () is called, i is not re-initialized to 1.On the contrary its old value 2 is still available. This current value of (i.e. 2) gets printed and then i=i+1 adds 1 to i to get a value of 3. When increment () is called third time, the current value of i (i.e. 3) gets printed and once again i is incremented. In short if storage class is static then the statement static int i=1 is executed only once irrespective of how many times the same function is called.

External Storage class

The features of a variable whose storage class has been defined as external as follows:
Storage : Memory.
Default initial value : Zero.
Scope : Global.
Life : As long as the program’s execution doesn’t comes to end.
Keyword : extern.

The variables that are available to all the functions i.e. from entire program they can be accessed are known as external or global variables. External variables are declared outside the function body. In case both external and auto variables are declared with the same name, in a program the first priority is given to the auto variable. In this case external variable is hidden.
Example: program that shows the default value, scope and life time of a global variable.

#include< stdio.h>
#include< conio.h>
int i ;
void main()
{
	extern int i;
	printf( "\n i=%d", i );
	increment();
	increment();
	decrement();
	decrement();
}
increment()
{
	i=i+1;
	printf("\n On incrementing i= %d",  i);
}
decrement()
{
	i=i-1;
	printf("\n On decrementing j= %d", j);
}
								


The output of the above program would be:
i=0
On incrementing i=1
On incrementing i=2
On decrementing j=1
On decrementing j=0
Explanation: In the above output it is clear that the value of i is available to l the functions increment() and decrement() since i is declared outside all the functions.