c
examples
examples.c🔧c
/**
* Nested Structures in C - Examples
*
* This file demonstrates nested structure concepts with practical examples.
* Compile with: gcc examples.c -o examples
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h> // For offsetof
// ============================================================
// EXAMPLE 1: Basic Nested Structure
// ============================================================
struct Date1 {
int day;
int month;
int year;
};
struct Person1 {
char name[50];
int age;
struct Date1 birth_date; // Nested structure
};
void example1_basic_nesting(void) {
printf("=== Example 1: Basic Nested Structure ===\n");
// Create and initialize using designated initializers
struct Person1 person = {
.name = "John Doe",
.age = 30,
.birth_date = {
.day = 15,
.month = 8,
.year = 1993
}
};
// Access nested members using multiple dot operators
printf("Name: %s\n", person.name);
printf("Age: %d\n", person.age);
printf("Birth Date: %02d/%02d/%d\n",
person.birth_date.day,
person.birth_date.month,
person.birth_date.year);
// Modify nested members
person.birth_date.year = 1994;
printf("Modified year: %d\n", person.birth_date.year);
printf("\n");
}
// ============================================================
// EXAMPLE 2: Multiple Nested Structures
// ============================================================
struct Address {
char street[100];
char city[50];
char state[30];
int zip_code;
};
struct Date {
int day;
int month;
int year;
};
struct Employee {
char name[50];
int emp_id;
float salary;
struct Date join_date;
struct Date birth_date;
struct Address home_address;
struct Address work_address;
};
void print_date(const char *label, struct Date d) {
printf("%s: %02d/%02d/%d\n", label, d.day, d.month, d.year);
}
void print_address(const char *label, struct Address a) {
printf("%s:\n", label);
printf(" %s\n", a.street);
printf(" %s, %s %d\n", a.city, a.state, a.zip_code);
}
void example2_multiple_nested(void) {
printf("=== Example 2: Multiple Nested Structures ===\n");
struct Employee emp = {
.name = "Alice Johnson",
.emp_id = 1001,
.salary = 75000.00,
.join_date = {1, 6, 2020},
.birth_date = {20, 3, 1992},
.home_address = {
.street = "123 Maple Avenue",
.city = "Springfield",
.state = "IL",
.zip_code = 62701
},
.work_address = {
.street = "456 Corporate Blvd",
.city = "Chicago",
.state = "IL",
.zip_code = 60601
}
};
printf("Employee: %s (ID: %d)\n", emp.name, emp.emp_id);
printf("Salary: $%.2f\n", emp.salary);
print_date("Birth Date", emp.birth_date);
print_date("Join Date", emp.join_date);
print_address("Home Address", emp.home_address);
print_address("Work Address", emp.work_address);
printf("\n");
}
// ============================================================
// EXAMPLE 3: Initializing Nested Structures
// ============================================================
struct Point {
int x;
int y;
};
struct Rectangle {
struct Point top_left;
struct Point bottom_right;
char color[20];
};
void example3_initialization_methods(void) {
printf("=== Example 3: Initialization Methods ===\n");
// Method 1: Nested braces
struct Rectangle rect1 = {
{0, 0}, // top_left
{100, 50}, // bottom_right
"Red" // color
};
// Method 2: Designated initializers
struct Rectangle rect2 = {
.top_left = {.x = 10, .y = 20},
.bottom_right = {.x = 110, .y = 70},
.color = "Blue"
};
// Method 3: Mixed
struct Rectangle rect3 = {
.top_left = {5, 5},
.bottom_right = {200, 150},
.color = "Green"
};
// Method 4: Member by member
struct Rectangle rect4;
rect4.top_left.x = 0;
rect4.top_left.y = 0;
rect4.bottom_right.x = 50;
rect4.bottom_right.y = 30;
strcpy(rect4.color, "Yellow");
printf("Rectangle 1: (%d,%d) to (%d,%d) - %s\n",
rect1.top_left.x, rect1.top_left.y,
rect1.bottom_right.x, rect1.bottom_right.y, rect1.color);
printf("Rectangle 2: (%d,%d) to (%d,%d) - %s\n",
rect2.top_left.x, rect2.top_left.y,
rect2.bottom_right.x, rect2.bottom_right.y, rect2.color);
printf("Rectangle 3: (%d,%d) to (%d,%d) - %s\n",
rect3.top_left.x, rect3.top_left.y,
rect3.bottom_right.x, rect3.bottom_right.y, rect3.color);
printf("Rectangle 4: (%d,%d) to (%d,%d) - %s\n",
rect4.top_left.x, rect4.top_left.y,
rect4.bottom_right.x, rect4.bottom_right.y, rect4.color);
printf("\n");
}
// ============================================================
// EXAMPLE 4: Pointers to Nested Structures
// ============================================================
void example4_pointers(void) {
printf("=== Example 4: Pointers to Nested Structures ===\n");
struct Person1 person = {
.name = "Bob Smith",
.age = 25,
.birth_date = {10, 5, 1998}
};
// Pointer to outer structure
struct Person1 *ptr = &person;
// Access using arrow and dot operators
printf("Using ptr->member.field:\n");
printf(" Name: %s\n", ptr->name);
printf(" Birth Year: %d\n", ptr->birth_date.year);
// Modify through pointer
ptr->birth_date.month = 6;
printf(" Modified month: %d\n", ptr->birth_date.month);
// Pointer to inner structure
struct Date1 *date_ptr = &person.birth_date;
printf("\nUsing pointer to inner structure:\n");
printf(" Day: %d\n", date_ptr->day);
printf(" Month: %d\n", date_ptr->month);
printf(" Year: %d\n", date_ptr->year);
// Modify through inner pointer
date_ptr->day = 15;
printf(" Modified day (via inner ptr): %d\n", person.birth_date.day);
printf("\n");
}
// ============================================================
// EXAMPLE 5: Passing Nested Structures to Functions
// ============================================================
// Pass entire nested structure by value
void print_person_value(struct Person1 p) {
printf(" Name: %s\n", p.name);
printf(" DOB: %02d/%02d/%d\n",
p.birth_date.day, p.birth_date.month, p.birth_date.year);
}
// Pass by pointer (efficient, can modify)
void update_birth_year(struct Person1 *p, int new_year) {
p->birth_date.year = new_year;
}
// Pass by const pointer (efficient, read-only)
void print_person_ptr(const struct Person1 *p) {
printf(" Name: %s\n", p->name);
printf(" DOB: %02d/%02d/%d\n",
p->birth_date.day, p->birth_date.month, p->birth_date.year);
}
// Return nested structure
struct Person1 create_person(const char *name, int day, int month, int year) {
struct Person1 p;
strncpy(p.name, name, sizeof(p.name) - 1);
p.name[sizeof(p.name) - 1] = '\0';
p.age = 2024 - year;
p.birth_date.day = day;
p.birth_date.month = month;
p.birth_date.year = year;
return p;
}
void example5_functions(void) {
printf("=== Example 5: Functions with Nested Structures ===\n");
struct Person1 person = {"Charlie", 30, {25, 12, 1993}};
printf("Pass by value:\n");
print_person_value(person);
printf("\nPass by pointer:\n");
print_person_ptr(&person);
printf("\nModify through pointer:\n");
printf(" Original year: %d\n", person.birth_date.year);
update_birth_year(&person, 1994);
printf(" Updated year: %d\n", person.birth_date.year);
printf("\nCreate and return:\n");
struct Person1 new_person = create_person("Diana", 1, 1, 2000);
print_person_ptr(&new_person);
printf("\n");
}
// ============================================================
// EXAMPLE 6: Deep Nesting (Multiple Levels)
// ============================================================
struct Country {
char name[50];
char code[5];
};
struct State {
char name[50];
struct Country country;
};
struct City {
char name[50];
int population;
struct State state;
};
struct FullAddress {
char street[100];
int number;
struct City city;
};
void example6_deep_nesting(void) {
printf("=== Example 6: Deep Nesting ===\n");
struct FullAddress addr = {
.street = "Main Street",
.number = 123,
.city = {
.name = "Los Angeles",
.population = 4000000,
.state = {
.name = "California",
.country = {
.name = "United States",
.code = "US"
}
}
}
};
// Access deeply nested members
printf("Full Address:\n");
printf(" %d %s\n", addr.number, addr.street);
printf(" %s (pop: %d)\n", addr.city.name, addr.city.population);
printf(" %s\n", addr.city.state.name);
printf(" %s (%s)\n",
addr.city.state.country.name,
addr.city.state.country.code);
// Modify deeply nested value
addr.city.state.country.code[0] = 'U';
addr.city.state.country.code[1] = 'S';
addr.city.state.country.code[2] = 'A';
addr.city.state.country.code[3] = '\0';
printf("\nModified country code: %s\n", addr.city.state.country.code);
printf("\n");
}
// ============================================================
// EXAMPLE 7: Anonymous Nested Structures (C11)
// ============================================================
struct Vector3D {
union {
struct {
float x;
float y;
float z;
}; // Anonymous struct
float coords[3]; // Array access
}; // Anonymous union
};
struct Widget {
int id;
struct {
int width;
int height;
}; // Anonymous struct - members directly accessible
};
void example7_anonymous(void) {
printf("=== Example 7: Anonymous Nested Structures ===\n");
struct Vector3D vec = {.x = 1.0, .y = 2.0, .z = 3.0};
// Direct access to anonymous struct members
printf("Vector using x, y, z: (%.1f, %.1f, %.1f)\n",
vec.x, vec.y, vec.z);
// Same data via array
printf("Vector using coords[]: (%.1f, %.1f, %.1f)\n",
vec.coords[0], vec.coords[1], vec.coords[2]);
// Modify through array, read through named members
vec.coords[0] = 10.0;
printf("After modifying coords[0]: x = %.1f\n", vec.x);
// Widget with anonymous struct
struct Widget w = {.id = 1, .width = 100, .height = 50};
printf("\nWidget %d: %d x %d\n", w.id, w.width, w.height);
printf("\n");
}
// ============================================================
// EXAMPLE 8: Self-Referential Structures
// ============================================================
struct Node {
int data;
struct Node *next; // Pointer to same type
};
void example8_self_referential(void) {
printf("=== Example 8: Self-Referential Structures ===\n");
// Create nodes
struct Node n1 = {10, NULL};
struct Node n2 = {20, NULL};
struct Node n3 = {30, NULL};
// Link them
n1.next = &n2;
n2.next = &n3;
// n3.next remains NULL (end of list)
// Traverse the list
printf("Linked list: ");
struct Node *current = &n1;
while (current != NULL) {
printf("%d", current->data);
if (current->next != NULL) {
printf(" -> ");
}
current = current->next;
}
printf(" -> NULL\n");
// Access through chain
printf("n1.next->data = %d\n", n1.next->data);
printf("n1.next->next->data = %d\n", n1.next->next->data);
printf("\n");
}
// ============================================================
// EXAMPLE 9: Memory Layout of Nested Structures
// ============================================================
struct Inner {
char a;
int b;
};
struct Outer {
char c;
struct Inner inner;
char d;
};
void example9_memory_layout(void) {
printf("=== Example 9: Memory Layout ===\n");
printf("Size of Inner: %zu bytes\n", sizeof(struct Inner));
printf("Size of Outer: %zu bytes\n", sizeof(struct Outer));
printf("\nOffsets in Inner:\n");
printf(" a: %zu\n", offsetof(struct Inner, a));
printf(" b: %zu\n", offsetof(struct Inner, b));
printf("\nOffsets in Outer:\n");
printf(" c: %zu\n", offsetof(struct Outer, c));
printf(" inner: %zu\n", offsetof(struct Outer, inner));
printf(" d: %zu\n", offsetof(struct Outer, d));
// Detailed addresses
struct Outer obj;
printf("\nActual addresses:\n");
printf(" &obj = %p\n", (void*)&obj);
printf(" &obj.c = %p (offset: %ld)\n",
(void*)&obj.c, (char*)&obj.c - (char*)&obj);
printf(" &obj.inner = %p (offset: %ld)\n",
(void*)&obj.inner, (char*)&obj.inner - (char*)&obj);
printf(" &obj.inner.a = %p (offset: %ld)\n",
(void*)&obj.inner.a, (char*)&obj.inner.a - (char*)&obj);
printf(" &obj.inner.b = %p (offset: %ld)\n",
(void*)&obj.inner.b, (char*)&obj.inner.b - (char*)&obj);
printf(" &obj.d = %p (offset: %ld)\n",
(void*)&obj.d, (char*)&obj.d - (char*)&obj);
printf("\n");
}
// ============================================================
// EXAMPLE 10: Real-World Application - Order System
// ============================================================
typedef struct {
char name[50];
float price;
int quantity;
} OrderItem;
typedef struct {
int day, month, year;
int hour, minute;
} Timestamp;
typedef struct {
char name[50];
char email[100];
struct Address shipping_address;
} Customer;
typedef struct {
int order_id;
Customer customer;
OrderItem items[10];
int item_count;
Timestamp created;
float total;
char status[20];
} Order;
Order create_order(int id, const char *cust_name, const char *email) {
Order order = {0}; // Initialize all to zero
order.order_id = id;
strncpy(order.customer.name, cust_name, sizeof(order.customer.name) - 1);
strncpy(order.customer.email, email, sizeof(order.customer.email) - 1);
order.created = (Timestamp){2024, 1, 15, 10, 30};
strcpy(order.status, "Pending");
return order;
}
void add_item(Order *order, const char *name, float price, int qty) {
if (order->item_count < 10) {
OrderItem *item = &order->items[order->item_count];
strncpy(item->name, name, sizeof(item->name) - 1);
item->price = price;
item->quantity = qty;
order->total += price * qty;
order->item_count++;
}
}
void print_order(const Order *order) {
printf("Order #%d - %s\n", order->order_id, order->status);
printf("Customer: %s (%s)\n", order->customer.name, order->customer.email);
printf("Created: %02d/%02d/%d %02d:%02d\n",
order->created.day, order->created.month, order->created.year,
order->created.hour, order->created.minute);
printf("\nItems:\n");
for (int i = 0; i < order->item_count; i++) {
printf(" %d. %s - $%.2f x %d = $%.2f\n",
i + 1,
order->items[i].name,
order->items[i].price,
order->items[i].quantity,
order->items[i].price * order->items[i].quantity);
}
printf("\nTotal: $%.2f\n", order->total);
}
void example10_real_world(void) {
printf("=== Example 10: Real-World Order System ===\n");
Order order = create_order(1001, "John Doe", "john@example.com");
// Set shipping address
strcpy(order.customer.shipping_address.street, "123 Main St");
strcpy(order.customer.shipping_address.city, "New York");
strcpy(order.customer.shipping_address.state, "NY");
order.customer.shipping_address.zip_code = 10001;
// Add items
add_item(&order, "Laptop", 999.99, 1);
add_item(&order, "Mouse", 29.99, 2);
add_item(&order, "USB Cable", 9.99, 3);
print_order(&order);
printf("\n");
}
// ============================================================
// EXAMPLE 11: Copying Nested Structures
// ============================================================
void example11_copying(void) {
printf("=== Example 11: Copying Nested Structures ===\n");
struct Employee emp1 = {
.name = "Original Employee",
.emp_id = 1,
.salary = 50000,
.join_date = {1, 1, 2020},
.birth_date = {15, 6, 1990},
.home_address = {"123 Home St", "City A", "State A", 11111},
.work_address = {"456 Work Ave", "City B", "State B", 22222}
};
// Structure assignment - deep copy of all members
struct Employee emp2 = emp1;
// Verify independence
strcpy(emp2.name, "Copied Employee");
emp2.emp_id = 2;
emp2.join_date.year = 2021;
strcpy(emp2.home_address.city, "City C");
printf("Original Employee:\n");
printf(" Name: %s, ID: %d\n", emp1.name, emp1.emp_id);
printf(" Join Year: %d\n", emp1.join_date.year);
printf(" Home City: %s\n", emp1.home_address.city);
printf("\nCopied Employee (modified):\n");
printf(" Name: %s, ID: %d\n", emp2.name, emp2.emp_id);
printf(" Join Year: %d\n", emp2.join_date.year);
printf(" Home City: %s\n", emp2.home_address.city);
printf("\nOriginal unchanged - structures are independent\n");
printf("\n");
}
// ============================================================
// Main Function
// ============================================================
int main(void) {
printf("*********************************************\n");
printf("* Nested Structures in C *\n");
printf("* Examples *\n");
printf("*********************************************\n\n");
example1_basic_nesting();
example2_multiple_nested();
example3_initialization_methods();
example4_pointers();
example5_functions();
example6_deep_nesting();
example7_anonymous();
example8_self_referential();
example9_memory_layout();
example10_real_world();
example11_copying();
printf("=== All Examples Completed ===\n");
return 0;
}