c
examples
examples.c🔧c
/**
* Array of Structures in C - Examples
*
* This file demonstrates array of structures concepts with practical examples.
* Compile with: gcc examples.c -o examples
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// ============================================================
// EXAMPLE 1: Basic Array of Structures
// ============================================================
struct Student {
char name[50];
int id;
float gpa;
};
void example1_basic_array(void) {
printf("=== Example 1: Basic Array of Structures ===\n");
// Declare and initialize array of structures
struct Student class[5] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9},
{"David", 104, 3.2},
{"Eve", 105, 3.7}
};
// Access elements
printf("First student: %s (ID: %d, GPA: %.2f)\n",
class[0].name, class[0].id, class[0].gpa);
printf("Third student: %s (ID: %d, GPA: %.2f)\n",
class[2].name, class[2].id, class[2].gpa);
// Modify an element
class[1].gpa = 3.6;
printf("Updated Bob's GPA: %.2f\n", class[1].gpa);
// Array size information
printf("\nSize of one student: %zu bytes\n", sizeof(struct Student));
printf("Size of array: %zu bytes\n", sizeof(class));
printf("Number of students: %zu\n", sizeof(class) / sizeof(class[0]));
printf("\n");
}
// ============================================================
// EXAMPLE 2: Iterating Through Array
// ============================================================
void example2_iteration(void) {
printf("=== Example 2: Iterating Through Array ===\n");
struct Student class[] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9},
{"David", 104, 3.2},
{"Eve", 105, 3.7}
};
int n = sizeof(class) / sizeof(class[0]);
// Method 1: Index-based loop
printf("Method 1 - Index-based:\n");
for (int i = 0; i < n; i++) {
printf(" %d. %s - GPA: %.2f\n", i + 1, class[i].name, class[i].gpa);
}
// Method 2: Pointer-based loop
printf("\nMethod 2 - Pointer-based:\n");
struct Student *ptr;
int count = 1;
for (ptr = class; ptr < class + n; ptr++) {
printf(" %d. %s - ID: %d\n", count++, ptr->name, ptr->id);
}
printf("\n");
}
// ============================================================
// EXAMPLE 3: Different Initialization Methods
// ============================================================
struct Product {
char name[30];
float price;
int stock;
};
void example3_initialization(void) {
printf("=== Example 3: Initialization Methods ===\n");
// Method 1: Complete initialization
struct Product products1[3] = {
{"Laptop", 999.99, 50},
{"Mouse", 29.99, 200},
{"Keyboard", 79.99, 150}
};
// Method 2: Designated initializers
struct Product products2[3] = {
{.name = "Phone", .price = 699.99, .stock = 100},
{.name = "Tablet", .price = 499.99, .stock = 75},
{.name = "Watch", .price = 299.99, .stock = 120}
};
// Method 3: Partial initialization (rest zeroed)
struct Product products3[5] = {
{"Item1", 10.0, 5},
{"Item2", 20.0, 10}
// products3[2], [3], [4] are zero-initialized
};
// Method 4: Loop initialization
struct Product products4[3];
for (int i = 0; i < 3; i++) {
sprintf(products4[i].name, "Product%d", i + 1);
products4[i].price = 10.0 * (i + 1);
products4[i].stock = 100 + i * 50;
}
printf("Products1: ");
for (int i = 0; i < 3; i++) {
printf("%s($%.2f) ", products1[i].name, products1[i].price);
}
printf("\n");
printf("Products2: ");
for (int i = 0; i < 3; i++) {
printf("%s($%.2f) ", products2[i].name, products2[i].price);
}
printf("\n");
printf("Products3: ");
for (int i = 0; i < 5; i++) {
printf("%s($%.2f) ", products3[i].name, products3[i].price);
}
printf("\n");
printf("Products4: ");
for (int i = 0; i < 3; i++) {
printf("%s($%.2f) ", products4[i].name, products4[i].price);
}
printf("\n\n");
}
// ============================================================
// EXAMPLE 4: Passing Array to Functions
// ============================================================
void print_students(const struct Student arr[], int size) {
printf(" Student List:\n");
for (int i = 0; i < size; i++) {
printf(" %d. %-15s ID: %d GPA: %.2f\n",
i + 1, arr[i].name, arr[i].id, arr[i].gpa);
}
}
void update_all_gpas(struct Student arr[], int size, float bonus) {
for (int i = 0; i < size; i++) {
arr[i].gpa += bonus;
if (arr[i].gpa > 4.0) arr[i].gpa = 4.0;
}
}
float calculate_average_gpa(const struct Student arr[], int size) {
float total = 0;
for (int i = 0; i < size; i++) {
total += arr[i].gpa;
}
return total / size;
}
void example4_functions(void) {
printf("=== Example 4: Passing Array to Functions ===\n");
struct Student class[] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9}
};
int n = 3;
printf("Before update:\n");
print_students(class, n);
printf(" Average GPA: %.2f\n", calculate_average_gpa(class, n));
// Add 0.1 bonus to all GPAs
update_all_gpas(class, n, 0.1);
printf("\nAfter adding 0.1 bonus:\n");
print_students(class, n);
printf(" Average GPA: %.2f\n", calculate_average_gpa(class, n));
printf("\n");
}
// ============================================================
// EXAMPLE 5: Searching in Array
// ============================================================
struct Student* find_by_id(struct Student arr[], int size, int id) {
for (int i = 0; i < size; i++) {
if (arr[i].id == id) {
return &arr[i];
}
}
return NULL;
}
int find_by_name(const struct Student arr[], int size, const char *name) {
for (int i = 0; i < size; i++) {
if (strcmp(arr[i].name, name) == 0) {
return i;
}
}
return -1;
}
struct Student* find_highest_gpa(struct Student arr[], int size) {
if (size == 0) return NULL;
struct Student *highest = &arr[0];
for (int i = 1; i < size; i++) {
if (arr[i].gpa > highest->gpa) {
highest = &arr[i];
}
}
return highest;
}
void example5_searching(void) {
printf("=== Example 5: Searching in Array ===\n");
struct Student class[] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9},
{"David", 104, 3.2},
{"Eve", 105, 3.7}
};
int n = 5;
// Search by ID
struct Student *found = find_by_id(class, n, 103);
if (found != NULL) {
printf("Found ID 103: %s (GPA: %.2f)\n", found->name, found->gpa);
}
found = find_by_id(class, n, 999);
if (found == NULL) {
printf("ID 999 not found\n");
}
// Search by name
int index = find_by_name(class, n, "Bob");
if (index >= 0) {
printf("Found 'Bob' at index %d\n", index);
}
// Find highest GPA
struct Student *top = find_highest_gpa(class, n);
printf("Highest GPA: %s with %.2f\n", top->name, top->gpa);
printf("\n");
}
// ============================================================
// EXAMPLE 6: Sorting Array of Structures
// ============================================================
void swap_students(struct Student *a, struct Student *b) {
struct Student temp = *a;
*a = *b;
*b = temp;
}
void sort_by_gpa_desc(struct Student arr[], int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (arr[j].gpa < arr[j + 1].gpa) {
swap_students(&arr[j], &arr[j + 1]);
}
}
}
}
void sort_by_name(struct Student arr[], int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (strcmp(arr[j].name, arr[j + 1].name) > 0) {
swap_students(&arr[j], &arr[j + 1]);
}
}
}
}
// Using qsort
int compare_gpa_desc(const void *a, const void *b) {
const struct Student *sa = (const struct Student *)a;
const struct Student *sb = (const struct Student *)b;
if (sa->gpa < sb->gpa) return 1;
if (sa->gpa > sb->gpa) return -1;
return 0;
}
void example6_sorting(void) {
printf("=== Example 6: Sorting Array ===\n");
struct Student class[] = {
{"Eve", 105, 3.7},
{"Alice", 101, 3.8},
{"David", 104, 3.2},
{"Carol", 103, 3.9},
{"Bob", 102, 3.5}
};
int n = 5;
printf("Original order:\n");
for (int i = 0; i < n; i++) {
printf(" %s: %.2f\n", class[i].name, class[i].gpa);
}
// Sort by GPA (descending)
sort_by_gpa_desc(class, n);
printf("\nSorted by GPA (descending):\n");
for (int i = 0; i < n; i++) {
printf(" %s: %.2f\n", class[i].name, class[i].gpa);
}
// Sort by name (alphabetical)
sort_by_name(class, n);
printf("\nSorted by name:\n");
for (int i = 0; i < n; i++) {
printf(" %s: %.2f\n", class[i].name, class[i].gpa);
}
// Using qsort
qsort(class, n, sizeof(struct Student), compare_gpa_desc);
printf("\nSorted by GPA using qsort:\n");
for (int i = 0; i < n; i++) {
printf(" %s: %.2f\n", class[i].name, class[i].gpa);
}
printf("\n");
}
// ============================================================
// EXAMPLE 7: Dynamic Array of Structures
// ============================================================
void example7_dynamic_array(void) {
printf("=== Example 7: Dynamic Array of Structures ===\n");
int n = 3;
// Allocate array dynamically
struct Student *students = malloc(n * sizeof(struct Student));
if (students == NULL) {
printf("Memory allocation failed!\n");
return;
}
// Initialize using pointer notation
for (int i = 0; i < n; i++) {
sprintf(students[i].name, "Student%d", i + 1);
students[i].id = 200 + i;
students[i].gpa = 3.0 + (i * 0.2);
}
printf("Dynamic array contents:\n");
for (int i = 0; i < n; i++) {
printf(" %s (ID: %d) - GPA: %.2f\n",
students[i].name, students[i].id, students[i].gpa);
}
// Resize array
int new_n = 5;
students = realloc(students, new_n * sizeof(struct Student));
if (students == NULL) {
printf("Reallocation failed!\n");
return;
}
// Initialize new elements
for (int i = n; i < new_n; i++) {
sprintf(students[i].name, "Student%d", i + 1);
students[i].id = 200 + i;
students[i].gpa = 3.0 + (i * 0.2);
}
printf("\nAfter resizing to %d:\n", new_n);
for (int i = 0; i < new_n; i++) {
printf(" %s (ID: %d) - GPA: %.2f\n",
students[i].name, students[i].id, students[i].gpa);
}
// Free memory
free(students);
printf("\nMemory freed successfully.\n");
printf("\n");
}
// ============================================================
// EXAMPLE 8: CRUD Operations
// ============================================================
#define MAX_EMPLOYEES 10
struct Employee {
int id;
char name[50];
float salary;
int active;
};
struct Employee employees[MAX_EMPLOYEES];
int employee_count = 0;
// Create
int add_employee(int id, const char *name, float salary) {
if (employee_count >= MAX_EMPLOYEES) return -1;
employees[employee_count].id = id;
strncpy(employees[employee_count].name, name, 49);
employees[employee_count].name[49] = '\0';
employees[employee_count].salary = salary;
employees[employee_count].active = 1;
return employee_count++;
}
// Read
struct Employee* get_employee(int id) {
for (int i = 0; i < employee_count; i++) {
if (employees[i].id == id && employees[i].active) {
return &employees[i];
}
}
return NULL;
}
// Update
int update_salary(int id, float new_salary) {
struct Employee *emp = get_employee(id);
if (emp != NULL) {
emp->salary = new_salary;
return 1;
}
return 0;
}
// Delete (soft delete)
int remove_employee(int id) {
struct Employee *emp = get_employee(id);
if (emp != NULL) {
emp->active = 0;
return 1;
}
return 0;
}
void print_all_employees(void) {
printf(" Active Employees:\n");
for (int i = 0; i < employee_count; i++) {
if (employees[i].active) {
printf(" ID: %d, Name: %s, Salary: $%.2f\n",
employees[i].id, employees[i].name, employees[i].salary);
}
}
}
void example8_crud(void) {
printf("=== Example 8: CRUD Operations ===\n");
// Reset
employee_count = 0;
// Create
add_employee(1, "John Doe", 50000);
add_employee(2, "Jane Smith", 55000);
add_employee(3, "Bob Johnson", 48000);
printf("After adding 3 employees:\n");
print_all_employees();
// Read
struct Employee *emp = get_employee(2);
if (emp != NULL) {
printf("\nFound employee 2: %s\n", emp->name);
}
// Update
update_salary(2, 60000);
printf("\nAfter updating Jane's salary:\n");
print_all_employees();
// Delete
remove_employee(1);
printf("\nAfter removing employee 1:\n");
print_all_employees();
printf("\n");
}
// ============================================================
// EXAMPLE 9: Statistics on Array
// ============================================================
typedef struct {
float min;
float max;
float average;
float sum;
int count;
} Statistics;
Statistics calculate_gpa_stats(const struct Student arr[], int size) {
Statistics stats = {0};
if (size == 0) return stats;
stats.count = size;
stats.min = arr[0].gpa;
stats.max = arr[0].gpa;
for (int i = 0; i < size; i++) {
stats.sum += arr[i].gpa;
if (arr[i].gpa < stats.min) stats.min = arr[i].gpa;
if (arr[i].gpa > stats.max) stats.max = arr[i].gpa;
}
stats.average = stats.sum / size;
return stats;
}
void example9_statistics(void) {
printf("=== Example 9: Statistics ===\n");
struct Student class[] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9},
{"David", 104, 3.2},
{"Eve", 105, 3.7}
};
int n = 5;
Statistics stats = calculate_gpa_stats(class, n);
printf("GPA Statistics:\n");
printf(" Count: %d\n", stats.count);
printf(" Sum: %.2f\n", stats.sum);
printf(" Average: %.2f\n", stats.average);
printf(" Minimum: %.2f\n", stats.min);
printf(" Maximum: %.2f\n", stats.max);
// Find students above average
printf("\nStudents above average (%.2f):\n", stats.average);
for (int i = 0; i < n; i++) {
if (class[i].gpa > stats.average) {
printf(" %s: %.2f\n", class[i].name, class[i].gpa);
}
}
printf("\n");
}
// ============================================================
// EXAMPLE 10: Nested Structures in Array
// ============================================================
struct Address {
char city[30];
char country[30];
};
struct Contact {
char name[50];
char email[50];
struct Address address;
};
void example10_nested_in_array(void) {
printf("=== Example 10: Nested Structures in Array ===\n");
struct Contact contacts[] = {
{
.name = "John Doe",
.email = "john@example.com",
.address = {"New York", "USA"}
},
{
.name = "Jane Smith",
.email = "jane@example.com",
.address = {"London", "UK"}
},
{
.name = "Bob Wilson",
.email = "bob@example.com",
.address = {"Paris", "France"}
}
};
int n = sizeof(contacts) / sizeof(contacts[0]);
printf("Contact List:\n");
for (int i = 0; i < n; i++) {
printf(" %d. %s\n", i + 1, contacts[i].name);
printf(" Email: %s\n", contacts[i].email);
printf(" Location: %s, %s\n",
contacts[i].address.city,
contacts[i].address.country);
}
// Filter by country
printf("\nContacts in USA:\n");
for (int i = 0; i < n; i++) {
if (strcmp(contacts[i].address.country, "USA") == 0) {
printf(" - %s (%s)\n", contacts[i].name, contacts[i].address.city);
}
}
printf("\n");
}
// ============================================================
// EXAMPLE 11: Memory Layout Demonstration
// ============================================================
void example11_memory_layout(void) {
printf("=== Example 11: Memory Layout ===\n");
struct Student class[3] = {
{"Alice", 101, 3.8},
{"Bob", 102, 3.5},
{"Carol", 103, 3.9}
};
printf("Size of Student: %zu bytes\n", sizeof(struct Student));
printf("Total array size: %zu bytes\n", sizeof(class));
printf("Expected: %zu × 3 = %zu bytes\n\n",
sizeof(struct Student), sizeof(struct Student) * 3);
printf("Memory addresses:\n");
printf(" Base address: %p\n", (void*)class);
for (int i = 0; i < 3; i++) {
printf(" class[%d]: %p (offset: %ld bytes)\n",
i, (void*)&class[i],
(char*)&class[i] - (char*)class);
}
// Demonstrate pointer arithmetic
struct Student *ptr = class;
printf("\nPointer arithmetic:\n");
printf(" ptr = %p (class[0])\n", (void*)ptr);
printf(" ptr + 1 = %p (class[1])\n", (void*)(ptr + 1));
printf(" ptr + 2 = %p (class[2])\n", (void*)(ptr + 2));
printf(" Difference: %zu bytes\n",
(size_t)((char*)(ptr + 1) - (char*)ptr));
printf("\n");
}
// ============================================================
// Main Function
// ============================================================
int main(void) {
printf("*********************************************\n");
printf("* Array of Structures in C *\n");
printf("* Examples *\n");
printf("*********************************************\n\n");
example1_basic_array();
example2_iteration();
example3_initialization();
example4_functions();
example5_searching();
example6_sorting();
example7_dynamic_array();
example8_crud();
example9_statistics();
example10_nested_in_array();
example11_memory_layout();
printf("=== All Examples Completed ===\n");
return 0;
}