Day 9: Structures & Unions#
Overview#
Structures and unions allow us to group multiple variables of different types into a single compound data type. Today we’ll learn how to define and use them effectively.
What We’ll Learn Today#
- Defining structures
- Declaring structure variables
- Accessing structure members
- Arrays of structures
- Nested structures
- Pointers to structures
- Introduction to unions
- Comparing structures and unions
What are Structures?#
A structure is a collection of variables of different types grouped under a single name:
struct Student {
int roll_number;
char name[50];
float gpa;
char grade;
};This defines a blueprint. To use it, we create variables:
struct Student student1; // Create an instance
Defining Structures#
Basic Structure Definition#
struct Person {
int age;
float height;
char name[50];
};Structure Naming Convention#
- Use descriptive names
- Start with capital letter (e.g.,
struct Student) - Can define and declare together:
struct Student {
int roll_number;
char name[50];
float gpa;
} student1, student2; // Declare variables here too
Declaring and Initializing Structure Variables#
Declaration#
struct Student student1; // Uninitialized
Initialization#
// Method 1: With values in order
struct Student s1 = {101, "Alice", 3.8, 'A'};
// Method 2: Partial initialization
struct Student s2 = {102, "Bob"}; // gpa and grade are 0/uninitialized
// Method 3: Zero initialization
struct Student s3 = {0}; // All members set to 0
// Method 4: Using designated initializers
struct Student s4 = {
.roll_number = 103,
.name = "Charlie",
.gpa = 3.9,
.grade = 'A'
};Accessing Structure Members#
Use the dot operator (.) to access members:
#include <stdio.h>
#include <string.h>
struct Student {
int roll_number;
char name[50];
float gpa;
char grade;
};
int main() {
struct Student s1 = {101, "Alice", 3.8, 'A'};
// Access and print
printf("Roll: %d\n", s1.roll_number);
printf("Name: %s\n", s1.name);
printf("GPA: %.2f\n", s1.gpa);
printf("Grade: %c\n", s1.grade);
// Modify members
s1.gpa = 3.9;
s1.grade = 'A';
return 0;
}Output:
Roll: 101
Name: Alice
GPA: 3.80
Grade: AComplete Structure Program#
#include <stdio.h>
#include <string.h>
struct Employee {
int id;
char name[50];
float salary;
char department[30];
};
int main() {
struct Employee emp1;
// Input
printf("Enter employee ID: ");
scanf("%d", &emp1.id);
printf("Enter name: ");
scanf("%s", emp1.name);
printf("Enter salary: ");
scanf("%f", &emp1.salary);
printf("Enter department: ");
scanf("%s", emp1.department);
// Output
printf("\n=== Employee Information ===\n");
printf("ID: %d\n", emp1.id);
printf("Name: %s\n", emp1.name);
printf("Salary: $%.2f\n", emp1.salary);
printf("Department: %s\n", emp1.department);
return 0;
}Arrays of Structures#
Store multiple structure instances:
#include <stdio.h>
struct Book {
char title[50];
char author[50];
float price;
};
int main() {
// Array of 3 books
struct Book books[3] = {
{"C Programming", "Dennis Ritchie", 45.99},
{"Learn C", "Yashavant Kanetkar", 39.99},
{"The C Book", "Mike Banahan", 35.50}
};
// Print each book
printf("=== Library Catalog ===\n");
for (int i = 0; i < 3; i++) {
printf("\nBook %d:\n", i + 1);
printf(" Title: %s\n", books[i].title);
printf(" Author: %s\n", books[i].author);
printf(" Price: $%.2f\n", books[i].price);
}
return 0;
}Output:
=== Library Catalog ===
Book 1:
Title: C Programming
Author: Dennis Ritchie
Price: $45.99
Book 2:
Title: Learn C
Author: Yashavant Kanetkar
Price: $39.99
Book 3:
Title: The C Book
Author: Mike Banahan
Price: $35.50Nested Structures#
Structures within structures:
struct Address {
char street[50];
char city[30];
int zipcode;
};
struct Person {
char name[50];
int age;
struct Address address; // Nested structure
};Accessing Nested Members#
#include <stdio.h>
struct Address {
char street[50];
char city[30];
int zipcode;
};
struct Person {
char name[50];
struct Address address;
};
int main() {
struct Person p1 = {
"Alice",
{"123 Main St", "New York", 10001}
};
printf("Name: %s\n", p1.name);
printf("Street: %s\n", p1.address.street);
printf("City: %s\n", p1.address.city);
printf("Zipcode: %d\n", p1.address.zipcode);
return 0;
}Output:
Name: Alice
Street: 123 Main St
City: New York
Zipcode: 10001Pointers to Structures#
struct Point {
int x;
int y;
};
// Create pointer to structure
struct Point p = {10, 20};
struct Point* ptr = &p;Accessing Members Through Pointers#
Use the arrow operator (->):
(*ptr).x = 10; // Method 1: Dereference then dot
ptr->x = 10; // Method 2: Arrow operator (preferred)
Complete Example#
#include <stdio.h>
struct Point {
int x;
int y;
};
int main() {
struct Point p = {10, 20};
struct Point* ptr = &p;
// Access through pointer
printf("x = %d\n", ptr->x);
printf("y = %d\n", ptr->y);
// Modify through pointer
ptr->x = 30;
ptr->y = 40;
printf("New x = %d\n", ptr->x);
printf("New y = %d\n", ptr->y);
return 0;
}Structures as Function Parameters#
Pass by Value#
void printStudent(struct Student s) {
printf("Roll: %d, Name: %s\n", s.roll_number, s.name);
}
struct Student s1 = {101, "Alice", 3.8, 'A'};
printStudent(s1); // Entire structure copied
Pass by Reference (Better for Large Structures)#
void printStudent(struct Student* s) {
printf("Roll: %d, Name: %s\n", s->roll_number, s->name);
}
struct Student s1 = {101, "Alice", 3.8, 'A'};
printStudent(&s1); // Only address passed
typedef for Structures#
Simplify structure declaration using typedef:
// Without typedef
struct Student s1;
// With typedef
typedef struct {
int roll_number;
char name[50];
float gpa;
} Student;
// Now use it directly
Student s1; // Simpler!
Complete Example with typedef#
#include <stdio.h>
typedef struct {
int id;
char name[50];
float salary;
} Employee;
int main() {
Employee emp1 = {101, "Alice", 50000};
Employee emp2 = {102, "Bob", 55000};
printf("Employee 1: %s - $%.2f\n", emp1.name, emp1.salary);
printf("Employee 2: %s - $%.2f\n", emp2.name, emp2.salary);
return 0;
}Unions#
A union is like a structure, but all members share the same memory:
union Data {
int i;
float f;
char c;
};Key Difference: Memory#
struct Structure {
int i; // 4 bytes
float f; // 4 bytes
char c; // 1 byte
};
// Total: ~9 bytes (possibly 12 with padding)
union Union {
int i; // 4 bytes
float f; // 4 bytes
char c; // 1 byte
};
// Total: 4 bytes (only the largest member)
Example#
#include <stdio.h>
union Data {
int i;
float f;
char c;
};
int main() {
union Data data;
printf("Size of union: %lu bytes\n", sizeof(data)); // 4
data.i = 10;
printf("data.i = %d\n", data.i); // 10
printf("data.f = %f\n", data.f); // Garbage (same memory as i)
printf("data.c = %c\n", data.c); // Garbage
// Assign to f - overwrites i
data.f = 3.14;
printf("\nAfter assigning to f:\n");
printf("data.i = %d\n", data.i); // Now garbage (changed)
printf("data.f = %f\n", data.f); // 3.14
return 0;
}Output:
Size of union: 4 bytes
data.i = 10
data.f = 0.000000
data.c =
After assigning to f:
data.i = 1078557696
data.f = 3.140000Structures vs Unions#
| Feature | Structures | Unions |
|---|---|---|
| Memory | Each member has own space | All share same space |
| Size | Sum of all members | Size of largest member |
| Use | Group related data | Store one of several options |
| Example | Student (name, ID, GPA) | Device (keyboard, mouse, printer) |
Practical Example: Student Management#
#include <stdio.h>
#include <string.h>
typedef struct {
int roll_number;
char name[50];
float marks[3];
float gpa;
} Student;
float calculateGPA(float* marks) {
float average = (marks[0] + marks[1] + marks[2]) / 3.0;
if (average >= 90) return 4.0;
if (average >= 80) return 3.5;
if (average >= 70) return 3.0;
return 2.0;
}
int main() {
Student students[2] = {
{101, "Alice", {85, 90, 88}},
{102, "Bob", {92, 88, 95}}
};
// Calculate and display
for (int i = 0; i < 2; i++) {
students[i].gpa = calculateGPA(students[i].marks);
printf("Roll: %d, Name: %s\n", students[i].roll_number, students[i].name);
printf("Marks: %.0f, %.0f, %.0f\n",
students[i].marks[0],
students[i].marks[1],
students[i].marks[2]);
printf("GPA: %.1f\n\n", students[i].gpa);
}
return 0;
}Practice Exercises#
Exercise 1: Bookstore System#
Create a structure for books with:
- Title, author, price, quantity
- Create array of books
- Display all books
- Find most expensive book
Exercise 2: Car Dealership#
Create a structure for cars with:
- Model, year, price, mileage
- Use arrays to store multiple cars
- Display inventory
- Calculate total value
Exercise 3: Employee Records#
Create an employee structure with:
- Name, ID, salary, address (nested structure)
- Array of employees
- Display all records
- Calculate average salary
Summary#
✅ Defined and used structures
✅ Declared structure variables
✅ Accessed structure members
✅ Created arrays of structures
✅ Worked with nested structures
✅ Used pointers to structures
✅ Applied typedef for convenience
✅ Understood unions
Key Points to Remember#
- Structures group different data types
- Use
.for direct access,->for pointer access - Arrays of structures allow multiple instances
- Pass structures by reference for efficiency
- typedef simplifies structure declarations
- Unions share memory; use when you need only one value at a time
- Structures are great for organizing related data
Next Steps#
Tomorrow we’ll learn about dynamic memory allocation - allocating memory at runtime!