C Notes
Complete guide to storage classes in C: auto, register, static, and extern. Understand variable lifetime, scope, linkage, default values, and when to use each storage class with examples.
Storage classes determine four important properties of a variable: its storage location (memory or CPU register), lifetime (how long it exists), scope (where it's accessible), and default initial value. C provides four storage class specifiers: auto, register, static, and extern. Understanding these gives you fine-grained control over variable behavior in your programs.
Overview of Storage Classes
| Storage Class | Storage | Lifetime | Scope | Default Value |
|---|---|---|---|---|
auto | Stack (RAM) | Until function returns | Local to block | Garbage |
register | CPU Register (suggestion) | Until function returns | Local to block | Garbage |
static (local) | Data segment (RAM) | Entire program | Local to block | 0 |
static (global) | Data segment (RAM) | Entire program | File only | 0 |
extern | Data segment (RAM) | Entire program | Global (multi-file) | 0 |
auto — Automatic Storage Class
auto is the default storage class for all local variables. You rarely see it written explicitly because it's implied for any variable declared inside a function or block.
#include <stdio.h>
void demonstrate() {
auto int x = 10; // Explicitly auto (unnecessary)
int y = 20; // Implicitly auto (same thing)
printf("x = %d, y = %d\n", x, y);
}
// x and y are DESTROYED when demonstrate() returns
int main() {
demonstrate();
demonstrate(); // x and y are re-created each call
// Uninitialized auto variable has garbage value
int uninit;
printf("Uninitialized auto: %d (garbage!)\n", uninit);
return 0;
}x = 10, y = 20 x = 10, y = 20 Uninitialized auto: 32767 (garbage!)
Key characteristics of auto:
- Stored on the stack
- Created when the block is entered, destroyed when it exits
- Must be explicitly initialized (contains garbage otherwise)
- Cannot be accessed outside its scope
- The
autokeyword is almost never written in practice
register — Register Storage Class
The register keyword is a hint to the compiler to store the variable in a CPU register instead of RAM for faster access. Modern compilers are smart enough to make this optimization themselves, so register is largely obsolete.
Sum 1 to 1000000 = 1784293664
Key characteristics of register:
- Only a suggestion — compiler may ignore it
- Cannot use
&(address-of) operator on register variables - Limited to block scope (like auto)
- Best for frequently accessed variables (loop counters)
- Modern compilers optimize this automatically, making the keyword unnecessary
static — Static Storage Class
The static keyword is the most useful and interesting storage class. It has different effects depending on where it's used:
Static Local Variables
A static local variable retains its value between function calls — it's initialized only once and persists for the program's entire lifetime:
Called 1 time(s) Called 2 time(s) Called 3 time(s) Auto count: 1 (always 1) Auto count: 1 (always 1) Auto count: 1 (always 1)
Practical Uses of Static Local Variables
IDs: 101, 102, 103 Avg after 10: 10.0 Avg after 20: 15.0 Avg after 30: 20.0 Fib(10) = 55 Fib(20) = 6765
Static Global Variables and Functions
When static is applied to a global variable or function, it limits visibility to that file only (internal linkage):
// file1.c
#include <stdio.h>
// This variable can only be used within file1.c
static int fileLocalVar = 42;
// This function can only be called from within file1.c
static void helperFunction() {
printf("I'm a private helper: %d\n", fileLocalVar);
}
void publicFunction() {
helperFunction(); // Can call from same file
printf("I'm accessible from other files\n");
}// file2.c
extern void publicFunction(); // OK - visible
// extern int fileLocalVar; // ERROR - static, not visible!
// extern void helperFunction(); // ERROR - static, not visible!
int main() {
publicFunction(); // Works
return 0;
}extern — External Storage Class
The extern keyword declares that a variable is defined in another file or elsewhere in the program. It doesn't allocate memory — it just tells the compiler "this variable exists somewhere else."
Sharing Variables Between Files
// globals.c - Definition (allocates memory)
int sharedCounter = 0;
float pi = 3.14159;Counter: 0 Counter: 2 Pi: 3.141590
extern with Functions
Function declarations are implicitly extern — you can use functions defined in other files without explicitly writing extern:
// math_utils.c
int add(int a, int b) {
return a + b;
}// main.c
#include <stdio.h>
// Both are equivalent:
extern int add(int a, int b); // Explicit extern
// int add(int a, int b); // Implicit extern (same thing)
int main() {
printf("3 + 4 = %d\n", add(3, 4));
return 0;
}Comparison Example
Call 1: auto=1, static=1, register=1, global=100 Call 2: auto=1, static=2, register=1, global=101 Call 3: auto=1, static=3, register=1, global=102
Notice:
autoVarandregVarare always 1 (recreated each call)staticVarincrements across calls (persists)globalVaralso persists and increments
Default Initial Values
#include <stdio.h>
int globalInt; // Default: 0
float globalFloat; // Default: 0.0
char globalChar; // Default: '\0'
int *globalPtr; // Default: NULL
int main() {
static int staticInt; // Default: 0
static float staticF; // Default: 0.0
int autoInt; // Default: GARBAGE!
float autoFloat; // Default: GARBAGE!
printf("Global int: %d\n", globalInt);
printf("Global float: %f\n", globalFloat);
printf("Global ptr: %p\n", (void*)globalPtr);
printf("Static int: %d\n", staticInt);
printf("Auto int: %d (garbage!)\n", autoInt);
return 0;
}Global int: 0 Global float: 0.000000 Global ptr: (nil) Static int: 0 Auto int: 32651 (garbage!)
When to Use Each Storage Class
| Scenario | Use |
|---|---|
| Normal local variables | auto (default, don't write it) |
| Value must persist between calls | static local |
| Limit global visibility to one file | static global |
| Share variables across files | extern |
| Performance-critical loop counter | register (usually unnecessary) |
Interview Questions
Q1: What is the difference between a static local variable and a global variable?
Both persist for the program's entire lifetime and are initialized to 0 by default. The difference is scope: a static local variable is only accessible within its function, providing encapsulation. A global variable is accessible from any function in the file (or other files with extern), which can lead to naming conflicts and uncontrolled access.
Q2: What does static mean for a function in C?
When applied to a function, static gives it internal linkage — the function can only be called from within the same source file. It's essentially a "private" function, hidden from other files. This is useful for helper functions that shouldn't be part of a module's public API.
Q3: What is the difference between declaration and definition with extern?
extern int x; is a declaration — it tells the compiler "x exists somewhere" without allocating memory. int x = 5; (or just int x; at file scope) is a definition — it allocates memory and optionally initializes the variable. A variable can be declared many times but defined only once.
Q4: Why can't you take the address of a register variable?
CPU registers don't have memory addresses — they're not part of RAM. Since register suggests storing the variable in a register (not memory), taking its address with & is not allowed. The compiler enforces this even if it decides to keep the variable in memory.
Q5: What happens to a static variable when the function is called recursively?
There's only ONE instance of a static variable regardless of how many recursive calls are active. All recursive invocations share the same static variable. This contrasts with auto variables, where each recursive call gets its own independent copy on the stack.
Summary
autois the default for locals: stack storage, block scope, garbage initial valueregistersuggests register storage for speed, but compilers usually ignore itstaticlocal variables persist between function calls and are initialized to 0staticglobal variables/functions are restricted to their file (internal linkage)externdeclares a variable defined elsewhere (no memory allocation)- Global and static variables default to 0; auto variables contain garbage
- Use
staticfor persistent state andexternfor cross-file variable sharing
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Storage Classes in C Programming.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, functions, storage, classes, storage classes in c programming
Related C Programming Topics