1.14 Enumerations and Storage Classes in C Programming
Module 1.14 • Custom Integer Sets, Variable Lifetimes, Scopes & Qualifiers
1.14.1 Introduction
While programming, we often use numbers to represent specific states or categories.
For example:
status = 1;
Looking at the above statement, it is difficult to understand what value 1 represents.
A better approach is:
status = SUCCESS;
This makes programs easier to read and maintain.
C provides Enumerations (enum) to create meaningful names for integer constants. C also provides Storage Classes to control:
- Scope of variables
- Lifetime of variables
- Memory location
- Visibility across files
Part A : Enumerations (enum)
1.14.2 What is an Enumeration?
An enumeration is a user-defined data type consisting of a set of named integer constants.
General Syntax:
enum EnumName
{
Constant1,
Constant2,
Constant3
};
Example:
enum Direction
{
NORTH,
SOUTH,
EAST,
WEST
};
1.14.3 Default Values of Enumerators
By default, enumeration constants start from zero.
Example:
enum Direction
{
NORTH,
SOUTH,
EAST,
WEST
};
Values assigned by compiler:
| Constant | Value |
|---|---|
| NORTH | 0 |
| SOUTH | 1 |
| EAST | 2 |
| WEST | 3 |
1.14.4 Program Using Enum
#include<stdio.h>
enum Direction
{
NORTH,
SOUTH,
EAST,
WEST
};
int main()
{
enum Direction move;
move = EAST;
printf("%d", move);
return 0;
}
Output:
2
1.14.5 Assigning Custom Values
Enumerators can be assigned specific values.
Example:
enum Grade
{
FAIL = 0,
PASS = 50,
DISTINCTION = 75,
EXCELLENT = 90
};
Values are explicitly controlled by the programmer.
1.14.6 Mixed Custom Values
enum Level
{
LOW = 10,
MEDIUM,
HIGH,
CRITICAL = 50,
EMERGENCY
};
Values become:
| Constant | Value |
|---|---|
| LOW | 10 |
| MEDIUM | 11 |
| HIGH | 12 |
| CRITICAL | 50 |
| EMERGENCY | 51 |
1.14.7 Declaring Enum Variables
enum Level current;
Assigning value:
current = HIGH;
1.14.8 Program Using Enum Variable
#include<stdio.h>
enum Traffic
{
RED,
YELLOW,
GREEN
};
int main()
{
enum Traffic signal;
signal = GREEN;
if(signal == GREEN)
{
printf("Proceed");
}
return 0;
}
Output:
Proceed
1.14.9 Enum with Switch Statement
Enums are commonly used with switch statements.
#include<stdio.h>
enum Traffic
{
RED,
YELLOW,
GREEN
};
int main()
{
enum Traffic signal = YELLOW;
switch(signal)
{
case RED:
printf("Stop");
break;
case YELLOW:
printf("Wait");
break;
case GREEN:
printf("Go");
break;
}
return 0;
}
Output:
Wait
1.14.10 Enum for Menu Selection
enum Menu
{
ADD = 1,
DELETE,
UPDATE,
DISPLAY
};
Values:
ADD = 1
DELETE = 2
UPDATE = 3
DISPLAY = 4
1.14.11 Enum for Weekdays
enum WeekDay
{
MONDAY = 1,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
1.14.12 Enum as Permission Flags
Enums can also represent bit flags.
enum Access
{
VIEW = 1,
CREATE = 2,
MODIFY = 4,
REMOVE = 8
};
Binary values:
VIEW = 0001
CREATE = 0010
MODIFY = 0100
REMOVE = 1000
1.14.13 Combining Flags
int rights;
rights = VIEW | MODIFY;
Result:
0101
1.14.14 Checking Permissions
if(rights & MODIFY)
{
printf("Modification Allowed");
}
1.14.15 Advantages of Enumerations
Improved Readability
Instead of: status = 2;, Use: status = APPROVED;
Easier Maintenance
Changes can be made in one place.
Fewer Coding Errors
Meaningful names reduce mistakes.
Better Program Design
Enums document program logic clearly.
1.14.16 Limitations of Enumerations
- Limited to integer values.
- Cannot store strings directly.
- Values are fixed during compilation.
- Cannot dynamically add enumerators.
Part B : Storage Classes
1.14.17 What is a Storage Class?
Storage classes define scope, lifetime, memory location, and visibility of variables and functions.
1.14.18 Types of Storage Classes
C provides four major storage classes:
- auto
- register
- static
- extern
1.14.19 auto Storage Class
auto is the default storage class for local variables.
Example:
auto int num;
Equivalent to:
int num;
Characteristics
| Property | Value |
|---|---|
| Scope | Local |
| Lifetime | Function execution |
| Storage | Stack |
| Default Value | Garbage |
1.14.20 auto Example
#include<stdio.h>
int main()
{
auto int value = 15;
printf("%d", value);
return 0;
}
Output:
15
1.14.21 register Storage Class
register requests the compiler to place variables in CPU registers.
Example:
register int counter;
Advantages
- Faster access
- Useful for loops
- Improve performance
Characteristics
| Property | Value |
|---|---|
| Scope | Local |
| Lifetime | Function |
| Storage | CPU Register |
| Default Value | Garbage |
1.14.22 register Example
#include<stdio.h>
int main()
{
register int i;
for(i=1;i<=5;i++)
{
printf("%d ",i);
}
return 0;
}
Output:
1 2 3 4 5
1.14.23 Limitation of register
Address operator cannot be used.
Invalid:
register int x;
printf("%p",&x);
1.14.24 static Storage Class
static changes the lifetime of variables. A static variable is created only once and exists until program termination.
1.14.25 Local Static Variable
static int count;
Scope remains local. Lifetime becomes entire program execution.
1.14.26 Example of Static Variable
#include<stdio.h>
void demo()
{
static int count = 1;
printf("%d\n",count);
count++;
}
int main()
{
demo();
demo();
demo();
return 0;
}
Output:
1
2
3
1.14.27 Why Static Works
Memory is allocated only once. Value remains preserved between function calls.
1.14.28 Comparison
Automatic Variable: Created → Used → Destroyed
Static Variable: Created Once → Used Entire Program
1.14.29 Static Global Variable
static int total;
Purpose: Restricts access to the current source file.
Benefits of Static Global Variables
- Data hiding
- Reduced naming conflicts
- Better modular design
1.14.31 extern Storage Class
extern is used to access variables defined elsewhere.
Example:
extern int total;
Characteristics
| Property | Value |
|---|---|
| Scope | Global |
| Lifetime | Entire Program |
| Storage | Data Segment |
| Visibility | Multiple Files |
1.14.32 Example of extern
File A
int total = 100;
File B
extern int total;
printf("%d", total);
Output:
100
1.14.33 Storage Class Comparison
| Feature | auto | register | static | extern |
|---|---|---|---|---|
| Scope | Local | Local | Local/Global | Global |
| Lifetime | Function | Function | Entire Program | Entire Program |
| Memory | Stack | Register | Data Segment | Data Segment |
| Default Value | Garbage | Garbage | 0 | 0 |
| Visibility | Block | Block | Restricted | Multiple Files |
Resumed Part C : Function Storage Classes
1.14.34 External Functions
Normal functions are external by default.
void display()
{
}
Accessible from other files through declarations.
1.14.35 Static Functions
static void display()
{
}
Accessible only within the current source file.
Benefits of Static Functions
- Encapsulation
- Information hiding
- Reduced naming conflicts
Part D : const and volatile Qualifiers
1.14.37 const Qualifier
A constant variable cannot be modified.
Example:
const int MAX = 100;
Invalid:
MAX = 200;
1.14.38 const Example
#include<stdio.h>
int main()
{
const int RATE = 18;
printf("%d",RATE);
return 0;
}
Output:
18
1.14.39 Pointer to Constant
const int *ptr;
Allowed:
ptr = &value;
Not Allowed:
*ptr = 50;
1.14.40 Constant Pointer
int *const ptr = &value;
Allowed:
*ptr = 50;
Not Allowed:
ptr = &another;
1.14.41 volatile Qualifier
volatile tells the compiler that the variable may change unexpectedly.
Used in:
- Hardware registers
- Embedded systems
- Interrupt handling
- Shared memory
1.14.42 volatile Example
volatile int sensorValue;
Compiler always reads the latest value from memory.
Part E : Variable Argument Functions
1.14.43 What are Variable Argument Functions?
Functions that accept different numbers of arguments.
Example:
printf();
scanf();
1.14.44 Required Header
#include <stdarg.h>
1.14.45 Important Components
va_list
va_start()
va_arg()
va_end()
1.14.46 Example Program
#include<stdio.h>
#include<stdarg.h>
int sum(int count,...)
{
va_list args;
int total=0;
int i;
va_start(args,count);
for(i=0;i<count;i++)
{
total += va_arg(args,int);
}
va_end(args);
return total;
}
int main()
{
printf("%d",sum(4,10,20,30,40));
return 0;
}
Output:
100
1.14.47 Memory Layout of a C Program
During execution memory is divided into:
- Code Segment
- Data Segment
- Heap
- Stack
Code Segment
Stores executable instructions.
Data Segment
Stores global variables and static variables.
Heap
Stores dynamic memory, malloc(), and calloc().
Stack
Stores local variables, function calls, and parameters.
1.14.48 Summary
- Enumerations create meaningful names for integer constants.
- Enum values start from 0 unless specified.
- Enums improve readability and maintainability.
- Storage classes control scope, lifetime and visibility.
- auto is the default local storage class.
- register suggests storage in CPU registers.
- static preserves values across function calls.
- extern allows sharing variables across files.
- const prevents modification of data.
- volatile prevents compiler optimization for specific variables.
- Variable argument functions use stdarg.h facilities.
- Understanding storage classes is essential for writing efficient and modular C programs.
Click your choice for each question to view feedback immediately. Complete all questions to evaluate your metric score.