Structured Programming in CUnit 711 min read
Structures & Unions: Data Packaging & Memory Efficiency
Unit 7 of Structured Programming in C covers structures (grouping related data) and unions (memory-efficient alternatives), their syntax, differences, and real-world applications in databases, financial records, and network packets. Learn how to define, access, and use them with pointers, and compare their memory usage
TAKEAWAYS:
- Structures bundle heterogeneous data (e.g.,
studentwithname,roll,marks) under one name, accessed via.or->. - Unions share memory for multiple variables (e.g.,
employeestoring eithersalaryorhourly_wage), saving space but risking data corruption. - Key differences: structures allocate memory for all members; unions allocate memory for the largest member only.
- Pointers to structures (
struct *ptr) enable dynamic memory allocation and linked data (e.g.,studentrecords in a class). - Real-world uses: eSewa (transaction records), Ncell (customer billing), NEPSE (stock portfolio tracking).
- Always initialize unions carefully to avoid garbage values in unused members.
1. Structures: Organizing Related Data
A structure (struct) groups variables of different types under a single name. It mimics real-world entities (e.g., a student has a name, roll, and marks).
Syntax & Definition
struct student {
char name[50];
int roll;
float marks;
};
- Members: Variables inside the structure (e.g.,
name,roll). - Declaration:
struct student s1;creates an instance. - Access: Use
.(dot operator) or->(arrow operator for pointers).
Example: Student Record
#include <stdio.h>
#include <string.h>
struct student {
char name[50];
int roll;
float marks;
};
int main() {
struct student s1;
strcpy(s1.name, "Ramesh");
s1.roll = 101;
s1.marks = 85.5;
printf("Name: %s, Roll: %d, Marks: %.2f\n", s1.name, s1.roll, s1.marks);
return 0;
}
Output:
Name: Ramesh, Roll: 101, Marks: 85.50
Memory Layout
- Total size:
50 (name) + 4 (roll) + 4 (marks) = 58 bytes(padding may add extra bytes for alignment).
Pointers to Structures
struct student *ptr = &s1;
printf("Roll: %d\n", ptr->roll); // Equivalent to (*ptr).roll
Use case: Linked lists of student records in a class roster.
2. Unions: Memory Efficiency at a Cost
A union shares memory for all members. Only one member holds a value at a time.
Syntax & Definition
union employee {
int salary;
float hourly_wage;
};
- Memory: Allocates space for the largest member (e.g.,
floatuses 4 bytes). - Access: Same as structures (
union_name.member).
Example: Employee Payroll
union employee emp;
emp.salary = 50000;
printf("Salary: %d\n", emp.salary); // Output: 50000
```figure
{"type":"array","values":[{"name":"emp1","fields":[{"name":"salary","value":"50000","type":"int","offset":0,"shared":true},{"name":"hourly_wage","value":"null","type":"float","offset":0,"shared":false}],"total_size":4},{"name":"emp2","fields":[{"name":"salary","value":"null","type":"int","offset":0,"shared":false},{"name":"hourly_wage","value":"250.5","type":"float","offset":0,"shared":true}],"total_size":4}],"caption":"Union memory usage: only one field active per instance (4 bytes each)"}
emp.hourly_wage = 250.5;
printf("Hourly wage: %.2f\n", emp.hourly_wage); // Output: 250.50
Warning: After assigning hourly_wage, salary becomes undefined (garbage value).
Memory Layout
- Total size:
4 bytes(size offloat).
When to Use Unions
- Network packets: Storing either an
IPaddress or aportnumber. - Database records: Alternate fields (e.g.,
phoneoremail). - Hardware registers: Reading/writing different bits as integers or floats.
3. Key Differences: Structures vs. Unions
| Feature | Structure | Union |
|---|---|---|
| Memory Allocation | Sum of all members | Size of the largest member |
| Data Access | All members valid simultaneously | Only one member valid at a time |
| Use Case | Grouped data (e.g., student) |
Memory optimization (e.g., IP/port) |
| Initialization | Safe (all members initialized) | Risky (uninitialized members) |
| Example | struct date { int day, month; } |
union data { int x; float y; } |
4. Real-World Applications
In Nepal
eSewa Transactions
- Uses structures to store:
struct transaction { char user_id[20]; int amount; char status[10]; // "Success"/"Failed" }; - Why? Bundles related data (user, amount, status) for processing.
- Uses structures to store:
Ncell Billing System
- Uses unions to store either:
union payment { int prepaid_balance; float postpaid_bill; }; - Why? Saves memory by reusing space for
prepaidorpostpaiddata.
- Uses unions to store either:
NEPSE Stock Portfolio
- Structures track:
struct stock { char symbol[10]; int quantity; float price; }; - Example: A portfolio with 100 shares of
NTCat ₹100/share and 50 shares ofNMBat ₹500/share.
- Structures track:
Global Examples
WhatsApp Messages
- Uses unions in its protocol buffer to store either:
- A
textmessage or - An
imagemetadata (without duplicating memory).
- A
- How? Saves bandwidth by sharing memory for different message types.
- Uses unions in its protocol buffer to store either:
Google’s Protocol Buffers
- Uses unions to define flexible message formats:
message UserProfile { oneof kind { string email = 1; string phone = 2; } } - Why? Efficient serialization for APIs.
- Uses unions to define flexible message formats:
Bank Loan Calculations
- Structures store loan details:
struct loan { char customer[50]; float principal; float rate; int tenure; }; - Example: Calculate monthly EMI for a ₹500,000 loan at 8% for 10 years:
float emi = (loan.principal * loan.rate * (1 + loan.rate)^tenure) / ((1 + loan.rate)^tenure - 1);
- Structures store loan details:
5. Common Pitfalls & Best Practices
Uninitialized Unions
- Always initialize the member you’ll use:
union data d; d.x = 10; // Safe // printf("%d", d.y); // Undefined behavior!
- Always initialize the member you’ll use:
Pointer Arithmetic
- Structures:
ptr++moves bysizeof(struct). - Unions:
ptr++moves bysizeof(union).
- Structures:
Nested Structures
- Combine structures for complex data:
struct address { char city[30]; int pincode; }; struct employee { char name[50]; struct address addr; };
- Combine structures for complex data:
Typedef for Simplicity
- Avoid
structkeyword repetition:typedef struct student { char name[50]; int roll; } Student; Student s1; // No 'struct' needed
- Avoid
6. Worked Example: Student Database
Task: Store 3 students and print their details using structures.
#include <stdio.h>
#include <string.h>
typedef struct {
char name[50];
int roll;
float marks;
} Student;
int main() {
Student students[3];
int i;
// Input data
for (i = 0; i < 3; i++) {
printf("Enter name, roll, marks for student %d:\n", i+1);
scanf("%s %d %f", students[i].name, &students[i].roll, &students[i].marks);
}
// Print data
printf("\nStudent Records:\n");
for (i = 0; i < 3; i++) {
printf("Name: %s, Roll: %d, Marks: %.2f\n",
students[i].name, students[i].roll, students[i].marks);
}
return 0;
}
Sample Input/Output:
Enter name, roll, marks for student 1:
Ramesh 101 85.5
Enter name, roll, marks for student 2:
Sita 102 90.0
Enter name, roll, marks for student 3:
Hari 103 78.5
Student Records:
Name: Ramesh, Roll: 101, Marks: 85.50
Name: Sita, Roll: 102, Marks: 90.00
Name: Hari, Roll: 103, Marks: 78.50
Trace Table:
| Step | students[0].name |
students[0].roll |
students[0].marks |
|---|---|---|---|
| 1 | "Ramesh" | 101 | 85.5 |
| 2 | "Sita" | 102 | 90.0 |
| 3 | "Hari" | 103 | 78.5 |
7. Exam Tip: How to Score Full Marks
Define Clearly
- Always start with:
struct name { type member1; type member2; };
- Always start with:
Compare Structures vs. Unions
- Exam question: "List 3 differences between structures and unions."
- Answer:
- Memory allocation (sum vs. largest member).
- Data validity (all vs. one member at a time).
- Use case (grouped data vs. memory optimization).
Show Memory Layouts
- Draw diagrams for:
- Structure size calculation.
- Union memory sharing.
- Draw diagrams for:
Code Correctness
- Use
typedefto simplify syntax. - Initialize unions before access.
- Use
Real-World Link
- Relate to eSewa transactions, Ncell billing, or bank loans in explanations.
In the real world
- eSewa Transaction Records: Uses
structto bundleuser_id,amount, andstatus(success/failure) for each transaction. This ensures all related data is stored together for processing and auditing. - Ncell Prepaid/Postpaid Billing: Uses
unionto store eitherprepaid_balance(integer) orpostpaid_bill(float) in the same memory space, optimizing storage for different billing types. - NEPSE Stock Portfolio Tracking: Uses nested
struct(e.g.,struct stockwithsymbol,quantity, andprice) to manage diverse stock holdings in a single portfolio, enabling calculations like total value or profit/loss.
Based on the TU BITM syllabus for Structured Programming in C (ITM102), unit 7.
Discussion
Loading…