Lecture 9:  Scope and Storage Class of variables

 

Objectives of this lecture

q       Learn the extent to which a variable can be used from its point of declaration  -- its scope

q       Lean the period for which a variable has memory space allocated to it – its life-time

q       Differentiate between the various storage classes in C (auto, extern, register and static )

 

Scope of variables

q       The scope of a variable is the extent to which the variable can be used from its point of declaration.

q       In C, the scope of a variable is the block in which it is declared.

q       Variables declared within a function for example, are only accessible within the function.

q       Such variables are called Local variables.

E.g.

#include <stdio.h>

void f(void);

main()

{   int x;

    x=14;

    printf(“\nIn main before function call, x=%d\n”,x);

    f();

    printf(“\nIn main after function call, x=%d\n”,x);

    return 0;

}

 

void f(void)

{   int x;

    x=-2;

    printf(“\nIn the function, x=%d\n”,x);

}

The output is:

In main before function call, x=14

In the function, x=-2

In main after function call, x=14

 

q       A variable declared outside functions is accessible to any function.

q       Such variables are called global variables.

e.g. Consider the following version of the previous program:

#include <stdio.h>

void f(void);

int x;

main()

{   x=14;

    printf(“\nIn main before function call, x=%d\n”,x);

    f();

    printf(“\nIn main after function call, x=%d\n”,x);

    return 0;

}

 

void f(void)

    x=-2;

    printf(“\nIn the function, x=%d\n”,x);

}

The output is:

In main before function call, x=14

In the function, x=-2

In main after function call, x=-2

 

q       It is an important structured programming principle not to use global variables unless it is absolutely necessary.

q       Functions should only access non-local variables through their parameters.

q       This makes programs transparent and easier to maintain.

 

Storage Classes:

q       Closely related to scope of variables, is the life-time of variables – the period of time within which a variable has memory space allocated to it.

q       This is determined by the storage class of the variable.

q       There are four storage classes: auto, extern, register, and static.

 

The Storage class auto

q       This is the most common of the four classes.

q       Variables declared within functions are automatic by default.

 

q       Variables declared as auto are local and are only allocated memory space when the function in which they are declared is called.  The space is returned to the system on exit from the function.

q       Thus their life-time is the period of execution of the function –values from previous function call are lost.

q       The keyword auto can be used in declaration as in: 

auto int a, b, c;

q       However, since the storage class is by default auto, the keyword is seldom used.

 

The Storage class extern

q       Variables declared outside functions are by default extern.

q       Such variables are global, that is they can be used by any function.

q       Memory space assigned to such variables remain for them as long as the program is executing.

q       Thus their life-time is the period of program execution.

Eg.

#include <stdio.h>

int a=1, b=2, c=3;

int f(void);

main()

{   printf(“%3d\n”,f());   /* 12 is printed */

    printf(“%3d%3d%3d\n”,a,b,c);  /* 4  2  3 is printed */

    return 0;

}

 

int f(void)

{   int b, c;

    a=b=c=4;

    return (a+b+c);

}

 

q       Note that even though the external variables a, b, c are global, only a is accessible by the function f(). –Why?

q       We could use the keyword extern as in: 

extern int a=1, b=2, c=3;

q       However, this is not necessary since variables declared outside functions are by default, extern.

 

q       The keyword extern is also used to tell the compiler to look for variables in another file.

e.g.

file1.c

#include <stdio.h>

int a=1, b=2, c=3;

int f(void);

main()

{   printf(“%3d\n”,f());

    printf(“%3d%3d%3d\n”,a,b,c);

    return 0;

}

 

file2.c

int f(void)

{   extern int a;  /* look for it elsewhere */

    int b, c;

    a=b=c=4;

    return (a+b+c);

}

q       The two files can be compiled separately

q       The ability to compile files separately is important when writing large programs.

 

The Storage class register

q       It tells the compiler that the variable be stored in high-speed register if possible.

q       Because of limited number of registers, this storage class defaults to automatic whenever the compiler cannot allocate a register.

q       If you have to declare register variables, declare a few, especially those that are frequently used.  Common candidates are the loop variables.

E.g.

{  register int I;

   for (I=0; I<SIZE; I++)

   {            }

}  /* block exit will free the register  */

 

q       Always remember that register declaration is only an advise to the compiler.

 

The storage class static

q       When used with a local variable, it allows the variable to retain its previous value when the function is re-entered.

e.g. 

void  f(void)

{   static int cnt=0;

     ++cnt;

    if (cnt %2 ==0)

       ……

    else

       …..

}

 

q       The first time the function is called, cnt is initializes to zero.  On exit, its value is preserved.

q       When the function is called again, cnt is not initialized, it retains its previous value.

q       Is this the same as declaring cnt global?  - No, the difference is that declaring cnt static makes it private to the function f(), it cannot be changed by other functions.

q       When static is used with global variables, it makes variables private to the functions in the source file which appear after the declaration.

q       In C, both external and static variables that are not initialized by the programmer are initialized to zero by the compiler.  These include arrays, strings, structures and unions.