Introduction
An array of structures in C is a collection of structure variables of the same type stored in contiguous memory locations. This powerful feature allows you to manage multiple records efficiently, making it ideal for applications like student databases, employee records, inventory systems, and other data management scenarios where you need to handle multiple entities with the same attributes.
Key Concepts
Structure Array: Collection of structure variables of the same type Index-based Access: Accessing individual structures using array indices Memory Layout: Structures stored sequentially in memory Iteration: Processing multiple records using loops Record Management: Adding, updating, deleting, and searching records
Basic Array of Structures
Simple Declaration and Initialization
#include <stdio.h>
#include <string.h>
struct Student {
int rollNo;
char name[30];
float marks;
char grade;
};
int main() {
// Declare array of 3 students
struct Student students[3];
// Initialize first student
students[0].rollNo = 101;
strcpy(students[0].name, "Alice Johnson");
students[0].marks = 85.5;
students[0].grade = 'A';
// Initialize second student
students[1].rollNo = 102;
strcpy(students[1].name, "Bob Smith");
students[1].marks = 78.0;
students[1].grade = 'B';
// Initialize third student
students[2].rollNo = 103;
strcpy(students[2].name, "Charlie Brown");
students[2].marks = 92.5;
students[2].grade = 'A';
// Display all students
printf("Student Records:\n");
printf("Roll No\tName\t\tMarks\tGrade\n");
printf("-------\t------------\t-----\t-----\n");
for (int i = 0; i < 3; i++) {
printf("%d\t%-12s\t%.1f\t%c\n",
students[i].rollNo,
students[i].name,
students[i].marks,
students[i].grade);
}
return 0;
}
Direct Initialization
#include <stdio.h>
struct Book {
int bookId;
char title[40];
char author[25];
float price;
};
int main() {
// Initialize array during declaration
struct Book library[4] = {
{1001, "C Programming", "Dennis Ritchie", 29.99},
{1002, "Data Structures", "Robert Sedgewick", 45.50},
{1003, "Algorithms", "Thomas Cormen", 85.00},
{1004, "Computer Networks", "Andrew Tanenbaum", 65.75}
};
printf("Library Catalog:\n");
printf("ID\tTitle\t\t\tAuthor\t\t\tPrice\n");
printf("----\t--------------------\t---------------\t--------\n");
for (int i = 0; i < 4; i++) {
printf("%d\t%-20s\t%-15s\t$%.2f\n",
library[i].bookId,
library[i].title,
library[i].author,
library[i].price);
}
return 0;
}
Input and Output Operations
Interactive Data Entry
#include <stdio.h>
#include <string.h>
#define MAX_EMPLOYEES 5
struct Employee {
int empId;
char name[30];
char department[20];
float salary;
int experience;
};
void inputEmployee(struct Employee *emp) {
printf("Enter Employee ID: ");
scanf("%d", &emp->empId);
printf("Enter Name: ");
scanf("%s", emp->name);
printf("Enter Department: ");
scanf("%s", emp->department);
printf("Enter Salary: ");
scanf("%f", &emp->salary);
printf("Enter Experience (years): ");
scanf("%d", &emp->experience);
}
void displayEmployee(struct Employee emp) {
printf("ID: %d, Name: %s, Dept: %s, Salary: $%.2f, Exp: %d years\n",
emp.empId, emp.name, emp.department, emp.salary, emp.experience);
}
int main() {
struct Employee employees[MAX_EMPLOYEES];
int count = 0;
char choice;
printf("Employee Data Entry System\n");
do {
printf("\nEntering employee %d:\n", count + 1);
inputEmployee(&employees[count]);
count++;
printf("Add another employee? (y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' && count < MAX_EMPLOYEES);
printf("\nEmployee Records:\n");
printf("================\n");
for (int i = 0; i < count; i++) {
printf("%d. ", i + 1);
displayEmployee(employees[i]);
}
return 0;
}
File-based Data Processing
#include <stdio.h>
#include <string.h>
struct Product {
int productId;
char name[25];
float price;
int stock;
char category[15];
};
void saveProducts(struct Product products[], int count, const char *filename) {
FILE *file = fopen(filename, "w");
if (file == NULL) {
printf("Error opening file for writing!\n");
return;
}
fprintf(file, "ID,Name,Price,Stock,Category\n");
for (int i = 0; i < count; i++) {
fprintf(file, "%d,%s,%.2f,%d,%s\n",
products[i].productId,
products[i].name,
products[i].price,
products[i].stock,
products[i].category);
}
fclose(file);
printf("Products saved to %s\n", filename);
}
void displayProducts(struct Product products[], int count) {
printf("\nProduct Inventory:\n");
printf("ID\tName\t\tPrice\tStock\tCategory\n");
printf("----\t------------\t-----\t-----\t--------\n");
for (int i = 0; i < count; i++) {
printf("%d\t%-12s\t$%.2f\t%d\t%s\n",
products[i].productId,
products[i].name,
products[i].price,
products[i].stock,
products[i].category);
}
}
int main() {
struct Product inventory[] = {
{1001, "Laptop", 899.99, 15, "Electronics"},
{1002, "Mouse", 25.50, 50, "Electronics"},
{1003, "Desk", 199.00, 8, "Furniture"},
{1004, "Chair", 149.50, 12, "Furniture"},
{1005, "Monitor", 299.99, 20, "Electronics"}
};
int productCount = sizeof(inventory) / sizeof(inventory[0]);
displayProducts(inventory, productCount);
saveProducts(inventory, productCount, "products.csv");
return 0;
}
Searching and Sorting
Linear Search Implementation
#include <stdio.h>
#include <string.h>
struct Student {
int rollNo;
char name[30];
float marks;
char course[20];
};
int searchByRollNo(struct Student students[], int count, int rollNo) {
for (int i = 0; i < count; i++) {
if (students[i].rollNo == rollNo) {
return i; // Return index if found
}
}
return -1; // Not found
}
int searchByName(struct Student students[], int count, const char *name) {
for (int i = 0; i < count; i++) {
if (strcmp(students[i].name, name) == 0) {
return i;
}
}
return -1;
}
void searchHighScorers(struct Student students[], int count, float threshold) {
printf("\nStudents with marks >= %.1f:\n", threshold);
int found = 0;
for (int i = 0; i < count; i++) {
if (students[i].marks >= threshold) {
printf("Roll No: %d, Name: %s, Marks: %.1f\n",
students[i].rollNo, students[i].name, students[i].marks);
found++;
}
}
if (found == 0) {
printf("No students found with marks >= %.1f\n", threshold);
}
}
int main() {
struct Student students[] = {
{101, "Alice Johnson", 85.5, "Computer Science"},
{102, "Bob Smith", 78.0, "Mathematics"},
{103, "Charlie Brown", 92.5, "Physics"},
{104, "Diana Wilson", 88.0, "Computer Science"},
{105, "Eve Davis", 76.5, "Chemistry"}
};
int count = sizeof(students) / sizeof(students[0]);
// Search by roll number
int rollNo = 103;
int index = searchByRollNo(students, count, rollNo);
if (index != -1) {
printf("Student found: %s (Roll No: %d)\n",
students[index].name, rollNo);
} else {
printf("Student with Roll No %d not found\n", rollNo);
}
// Search by name
char name[] = "Diana Wilson";
index = searchByName(students, count, name);
if (index != -1) {
printf("Student found: Roll No %d, Marks: %.1f\n",
students[index].rollNo, students[index].marks);
}
// Search high scorers
searchHighScorers(students, count, 80.0);
return 0;
}
Sorting Array of Structures
#include <stdio.h>
#include <string.h>
struct Employee {
int empId;
char name[25];
float salary;
int age;
};
void sortBySalary(struct Employee employees[], int count) {
struct Employee temp;
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1; j++) {
if (employees[j].salary > employees[j + 1].salary) {
// Swap entire structures
temp = employees[j];
employees[j] = employees[j + 1];
employees[j + 1] = temp;
}
}
}
}
void sortByName(struct Employee employees[], int count) {
struct Employee temp;
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1; j++) {
if (strcmp(employees[j].name, employees[j + 1].name) > 0) {
temp = employees[j];
employees[j] = employees[j + 1];
employees[j + 1] = temp;
}
}
}
}
void displayEmployees(struct Employee employees[], int count, const char *title) {
printf("\n%s:\n", title);
printf("ID\tName\t\tSalary\t\tAge\n");
printf("----\t--------\t--------\t---\n");
for (int i = 0; i < count; i++) {
printf("%d\t%-8s\t$%.2f\t\t%d\n",
employees[i].empId,
employees[i].name,
employees[i].salary,
employees[i].age);
}
}
int main() {
struct Employee employees[] = {
{1001, "John", 55000.0, 28},
{1002, "Alice", 62000.0, 32},
{1003, "Bob", 48000.0, 25},
{1004, "Diana", 71000.0, 35},
{1005, "Charlie", 59000.0, 30}
};
int count = sizeof(employees) / sizeof(employees[0]);
displayEmployees(employees, count, "Original Order");
// Sort by salary
sortBySalary(employees, count);
displayEmployees(employees, count, "Sorted by Salary (Ascending)");
// Sort by name
sortByName(employees, count);
displayEmployees(employees, count, "Sorted by Name (Alphabetical)");
return 0;
}
Advanced Operations
Statistical Analysis
#include <stdio.h>
#include <string.h>
struct Score {
char subject[20];
float marks;
};
struct Student {
int rollNo;
char name[25];
struct Score scores[3];
float average;
char grade;
};
void calculateStats(struct Student students[], int count) {
for (int i = 0; i < count; i++) {
float total = 0;
for (int j = 0; j < 3; j++) {
total += students[i].scores[j].marks;
}
students[i].average = total / 3.0;
// Assign grade based on average
if (students[i].average >= 90) students[i].grade = 'A';
else if (students[i].average >= 80) students[i].grade = 'B';
else if (students[i].average >= 70) students[i].grade = 'C';
else if (students[i].average >= 60) students[i].grade = 'D';
else students[i].grade = 'F';
}
}
void displayDetailedReport(struct Student students[], int count) {
printf("\nDetailed Student Report:\n");
printf("=" * 60);
printf("\n");
for (int i = 0; i < count; i++) {
printf("Student: %s (Roll No: %d)\n", students[i].name, students[i].rollNo);
printf("Subjects and Marks:\n");
for (int j = 0; j < 3; j++) {
printf(" %s: %.1f\n",
students[i].scores[j].subject,
students[i].scores[j].marks);
}
printf("Average: %.2f, Grade: %c\n", students[i].average, students[i].grade);
printf("---\n");
}
}
void classStatistics(struct Student students[], int count) {
float classTotal = 0, highest = 0, lowest = 100;
int aCount = 0, bCount = 0, cCount = 0, dCount = 0, fCount = 0;
for (int i = 0; i < count; i++) {
classTotal += students[i].average;
if (students[i].average > highest) highest = students[i].average;
if (students[i].average < lowest) lowest = students[i].average;
switch (students[i].grade) {
case 'A': aCount++; break;
case 'B': bCount++; break;
case 'C': cCount++; break;
case 'D': dCount++; break;
case 'F': fCount++; break;
}
}
printf("\nClass Statistics:\n");
printf("Class Average: %.2f\n", classTotal / count);
printf("Highest Score: %.2f\n", highest);
printf("Lowest Score: %.2f\n", lowest);
printf("\nGrade Distribution:\n");
printf("A: %d, B: %d, C: %d, D: %d, F: %d\n", aCount, bCount, cCount, dCount, fCount);
}
int main() {
struct Student students[] = {
{101, "Alice", {{"Math", 85}, {"Physics", 90}, {"Chemistry", 88}}, 0, 'X'},
{102, "Bob", {{"Math", 78}, {"Physics", 82}, {"Chemistry", 75}}, 0, 'X'},
{103, "Charlie", {{"Math", 95}, {"Physics", 92}, {"Chemistry", 89}}, 0, 'X'},
{104, "Diana", {{"Math", 88}, {"Physics", 85}, {"Chemistry", 91}}, 0, 'X'}
};
int count = sizeof(students) / sizeof(students[0]);
calculateStats(students, count);
displayDetailedReport(students, count);
classStatistics(students, count);
return 0;
}
Dynamic Array Management
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Contact {
char name[30];
char phone[15];
char email[40];
};
struct ContactBook {
struct Contact *contacts;
int count;
int capacity;
};
void initContactBook(struct ContactBook *book, int initialCapacity) {
book->contacts = (struct Contact*)malloc(initialCapacity * sizeof(struct Contact));
book->count = 0;
book->capacity = initialCapacity;
}
void addContact(struct ContactBook *book, const char *name, const char *phone, const char *email) {
if (book->count >= book->capacity) {
// Resize array
book->capacity *= 2;
book->contacts = (struct Contact*)realloc(book->contacts,
book->capacity * sizeof(struct Contact));
printf("Array resized to capacity: %d\n", book->capacity);
}
strcpy(book->contacts[book->count].name, name);
strcpy(book->contacts[book->count].phone, phone);
strcpy(book->contacts[book->count].email, email);
book->count++;
printf("Contact added: %s\n", name);
}
void displayContacts(struct ContactBook *book) {
printf("\nContact Book (%d contacts):\n", book->count);
printf("Name\t\t\tPhone\t\tEmail\n");
printf("----\t\t\t-----\t\t-----\n");
for (int i = 0; i < book->count; i++) {
printf("%-15s\t%-12s\t%s\n",
book->contacts[i].name,
book->contacts[i].phone,
book->contacts[i].email);
}
}
void freeContactBook(struct ContactBook *book) {
free(book->contacts);
book->contacts = NULL;
book->count = 0;
book->capacity = 0;
}
int main() {
struct ContactBook myContacts;
initContactBook(&myContacts, 2); // Start with capacity of 2
// Add contacts (will trigger resize)
addContact(&myContacts, "Alice Johnson", "555-0101", "alice@email.com");
addContact(&myContacts, "Bob Smith", "555-0102", "bob@email.com");
addContact(&myContacts, "Charlie Brown", "555-0103", "charlie@email.com");
addContact(&myContacts, "Diana Wilson", "555-0104", "diana@email.com");
displayContacts(&myContacts);
printf("\nCapacity: %d, Count: %d\n", myContacts.capacity, myContacts.count);
freeContactBook(&myContacts);
return 0;
}
Memory Management
Efficient Memory Usage
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct LargeRecord {
int id;
char description[200];
double values[50];
int flags[20];
};
void demonstrateMemoryUsage() {
printf("Memory Usage Analysis:\n");
printf("Size of one record: %zu bytes\n", sizeof(struct LargeRecord));
// Static array (limited size)
struct LargeRecord staticArray[10];
printf("Static array (10 records): %zu bytes\n", sizeof(staticArray));
// Dynamic array (flexible size)
int recordCount = 100;
struct LargeRecord *dynamicArray =
(struct LargeRecord*)malloc(recordCount * sizeof(struct LargeRecord));
if (dynamicArray != NULL) {
printf("Dynamic array (%d records): %zu bytes\n",
recordCount, recordCount * sizeof(struct LargeRecord));
// Initialize some records
for (int i = 0; i < 5; i++) {
dynamicArray[i].id = i + 1;
snprintf(dynamicArray[i].description, 200, "Record %d description", i + 1);
for (int j = 0; j < 50; j++) {
dynamicArray[i].values[j] = i * 10.0 + j;
}
}
printf("Initialized first 5 records\n");
// Display sample record
printf("\nSample Record (ID: %d):\n", dynamicArray[0].id);
printf("Description: %s\n", dynamicArray[0].description);
printf("First 5 values: ");
for (int j = 0; j < 5; j++) {
printf("%.1f ", dynamicArray[0].values[j]);
}
printf("\n");
free(dynamicArray);
}
}
int main() {
demonstrateMemoryUsage();
return 0;
}
Best Practices
Modular Design with Functions
#include <stdio.h>
#include <string.h>
#define MAX_PRODUCTS 100
struct Product {
int id;
char name[30];
float price;
int quantity;
};
// Function prototypes
void initializeInventory(struct Product products[], int *count);
void addProduct(struct Product products[], int *count);
void updateProduct(struct Product products[], int count);
void displayInventory(struct Product products[], int count);
void searchProduct(struct Product products[], int count);
int main() {
struct Product inventory[MAX_PRODUCTS];
int productCount = 0;
int choice;
initializeInventory(inventory, &productCount);
do {
printf("\n=== Inventory Management System ===\n");
printf("1. Add Product\n");
printf("2. Update Product\n");
printf("3. Display Inventory\n");
printf("4. Search Product\n");
printf("5. Exit\n");
printf("Choice: ");
scanf("%d", &choice);
switch (choice) {
case 1: addProduct(inventory, &productCount); break;
case 2: updateProduct(inventory, productCount); break;
case 3: displayInventory(inventory, productCount); break;
case 4: searchProduct(inventory, productCount); break;
case 5: printf("Goodbye!\n"); break;
default: printf("Invalid choice!\n");
}
} while (choice != 5);
return 0;
}
void initializeInventory(struct Product products[], int *count) {
// Initialize with sample data
struct Product samples[] = {
{1001, "Laptop", 999.99, 10},
{1002, "Mouse", 29.99, 50},
{1003, "Keyboard", 79.99, 30}
};
int sampleCount = sizeof(samples) / sizeof(samples[0]);
for (int i = 0; i < sampleCount; i++) {
products[i] = samples[i];
}
*count = sampleCount;
printf("Inventory initialized with %d sample products.\n", *count);
}
void addProduct(struct Product products[], int *count) {
if (*count >= MAX_PRODUCTS) {
printf("Inventory full!\n");
return;
}
printf("Enter product details:\n");
printf("ID: ");
scanf("%d", &products[*count].id);
printf("Name: ");
scanf("%s", products[*count].name);
printf("Price: ");
scanf("%f", &products[*count].price);
printf("Quantity: ");
scanf("%d", &products[*count].quantity);
(*count)++;
printf("Product added successfully!\n");
}
void displayInventory(struct Product products[], int count) {
printf("\nCurrent Inventory:\n");
printf("ID\tName\t\tPrice\t\tQuantity\n");
printf("----\t--------\t--------\t--------\n");
for (int i = 0; i < count; i++) {
printf("%d\t%-8s\t$%.2f\t\t%d\n",
products[i].id, products[i].name,
products[i].price, products[i].quantity);
}
}
Summary
Array of structures in C provides a powerful way to manage collections of related data. They enable efficient storage, retrieval, and manipulation of multiple records with the same structure. Key operations include initialization, input/output, searching, sorting, and statistical analysis. Proper memory management, modular function design, and efficient algorithms are essential for building robust applications using arrays of structures.
Part of BCA Programming with C Course (UGCOA22J201)