Structures and Unions in C: From Basics to Advanced
Last Updated on: 24th Jul 2025 19:31:27 PM
Structures and unions in C are like custom toolkits, allowing you to bundle related data or share memory efficiently to model real-world entities. Structures group different data types into a single unit, while unions provide a memory-efficient way to store one of several types. This tutorial covers Defining and Using Structures, Nested Structures, Array of Structures, and Unions and Differences from Structures, progressing from beginner-friendly concepts to advanced, real-life applications. Designed for your website, it features unique, engaging examples with user input via scanf and fgets to captivate students. Each example includes code, output, and a detailed explanation to ensure clarity and excitement. Let’s explore structures and unions!
1. Introduction to Structures and Unions
1.1. Structures
A structure in C is a user-defined data type that groups variables of different types into a single unit, like a blueprint for an object (e.g., a student record with name, ID, and grade).
Key Features:
-
Defined using the struct keyword.
-
Members accessed using the dot (.) or arrow (->) operator (for pointers).
-
Ideal for modeling complex entities like records or objects.
1.2. Unions
A union is a user-defined type where all members share the same memory location, allowing only one member to hold a value at a time, like a multi-purpose container.
Key Features:
-
Defined using the union keyword.
-
Memory-efficient, as the size is determined by the largest member.
-
Useful for type punning or saving space when only one member is needed.
Why Use Structures and Unions?
-
Structures: Organize related data (e.g., employee details).
-
Unions: Optimize memory for mutually exclusive data (e.g., variant types).
-
Both: Enable real-world modeling in applications like databases or systems.
2. Defining and Using Structures
Syntax:
struct structure_name {
data_type member1;
data_type member2;
// ...
};
struct structure_name variable; // Declare variable
Accessing Members:
-
Dot operator: variable.member
-
Arrow operator (for pointers): ptr->member
Basic Example: Student Record
This program defines a structure for a student and takes user input to store and display details.
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int id;
float grade;
};
int main() {
struct Student student;
printf("Enter student name: ");
fgets(student.name, 50, stdin);
student.name[strcspn(student.name, "\n")] = '\0';
printf("Enter student ID: ");
scanf("%d", &student.id);
printf("Enter student grade (0-100): ");
scanf("%f", &student.grade);
printf("\nStudent Details:\n");
printf("Name: %s\n", student.name);
printf("ID: %d\n", student.id);
printf("Grade: %.2f\n", student.grade);
return 0;
}
Output (example user input: Alice Smith, 101, 85.5):
Enter student name: Alice Smith
Enter student ID: 101
Enter student grade (0-100): 85.5
Student Details:
Name: Alice Smith
ID: 101
Grade: 85.5
Explanation:
-
The Student structure groups a name (char array), ID (int), and grade (float).
-
fgets reads the name with spaces, and strcspn removes the newline.
-
scanf inputs the ID and grade.
-
The dot operator (student.name, etc.) accesses members to display the data.
3. Nested Structures
A nested structure is a structure containing another structure as a member, allowing hierarchical data organization (e.g., a student with an address).
Syntax:
struct Outer {
data_type member1;
struct Inner {
data_type member2;
} inner;
};
Example: Employee with Address
This program defines a nested structure for an employee with an address and takes user input.
#include <stdio.h>
#include <string.h>
struct Address {
char city[50];
int zip;
};
struct Employee {
char name[50];
int emp_id;
struct Address address;
};
int main() {
struct Employee emp;
printf("Enter employee name: ");
fgets(emp.name, 50, stdin);
emp.name[strcspn(emp.name, "\n")] = '\0';
printf("Enter employee ID: ");
scanf("%d", &emp.emp_id);
printf("Enter city: ");
scanf(" %[^\n]", emp.address.city); // Reads string with spaces
printf("Enter zip code: ");
scanf("%d", &emp.address.zip);
printf("\nEmployee Details:\n");
printf("Name: %s\n", emp.name);
printf("ID: %d\n", emp.emp_id);
printf("City: %s\n", emp.address.city);
printf("Zip: %d\n", emp.address.zip);
return 0;
}
Output (example user input: John Doe, 502, New York, 10001):
Enter employee name: John Doe
Enter employee ID: 502
Enter city: New York
Enter zip code: 10001
Employee Details:
Name: John Doe
ID: 502
City: New York
Zip: 10001
Explanation:
-
The Address structure is nested inside the Employee structure.
-
fgets and scanf input the employee’s name, ID, city, and zip code.
-
The nested structure is accessed using emp.address.city and emp.address.zip.
-
The program organizes hierarchical data (employee → address) clearly.
4. Array of Structures
An array of structures stores multiple structure instances, like a list of records (e.g., multiple students).
Syntax:
struct structure_name array[size];
Real-Life Example 1: List of Employees
Suppose you are making a system to manage 3 employees in a company. Each employee has:
-
empId
-
name
-
salary
We can define a structure Employee
and then create an array to hold all 3 employees.
#include <stdio.h>
// Defining structure
struct Employee {
int empId;
char empName[50];
float salary;
};
int main() {
// Array of 3 employees
struct Employee emp[3];
// Input details
for(int i = 0; i < 3; i++) {
printf("Enter ID, Name, and Salary for Employee %d:\n", i+1);
printf("ID: ");
scanf("%d", &emp[i].empId);
printf("Name: ");
scanf(" %[^\n]", emp[i].empName); // Reads string with spaces
printf("Salary: ");
scanf("%f", &emp[i].salary);
printf("\n");
}
// Display details
printf("\n--- Employee Details ---\n");
for(int i = 0; i < 3; i++) {
printf("Employee %d: ID = %d, Name = %s, Salary = %.2f\n",
i+1, emp[i].empId, emp[i].empName, emp[i].salary);
}
return 0;
}
Enter ID, Name, and Salary for Employee 1:
ID: 101
Name: Ravi Kumar
Salary: 45000
Enter ID, Name, and Salary for Employee 2:
ID: 102
Name: Meena Singh
Salary: 47000
Enter ID, Name, and Salary for Employee 3:
ID: 103
Name: Anil Sharma
Salary: 43000
--- Employee Details ---
Employee 1: ID = 101, Name = Ravi Kumar, Salary = 45000.00
Employee 2: ID = 102, Name = Meena Singh, Salary = 47000.00
Employee 3: ID = 103, Name = Anil Sharma, Salary = 43000.00
Explanation:
-
struct Employee emp[3];
declares an array to store 3 employees. -
scanf(" %[^\n]", emp[i].empName);
is used to read names with spaces. -
The loop inputs and then prints each employee's data.
-
This is a realistic structure used in HR systems, payroll, etc.
Example 2: Classroom Gradebook
This program manages a classroom of 3 students, taking input and calculating the average grade.
#include <stdio.h>
#include <string.h>
#define SIZE 3
struct Student {
char name[50];
float grade;
};
int main() {
struct Student students[SIZE];
float total = 0.0;
printf("Enter details for %d students:\n", SIZE);
for (int i = 0; i < SIZE; i++) {
printf("\nStudent %d:\n", i + 1);
printf("Name: ");
fgets(students[i].name, 50, stdin);
students[i].name[strcspn(students[i].name, "\n")] = '\0';
printf("Grade (0-100): ");
scanf("%f", &students[i].grade);
getchar(); // Clear newline
total += students[i].grade;
}
printf("\nClassroom Gradebook:\n");
for (int i = 0; i < SIZE; i++) {
printf("Student %d: %s, Grade: %.2f\n", i + 1, students[i].name, students[i].grade);
}
printf("Average Grade: %.2f\n", total / SIZE);
return 0;
}
Output (example user input: Alice 90, Bob 85, Charlie 88):
Enter details for 3 students:
Student 1:
Name: Alice
Grade (0-100): 90
Student 2:
Name: Bob
Grade (0-100): 85
Student 3:
Name: Charlie
Grade (0-100): 88
Classroom Gradebook:
Student 1: Alice, Grade: 90.00
Student 2: Bob, Grade: 85.00
Student 3: Charlie, Grade: 88.00
Average Grade: 87.67
Explanation:
-
An array of Student structures stores data for 3 students.
-
fgets and scanf input each student’s name and grade, with getchar() clearing the newline.
-
A loop calculates the total grade, and the average is computed.
-
The program displays all students and their average, modeling a simple gradebook.
When to Use Array of Structures?
-
When you have multiple records of the same entity (students, books, cars).
-
Useful in search, sort, update based on specific fields (like highest salary).
5. Unions and Differences from Structures
5.1. Unions
A union allows multiple members to share the same memory location, with only one member active at a time. The size of a union is the size of its largest member.
Syntax:
union union_name {
data_type member1;
data_type member2;
// ...
};
union union_name variable;
Differences from Structures:
-
Memory: Structures allocate memory for all members; unions allocate memory for the largest member only.
-
Usage: Structures store all members simultaneously; unions store one member at a time.
-
Size: sizeof(struct) is the sum of member sizes (plus padding); sizeof(union) is the size of the largest member.
Example: Product Variant Storage
This program uses a union to store either a book’s page count or a gadget’s battery capacity, demonstrating memory sharing.
#include <stdio.h>
#include <string.h>
union ProductData {
int pages; // For books
float battery; // For gadgets
};
struct Product {
char name[50];
char type[20]; // "book" or "gadget"
union ProductData data;
};
int main() {
struct Product product;
printf("Enter product name: ");
fgets(product.name, 50, stdin);
product.name[strcspn(product.name, "\n")] = '\0';
printf("Enter product type (book/gadget): ");
scanf("%s", product.type);
if (strcmp(product.type, "book") == 0) {
printf("Enter page count: ");
scanf("%d", &product.data.pages);
} else if (strcmp(product.type, "gadget") == 0) {
printf("Enter battery capacity (mAh): ");
scanf("%f", &product.data.battery);
} else {
printf("Invalid type!\n");
return 1;
}
printf("\nProduct Details:\n");
printf("Name: %s\n", product.name);
printf("Type: %s\n", product.type);
if (strcmp(product.type, "book") == 0) {
printf("Pages: %d\n", product.data.pages);
} else {
printf("Battery: %.2f mAh\n", product.data.battery);
}
printf("Size of union: %zu bytes\n", sizeof(product.data));
return 0;
}
Output (example user input: Kindle, book, 300):
Enter product name: Kindle
Enter product type (book/gadget): book
Enter page count: 300
Product Details:
Name: Kindle
Type: book
Pages: 300
Size of union: 4 bytes
Output (example user input: Smartwatch, gadget, 400.5):
Enter product name: Smartwatch
Enter product type (book/gadget): gadget
Enter battery capacity (mAh): 400.5
Product Details:
Name: Smartwatch
Type: gadget
Battery: 400.50 mAh
Size of union: 4 bytes
Explanation:
-
The ProductData union stores either pages (int) or battery (float), sharing the same 4-byte memory.
-
The Product structure includes the union and a type field to track the active member.
-
Based on type, the program inputs either pages or battery using scanf.
-
The union’s size is 4 bytes (largest member), saving memory compared to a structure.
6. Advanced Example: Library Management System
This real-life program simulates a library system, using nested structures, an array of structures, and a union to manage books and e-books, including user input for book details and search functionality.
#include <stdio.h>
#include <string.h>
#define MAX_BOOKS 3
union BookFormat {
int pages; // For physical books
float file_size; // For e-books (MB)
};
struct Publication {
int year;
char publisher[50];
};
struct Book {
char title[50];
char author[50];
char format[20]; // "physical" or "ebook"
union BookFormat details;
struct Publication pub;
};
void inputBook(struct Book *book) {
printf("Enter book title: ");
fgets(book->title, 50, stdin);
book->title[strcspn(book->title, "\n")] = '\0';
printf("Enter author: ");
fgets(book->author, 50, stdin);
book->author[strcspn(book->author, "\n")] = '\0';
printf("Enter format (physical/ebook): ");
scanf("%s", book->format);
if (strcmp(book->format, "physical") == 0) {
printf("Enter page count: ");
scanf("%d", &book->details.pages);
} else if (strcmp(book->format, "ebook") == 0) {
printf("Enter file size (MB): ");
scanf("%f", &book->details.file_size);
}
printf("Enter publication year: ");
scanf("%d", &book->pub.year);
getchar(); // Clear newline
printf("Enter publisher: ");
fgets(book->pub.publisher, 50, stdin);
book->pub.publisher[strcspn(book->pub.publisher, "\n")] = '\0';
}
void searchBook(struct Book books[], int n, char *searchTitle) {
int found = 0;
for (int i = 0; i < n; i++) {
if (strstr(books[i].title, searchTitle)) {
printf("\nBook Found:\n");
printf("Title: %s\n", books[i].title);
printf("Author: %s\n", books[i].author);
printf("Format: %s\n", books[i].format);
if (strcmp(books[i].format, "physical") == 0) {
printf("Pages: %d\n", books[i].details.pages);
} else {
printf("File Size: %.2f MB\n", books[i].details.file_size);
}
printf("Year: %d\n", books[i].pub.year);
printf("Publisher: %s\n", books[i].pub.publisher);
found = 1;
}
}
if (!found) {
printf("\nNo book found with title containing '%s'.\n", searchTitle);
}
}
int main() {
struct Book library[MAX_BOOKS];
printf("Enter details for %d books:\n", MAX_BOOKS);
for (int i = 0; i < MAX_BOOKS; i++) {
printf("\nBook %d:\n", i + 1);
inputBook(&library[i]);
getchar(); // Clear newline
}
printf("\nLibrary Catalog:\n");
for (int i = 0; i < MAX_BOOKS; i++) {
printf("\nBook %d:\n", i + 1);
printf("Title: %s\n", library[i].title);
printf("Author: %s\n", library[i].author);
printf("Format: %s\n", library[i].format);
if (strcmp(library[i].format, "physical") == 0) {
printf("Pages: %d\n", library[i].details.pages);
} else {
printf("File Size: %.2f MB\n", library[i].details.file_size);
}
printf("Year: %d\n", library[i].pub.year);
printf("Publisher: %s\n", library[i].pub.publisher);
}
char searchTitle[50];
printf("\nEnter title to search: ");
fgets(searchTitle, 50, stdin);
searchTitle[strcspn(searchTitle, "\n")] = '\0';
searchBook(library, MAX_BOOKS, searchTitle);
return 0;
}
Output (example user input: {C Programming, K&R, physical, 200, 1978, Prentice}, {Python Guide, Guido, ebook, 2.5, 2000, OReilly}, {C++ Primer, Lippman, physical, 500, 2012, Addison}, search: C):
Enter details for 3 books:
Book 1:
Enter book title: C Programming
Enter author: K&R
Enter format (physical/ebook): physical
Enter page count: 200
Enter publication year: 1978
Enter publisher: Prentice
Book 2:
Enter book title: Python Guide
Enter author: Guido
Enter format (physical/ebook): ebook
Enter file size (MB): 2.5
Enter publication year: 2000
Enter publisher: OReilly
Book 3:
Enter book title: C++ Primer
Enter author: Lippman
Enter format (physical/ebook): physical
Enter page count: 500
Enter publication year: 2012
Enter publisher: Addison
Library Catalog:
Book 1:
Title: C Programming
Author: K&R
Format: physical
Pages: 200
Year: 1978
Publisher: Prentice
Book 2:
Title: Python Guide
Author: Guido
Format: ebook
File Size: 2.50 MB
Year: 2000
Publisher: OReilly
Book 3:
Title: C++ Primer
Author: Lippman
Format: physical
Pages: 500
Year: 2012
Publisher: Addison
Enter title to search: C
Book Found:
Title: C Programming
Author: K&R
Format: physical
Pages: 200
Year: 1978
Publisher: Prentice
Book Found:
Title: C++ Primer
Author: Lippman
Format: physical
Pages: 500
Year: 2012
Publisher: Addison
Explanation:
-
The BookFormat union stores either pages or file_size, saving memory.
-
The Publication structure is nested in the Book structure for publication details.
-
An array of Book structures (library) stores 3 books.
-
The inputBook function uses a pointer to input data for a single book, handling both physical and e-book formats.
-
The searchBook function searches for books by title substring using strstr.
-
The program models a real-life library system, demonstrating nested structures, arrays of structures, and unions in a practical context.
7. Why Structures and Unions Are Essential
Structures and unions in C are vital for:
-
Data Organization: Structures group related data for complex entities (e.g., books).
-
Memory Efficiency: Unions optimize storage for mutually exclusive data.
-
Real-World Applications: Used in databases, file systems, and simulations.
Pro Tip: Experiment with these examples! Try extending the library system to sort books by year, add a function to count e-books, or create a union for different payment types. Structures and unions are your foundation for structured programming!
Happy coding