|
|
|
Storage Classes
|
|
Every C variable has a storage class and a scope. The storage class determines the part of memory where storage is allocated for an object and how long the storage allocation continues to exist. It also determines the scope which specifies the part of the program over which a variable name is visible, i.e. the variable is accessible by name. There are four storage classes in C are
automatic, register, external, and static.
|
|
Automatic Variables
|
|
We have already used automatic variables. They are declared at the start of a block. Memory is allocated automatically upon entry to a block and freed automatically upon exit from the block. The scope of automatic variables is local to the block in which they are declared, including any blocks nested within that block. For these reasons, they are also called local variables. No block outside the defining block may have direct access to automatic variables, i.e. by name. Of course, they may be accessed indirectly by other blocks and/or functions using
pointers.
Automatic variables may be specified upon declaration to be of storage class auto. However, it is not required; by default, storage class within a block is auto. Automatic variables declared with
initializes are initialized each time the block in which they are declared is entered.
|
|
Register Variables
|
|
Register variables are a special case of automatic variables. Automatic variables are allocated storage in the memory of the computer; however, for most computers, accessing data in memory is considerably slower than processing in the CPU. These computers often have small amounts of storage within the CPU itself where data can be stored and accessed quickly. These storage cells are called registers.
Normally, the compiler determines what data is to be stored in the registers of the CPU at what times. However, the C language provides the storage class register so that the programmer can ``suggest'' to the compiler that particular automatic variables should be allocated to CPU registers, if possible. Thus, register variables provide a certain control over efficiency of program execution. Variables which are used repeatedly or whose access times are critical, may be declared to be of storage class register.
#include<stdio.h>
#include<conio.h>
void main()
{
register float a=0;
auto int bb=1;
autto char cc = 'w';
/* Rest of the program */
} |
Register variables behave in every other way just like automatic variables. They are allocated storage upon entry to a block; and the storage is freed when the block is exited. The scope of register variables is local to the block in which they are declared. Rules for initializations for register variables are the same as for automatic variables.
As stated above, the register class designation is merely a suggestion to the compiler. Not all implementations will allocate storage in registers for these variables, depending on the number of registers available for the particular computer, or the use of these registers by the compiler. They may be treated just like automatic variables and provided storage in memory.
Finally, even the availability of register storage does not guarantee faster execution of the program. For example, if too many register variables are declared, or there are not enough registers available to store all of them, values in some registers would have to be moved to temporary storage in memory in order to clear those registers for other variables. Thus, much time may be wasted in moving data back and forth between registers and memory locations. In addition, the use of registers for variable storage may interfere with other uses of registers by the compiler, such as storage of temporary values in expression evaluation. In the end, use of register variables could actually result in slower execution. Register variables should only be used if you have a detailed knowledge of the architecture and compiler for the computer you are using. It is best to check the appropriate manuals if you should need to use register variables.
|
|
External Variables
|
|
All variables we have seen so far have had limited scope (the block in which they are declared) and limited lifetimes (as for automatic variables). However, in some applications it may be useful to have data which is accessible from within any block and/or which remains in existence for the entire execution of the program. Such variables are called global variables, and the C language provides storage classes which can meet these requirements; namely, the external and static classes.
External variables may be declared outside any function block in a source code File the same way any other variable is declared; by specifying its type and name. No storage class specifier is used - the position of the declaration within the File indicates external storage class. Memory for such variables is allocated when the program begins execution, and remains allocated until the program terminates. For most C implementations, every byte of memory allocated for an external variable is initialized to zero.
The scope of external variables is global, i.e. the entire source code in the File following the declarations. All functions following the declaration may access the external variable by using its name. However, if a local variable having the same name is declared within a function, references to the name access the local variable cell.
|
#include<stdio.h>
void next(void);
void next1(void);
int a1=1;
void main()
{
printf(" Scope of External Variables
\n\n");
a1=2;
printf("a1=%d\n",a1);
next();
printf("a1=%d\n",a1);
next1();
printf(" a1= %d\n",a1);
}
int b1=0;
void next(void)
{
char a1;
a1='a';
b1=77;
printf("a1= %c,b1=%d\n",a1,b1);
}
void next1(void)
{
float b1;
b1=19.2;
a1=13;
peintf("a1=%d.b1=%f\n",a1,b1);
} |
External variables may be initialized in declarations just as automatic variables; however, the
initializes must be constant expressions. The initialization is done only once at compile time, i.e. when memory is allocated for the variables variables.
In general, it is a good programming practice to avoid use of external variables as they destroy the concept of a function as a ``black box''. The black box concept is essential to the development of a modular program with modules. With an external variable, any function in the program can access and alter the variable, thus making debugging more difficult as well. This is not to say that external variables should never be used. There may be occasions when the use of an external variable significantly simplifies the implementation of an algorithm. Suffice it to say that external variables should be used rarely and with caution.
|
|
Static Variables
|
|
As we have seen, external variables have global scope across the entire program (provided extern declarations are used is Files other than where the variable is defined), and a lifetime over the the entire program run. The storage class, static, similarly provides a lifetime over the entire program, however; it provides a way to limit the scope of such variables, Static storage class is declared with the keyword static as the class
specifier when the variable is defined. These variables are automatically initialized to zero upon memory allocation just as external variables are. Static storage class can be specified for automatic as well as external variables.
Static automatic variables continue to exist even after the block in which they are defined terminates. Thus,
the value of a static variable in a function is retained between repeated function calls to the
same function. The scope of static automatic variables is identical to that of automatic variables, i.e. it is local to the block in which it is defined; however, the storage allocated becomes permanent for the duration of the program. Static variables may be initialized in their declarations; however, the
initializes must be constant expressions, and initialization is done only once at compile time when memory is allocated for the static variable.
#include<stdio.h>
#include<conio.h>
#define MAX 5
void sumit();
void main()
{
int count;
printf("Static Variables\n");
printf("Enter 5 nubers to be summed\n");
for(count=0;count<MAX;count++)
sumit();
printf("Program Completed");
}
void sumit(void)
{
static int sum=0;
int num;
printf("Enter a number");
scanf("%d",&num);
sum+=num;
printf("The curent total is %d",sum);
}
|
While the static variable, sum, would be automatically initialized to zero, it is better to do so explicitly. In any case, the initialization is performed only once at the time of memory allocation by the compiler.
The variable sum retains its value during program execution. Each time the function sumit() is called, sum is incremented by the next integer read.
Static storage class designation can also be applied to external variables. The only difference is that static external variables can be accessed as external variables only in the file in which they are defined. No other source file can access static external variables that are defined in another file.
/* file: xxx.c */
static int count;
static char name[8];
main()
{
... /* program body */
}
|
Only the code in the file xxx.c can access the external variables count and name. Other files cannot access them, even with extern declarations.
We have seen that external variables should be used with care, and access to them should not be available indiscriminately. Defining external variables to be static provides an additional control on which functions can access them. For example, in the symbol.c example in the last section, we created a file symio.c which contained an external variable. This external variable should be accessible only to the functions in that file. However, there is no way to guarantee that some other file may not access it by declaring it as extern. We can ensure that this will not happen by declaring the variable as static as
#include<stdio.h>
#include "symdef.h"
static int c =NULL;
int getchr()
{
int ch;
if(c)
{
ch=c;
c=NULL;
return(ch);
}
else
return(getchar());
}
void ungetchr(int cc)
{
c=cc;
}
|
The static variable c would not be accessible to functions defined in any other file, thus preventing an unplanned use of it as an external variable by the code in other files.
|
|
Back
|
|
Next
|
|
|