C ProgrammingUnit 98 min read
Structures, Unions, Enums: Data Grouping & Memory Efficiency
Unit 9 of C Programming: Explores how to bundle related data into structures, unions, and enumerations, their memory layouts, operations, and real-world uses in apps like eSewa transactions and Daraz order tracking.
TAKEAWAYS:
- Structures group heterogeneous data under a single name, enabling logical data organization (e.g., employee records).
- Unions share the same memory block for multiple variables, saving space but requiring careful use (e.g., storing either a phone number or email in a contact).
- Enumerations define symbolic integer constants (e.g.,
enum Day {MON, TUE, WED}) for cleaner code. - Memory alignment and size differ between structures, unions, and arrays—critical for performance optimization.
- Structures can be nested and passed to functions, while unions require explicit type casting.
- Real-world examples: eSewa uses structures to store transaction details; Daraz employs enums for order statuses.
1. Introduction to Structures
A structure is a user-defined data type that groups multiple variables of different types under a single name. It allows storing related data logically.
Syntax
struct <tag> {
<data_type> <member1>;
<data_type> <member2>;
...
};
- Tag: Optional identifier for type declaration (e.g.,
struct Employee). - Members: Variables inside the structure.
Example: Employee Record
classDiagram
Employee : +int id
Employee : +char name[50]
Employee : +float salary
Employee : +char post[20]Declaration and Initialization
struct Employee emp1 = {101, "John", 50000.0, "Manager"};
struct Employee emp2; // Default initialization (garbage values)
Accessing Members
printf("ID: %d\n", emp1.id);
scanf("%s", emp2.name); // Note: %s for strings
Memory Layout
graph TD
A["Memory Address"] --> B["emp1.id (int, 4 bytes)"]
B --> C["emp1.name (char[50], 50 bytes)"]
C --> D["emp1.salary (float, 4 bytes)"]
D --> E["emp1.post (char[20], 20 bytes)"]Key Points:
- Size of a structure is the sum of its members (rounded up to the nearest multiple of the largest member’s alignment).
- Structures can be nested:
struct Address { char city[30]; int pincode; }; struct Employee { int id; char name[50]; struct Address addr; // Nested structure };
2. Operations on Structures
(a) Input/Output
#include <stdio.h>
struct Employee {
int id;
char name[50];
float salary;
};
int main() {
struct Employee e;
printf("Enter ID: ");
scanf("%d", &e.id); // Use & for non-string members
printf("Enter Name: ");
scanf(" %[^\n]", e.name); // Read full line
printf("Enter Salary: ");
scanf("%f", &e.salary);
printf("\nDetails:\nID: %d\nName: %s\nSalary: %.2f\n", e.id, e.name, e.salary);
return 0;
}
(b) Passing Structures to Functions
void display(struct Employee e) {
printf("ID: %d\nName: %s\n", e.id, e.name);
}
int main() {
struct Employee e = {101, "Alice"};
display(e); // Pass by value (copy)
return 0;
}
Pass by Reference (Pointers):
void display(struct Employee *e) {
printf("ID: %d\n", (*e).id); // or e->id
}
(c) Array of Structures
struct Employee emp[3] = {
{101, "Bob", 45000},
{102, "Charlie", 55000},
{103, "Diana", 60000}
};
Worked Example: Filter Employees by Post
Problem: Display details of employees with post = "clerk". Solution:
#include <stdio.h>
#include <string.h>
struct Employee {
int id;
char name[50];
char post[20];
float salary;
};
int main() {
struct Employee emp[3] = {
{101, "Alice", "Manager", 50000},
{102, "Bob", "Clerk", 30000},
{103, "Charlie", "Clerk", 32000}
};
for (int i = 0; i < 3; i++) {
if (strcmp(emp[i].post, "Clerk") == 0) {
printf("ID: %d, Name: %s, Salary: %.2f\n",
emp[i].id, emp[i].name, emp[i].salary);
}
}
return 0;
}
Output:
ID: 102, Name: Bob, Salary: 30000.00
ID: 103, Name: Charlie, Salary: 32000.00
3. Unions: Memory Efficiency at a Cost
A union shares the same memory block for all its members. Only one member can hold a value at a time.
Syntax
union Data {
int i;
float f;
char str[20];
};
Memory Layout
graph TD
A["Memory Address"] --> B["union Data (size = largest member, 20 bytes)"]
B --> C["Member 'i' (int, 4 bytes)"]
B --> D["Member 'f' (float, 4 bytes)"]
B --> E["Member 'str' (char[20], 20 bytes)"]Key Differences: Structure vs. Union
| Feature | Structure | Union |
|---|---|---|
| Memory Usage | Sum of all members | Size of largest member |
| Access | All members accessible | Only one member active at a time |
| Use Case | Group related data (e.g., employee) | Optimize memory (e.g., flags) |
| Initialization | All members initialized | Only first member initialized |
Example: Storing Contact Info
union Contact {
long phone;
char email[50];
};
int main() {
union Contact c;
c.phone = 9812345678; // Use phone
printf("Phone: %ld\n", c.phone);
// c.email = "test@example.com"; // Overwrites phone!
return 0;
}
Disadvantage:
- Data Loss: Writing to one member overwrites others.
- No Direct Comparison: Cannot compare unions directly (use
memcmpfor byte comparison).
4. Enumerations (Enums): Symbolic Constants
Enums define a set of named integer constants.
Syntax
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN };
- Internally,
MON = 0,TUE = 1, etc.
Example: Order Status
enum OrderStatus { PENDING, SHIPPED, DELIVERED, CANCELLED };
Usage in Functions
void printStatus(enum OrderStatus status) {
switch (status) {
case PENDING: printf("Order pending\n"); break;
case SHIPPED: printf("Order shipped\n"); break;
default: printf("Invalid status\n");
}
}
Memory Efficiency
- Enums occupy 1 byte (or more, depending on range) per variable.
5. Typedef for Cleaner Syntax
typedef creates aliases for complex types.
Example
typedef struct {
int id;
char name[50];
} Employee;
Employee e1 = {101, "Eve"}; // No 'struct' keyword needed
6. Real-World Applications
(a) eSewa Transaction Records
- Structure Use: Stores
transaction_id,amount,timestamp,status(e.g.,PENDING,COMPLETED). - Example:
struct Transaction { int id; float amount; enum Status { PENDING, COMPLETED, FAILED } status; };
(b) Daraz Order Tracking
- Enum Use: Tracks order status (
NEW,PROCESSING,SHIPPED,DELIVERED). - Worked Example:
enum OrderStatus { NEW, PROCESSING, SHIPPED, DELIVERED }; OrderStatus status = PROCESSING; if (status == PROCESSING) { printf("Order is being processed.\n"); }
(c) Pathao Driver Shift Logs
- Union Use: Stores either
distance_covered(float) orfuel_used(float) in a single memory block.union ShiftData { float distance; float fuel; };
7. Exam Tips
Structures vs. Unions:
- Always compare memory usage and access patterns.
- Use structures for grouped data; unions for memory optimization.
Enumerations:
- Prefer enums over
#definefor symbolic constants (safer and type-checked). - Example:
enum Color { RED, GREEN, BLUE };instead of#define RED 1.
- Prefer enums over
Pointers with Structures:
- Passing structures by pointer (
struct Employee *) is efficient for large data. - Example:
void updateSalary(struct Employee *e, float newSalary) { e->salary = newSalary; }
- Passing structures by pointer (
Array of Structures:
- Common in exams (e.g., "Store 5 student records and display names").
- Use loops to iterate:
for (int i = 0; i < 5; i++) { printf("%s\n", students[i].name); }
Common Pitfalls:
- Forgetting
&for non-string members inscanf. - Overwriting union members without intention.
- Not initializing structures (leads to garbage values).
- Forgetting
Code Structure:
- Always declare structures before
main(). - Use
typedeffor cleaner code in larger programs.
- Always declare structures before
Final Note: Structures and unions are foundational for real-world data handling. Master their memory behavior and operations to ace exams and build scalable programs!
Based on the TU BIT syllabus for C Programming (BIT102), unit 9.
Discussion
Loading…