Learn C Programming
Storage Classes in C
In C programming, storage classes determine the lifetime, visibility, and scope of variables. There are four main storage classes in C:
- Automatic Storage Class
- Static Storage Class
- External Storage Class
- Register Storage Class
Automatic Storage Class
Automatic (auto): The default storage class for local variables declared within a function or a block is โauto.โ Variables declared with โautoโ come into existence when entering the block and get destroyed when exiting it. The explicit use of the keyword โautoโ is rare since it represents the default behavior for local variables.
For instance:
void exampleFunction() {
auto int localVar;
// "auto" is optional here (same as just "int localVar;")
// Rest of the function code
}
In this example, we have a function called exampleFunction. Inside this function, we declare a local variable localVar. The โautoโ keyword is optional here because it is the default storage class for local variables. The function creates the variable localVar when called and destroys it when it returns, limiting its lifetime to the scope of the function.
Static Storage Class
Static (static):ย The โstaticโ storage class behaves differently based on whether we use it with a local variable or a global variable.
- With local variables: When you use โstaticโ with a local variable, the variable keeps its value between function calls. It means the variable holds its value across function invocations. The variable is initialized only once and keeps its value throughout the programโs lifetime.
- With global variables: When โstaticโ is used with a global variable, it limits the scope of that variable to the file in which it is declared. This means the variable is not accessible from other files using extern. It effectively gives the variable internal linkage.
For instance:
void exampleFunction() {
static int counter = 0;
counter++;
printf("Counter: %d\n", counter);
}
In this example, we have a function called exampleFunction. Inside the function, we have a static local variable counter.ย
During the programโs execution, we initialize the variable โcounterโ only once, and it keeps its value across different calls to exampleFunction. Each time we call the function, the counter increments, and it maintains its value throughout the programโs lifetime.
External Storage Class
External (extern): The โexternโ storage class is used to declare variables that are defined in other files.
When we declare a variable as โextern,โ it indicates that the variable exists and has a type, but it belongs to another location. The file where we define it will handle the actual memory allocation for the variable.
For instance:
// File1.c
int globalVar;
// This is a global variable defined in File1.c
// File2.c
extern int globalVar;
/* This is just a declaration indicating that
globalVar is defined elsewhere.*/
In this example, we have two separate C files: File1.c and File2.c.
We defined a global variable called globalVar in File1.c.ย
File2.c needs to use a global variable defined in another file. To inform the compiler about the variableโs existence elsewhere, we must specify its location.
Thatโs why we use the extern keyword to declare the globalVar in File2.c, telling the compiler that the actual definition of the variable is in File1.c.
Register Storage Class
Register (register): The โregisterโ storage class suggests to the compiler that a variable should reside in a CPU register rather than RAM memory. Note that the โregisterโ keyword is just a suggestion, and the compiler may or may not place the variable in a register, depending on its own optimizations.
For instance:
void exampleFunction() {
register int x;
/* Suggests that the variable x should be stored
in a CPU register.*/
// Rest of the function code
}
In this example, we have a function called exampleFunction. Inside the function, we declare a variable x with the register keyword. This suggests to the compiler that it should try to store the variable x in a CPU register for faster access, rather than using RAM memory. However, itโs essential to note that the โregisterโ keyword is just a hint to the compiler, and the compiler may or may not honor this suggestion depending on its optimization strategies and hardware constraints. Modern compilers often ignore the use of register since compilers can automatically optimize the storage of variables depending on their usage patterns.
Modern compilers mostly ignore the โregisterโ keyword usage due to their advanced optimizations, and the effects of these storage classes may vary depending on the compiler and platform.