c

examples

examples.c🔧
/**
 * Structure Basics in C - Examples
 * 
 * This file demonstrates fundamental structure concepts with
 * practical examples. Compile with: gcc examples.c -o examples
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// ============================================================
// EXAMPLE 1: Basic Structure Declaration and Usage
// ============================================================

struct Point {
    int x;
    int y;
};

void example1_basic_structure(void) {
    printf("=== Example 1: Basic Structure ===\n");
    
    // Creating structure variables
    struct Point p1;
    struct Point p2;
    
    // Assigning values using dot operator
    p1.x = 10;
    p1.y = 20;
    
    p2.x = 30;
    p2.y = 40;
    
    printf("Point 1: (%d, %d)\n", p1.x, p1.y);
    printf("Point 2: (%d, %d)\n", p2.x, p2.y);
    
    // Structure assignment
    struct Point p3 = p1;  // Copy p1 to p3
    printf("Point 3 (copy of p1): (%d, %d)\n", p3.x, p3.y);
    
    // Modifying p3 doesn't affect p1
    p3.x = 100;
    printf("After modifying p3:\n");
    printf("  p1: (%d, %d)\n", p1.x, p1.y);
    printf("  p3: (%d, %d)\n", p3.x, p3.y);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 2: Structure with Different Data Types
// ============================================================

struct Student {
    char name[50];
    int roll_number;
    float gpa;
    int age;
    char grade;
};

void example2_mixed_types(void) {
    printf("=== Example 2: Structure with Mixed Types ===\n");
    
    struct Student s1;
    
    // Assigning values to each member
    strcpy(s1.name, "John Doe");
    s1.roll_number = 101;
    s1.gpa = 3.75;
    s1.age = 20;
    s1.grade = 'A';
    
    printf("Student Information:\n");
    printf("  Name: %s\n", s1.name);
    printf("  Roll Number: %d\n", s1.roll_number);
    printf("  GPA: %.2f\n", s1.gpa);
    printf("  Age: %d\n", s1.age);
    printf("  Grade: %c\n", s1.grade);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 3: Structure Initialization Methods
// ============================================================

struct Date {
    int day;
    int month;
    int year;
};

void example3_initialization(void) {
    printf("=== Example 3: Structure Initialization ===\n");
    
    // Method 1: Initializer list (order matters)
    struct Date date1 = {15, 8, 2024};
    
    // Method 2: Designated initializers (C99 - order doesn't matter)
    struct Date date2 = {
        .year = 2024,
        .day = 20,
        .month = 12
    };
    
    // Method 3: Partial initialization (unspecified members = 0)
    struct Date date3 = {1};  // day=1, month=0, year=0
    
    // Method 4: Zero initialization
    struct Date date4 = {0};  // All members set to 0
    
    printf("Date 1 (initializer list): %02d/%02d/%d\n", 
           date1.day, date1.month, date1.year);
    printf("Date 2 (designated): %02d/%02d/%d\n", 
           date2.day, date2.month, date2.year);
    printf("Date 3 (partial): %02d/%02d/%d\n", 
           date3.day, date3.month, date3.year);
    printf("Date 4 (zero init): %02d/%02d/%d\n", 
           date4.day, date4.month, date4.year);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 4: Structure Size and Padding
// ============================================================

// Poorly ordered structure
struct Padded1 {
    char a;     // 1 byte
    int b;      // 4 bytes
    char c;     // 1 byte
};

// Well ordered structure
struct Padded2 {
    int b;      // 4 bytes
    char a;     // 1 byte
    char c;     // 1 byte
};

// Mixed types
struct Mixed {
    char a;
    short b;
    int c;
    char d;
    double e;
};

void example4_size_and_padding(void) {
    printf("=== Example 4: Size and Padding ===\n");
    
    printf("sizeof(char)   = %zu bytes\n", sizeof(char));
    printf("sizeof(short)  = %zu bytes\n", sizeof(short));
    printf("sizeof(int)    = %zu bytes\n", sizeof(int));
    printf("sizeof(double) = %zu bytes\n", sizeof(double));
    printf("\n");
    
    printf("Padded1 (char, int, char):\n");
    printf("  Expected size: 1 + 4 + 1 = 6 bytes\n");
    printf("  Actual size: %zu bytes (includes padding)\n", sizeof(struct Padded1));
    
    printf("\nPadded2 (int, char, char):\n");
    printf("  Expected size: 4 + 1 + 1 = 6 bytes\n");
    printf("  Actual size: %zu bytes\n", sizeof(struct Padded2));
    
    printf("\nMixed structure:\n");
    printf("  Members: char + short + int + char + double\n");
    printf("  Minimum size: 1 + 2 + 4 + 1 + 8 = 16 bytes\n");
    printf("  Actual size: %zu bytes\n", sizeof(struct Mixed));
    
    // Show member offsets
    struct Padded1 p1;
    printf("\nPadded1 member addresses:\n");
    printf("  Address of struct: %p\n", (void*)&p1);
    printf("  Address of a: %p (offset: %ld)\n", (void*)&p1.a, (char*)&p1.a - (char*)&p1);
    printf("  Address of b: %p (offset: %ld)\n", (void*)&p1.b, (char*)&p1.b - (char*)&p1);
    printf("  Address of c: %p (offset: %ld)\n", (void*)&p1.c, (char*)&p1.c - (char*)&p1);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 5: typedef with Structures
// ============================================================

// Method 1: typedef after structure
struct Rectangle_s {
    int width;
    int height;
};
typedef struct Rectangle_s Rectangle;

// Method 2: typedef with anonymous structure
typedef struct {
    float real;
    float imag;
} Complex;

// Method 3: typedef with named structure (for self-reference)
typedef struct Node_s {
    int data;
    struct Node_s *next;  // Self-reference needs struct keyword
} Node;

void example5_typedef(void) {
    printf("=== Example 5: typedef with Structures ===\n");
    
    // Using Rectangle (needs struct keyword internally, not externally)
    Rectangle rect = {10, 5};
    printf("Rectangle: %d x %d = %d sq units\n", 
           rect.width, rect.height, rect.width * rect.height);
    
    // Using Complex
    Complex c1 = {3.0, 4.0};
    Complex c2 = {1.0, 2.0};
    printf("Complex 1: %.1f + %.1fi\n", c1.real, c1.imag);
    printf("Complex 2: %.1f + %.1fi\n", c2.real, c2.imag);
    
    // Complex addition
    Complex sum = {c1.real + c2.real, c1.imag + c2.imag};
    printf("Sum: %.1f + %.1fi\n", sum.real, sum.imag);
    
    // Using Node
    Node n1 = {10, NULL};
    Node n2 = {20, NULL};
    n1.next = &n2;
    printf("Node 1: %d -> ", n1.data);
    printf("Node 2: %d\n", n1.next->data);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 6: Nested Structures
// ============================================================

struct Address {
    char street[100];
    char city[50];
    char state[30];
    int zip_code;
};

struct Employee {
    char name[50];
    int emp_id;
    float salary;
    struct Date join_date;
    struct Address address;
};

void example6_nested_structures(void) {
    printf("=== Example 6: Nested Structures ===\n");
    
    // Initialize using designated initializers
    struct Employee emp = {
        .name = "Alice Johnson",
        .emp_id = 1001,
        .salary = 75000.00,
        .join_date = {1, 6, 2020},
        .address = {
            .street = "123 Main Street",
            .city = "New York",
            .state = "NY",
            .zip_code = 10001
        }
    };
    
    printf("Employee Information:\n");
    printf("  Name: %s\n", emp.name);
    printf("  ID: %d\n", emp.emp_id);
    printf("  Salary: $%.2f\n", emp.salary);
    printf("  Join Date: %02d/%02d/%d\n", 
           emp.join_date.day, emp.join_date.month, emp.join_date.year);
    printf("  Address:\n");
    printf("    %s\n", emp.address.street);
    printf("    %s, %s %d\n", 
           emp.address.city, emp.address.state, emp.address.zip_code);
    
    printf("\nSize of Employee structure: %zu bytes\n", sizeof(struct Employee));
    
    printf("\n");
}

// ============================================================
// EXAMPLE 7: Structures and Functions
// ============================================================

// Function that takes structure by value
void print_point(struct Point p) {
    printf("Point: (%d, %d)\n", p.x, p.y);
}

// Function that modifies structure (by value - no effect on original)
void try_modify_point(struct Point p) {
    p.x = 999;
    p.y = 999;
    printf("Inside function: (%d, %d)\n", p.x, p.y);
}

// Function that returns structure
struct Point create_point(int x, int y) {
    struct Point p;
    p.x = x;
    p.y = y;
    return p;
}

// Function returning structure with multiple values
struct DivResult {
    int quotient;
    int remainder;
    int valid;
};

struct DivResult divide(int a, int b) {
    struct DivResult result = {0, 0, 0};
    
    if (b != 0) {
        result.quotient = a / b;
        result.remainder = a % b;
        result.valid = 1;
    }
    
    return result;
}

void example7_functions(void) {
    printf("=== Example 7: Structures and Functions ===\n");
    
    // Pass structure to function
    struct Point p1 = {10, 20};
    printf("Original point: ");
    print_point(p1);
    
    // Trying to modify (won't affect original)
    printf("Trying to modify through function...\n");
    try_modify_point(p1);
    printf("After function call: ");
    print_point(p1);  // Still (10, 20)
    
    // Function returning structure
    struct Point p2 = create_point(30, 40);
    printf("Created point: ");
    print_point(p2);
    
    // Returning multiple values
    struct DivResult r = divide(17, 5);
    if (r.valid) {
        printf("17 / 5 = %d remainder %d\n", r.quotient, r.remainder);
    }
    
    struct DivResult r2 = divide(10, 0);
    if (!r2.valid) {
        printf("Division by zero detected!\n");
    }
    
    printf("\n");
}

// ============================================================
// EXAMPLE 8: Structure Comparison
// ============================================================

void example8_comparison(void) {
    printf("=== Example 8: Structure Comparison ===\n");
    
    struct Point p1 = {10, 20};
    struct Point p2 = {10, 20};
    struct Point p3 = {30, 40};
    
    // Cannot use == directly
    // if (p1 == p2)  // This would be an ERROR
    
    // Must compare member by member
    if (p1.x == p2.x && p1.y == p2.y) {
        printf("p1 and p2 are equal\n");
    } else {
        printf("p1 and p2 are different\n");
    }
    
    if (p1.x == p3.x && p1.y == p3.y) {
        printf("p1 and p3 are equal\n");
    } else {
        printf("p1 and p3 are different\n");
    }
    
    // Using memcmp (works but be careful with padding)
    struct Point p4 = {10, 20};
    if (memcmp(&p1, &p4, sizeof(struct Point)) == 0) {
        printf("p1 and p4 are equal (memcmp)\n");
    }
    
    // Comparison function
    printf("\n");
}

// ============================================================
// EXAMPLE 9: Anonymous Structures and Unions (C11)
// ============================================================

// Anonymous structure inside a structure
struct Container {
    int id;
    struct {
        int x;
        int y;
    };  // Anonymous - members accessible directly
};

void example9_anonymous(void) {
    printf("=== Example 9: Anonymous Structures ===\n");
    
    struct Container c = {
        .id = 1,
        .x = 100,
        .y = 200
    };
    
    printf("Container:\n");
    printf("  ID: %d\n", c.id);
    printf("  X: %d (direct access, no intermediate name)\n", c.x);
    printf("  Y: %d\n", c.y);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 10: Real-World Structure Example
// ============================================================

typedef struct {
    int year;
    char make[30];
    char model[30];
    float price;
    int mileage;
    char color[20];
} Car;

Car create_car(int year, const char *make, const char *model, 
               float price, int mileage, const char *color) {
    Car car;
    car.year = year;
    strncpy(car.make, make, sizeof(car.make) - 1);
    car.make[sizeof(car.make) - 1] = '\0';
    strncpy(car.model, model, sizeof(car.model) - 1);
    car.model[sizeof(car.model) - 1] = '\0';
    car.price = price;
    car.mileage = mileage;
    strncpy(car.color, color, sizeof(car.color) - 1);
    car.color[sizeof(car.color) - 1] = '\0';
    return car;
}

void print_car(const Car *car) {
    printf("Car Details:\n");
    printf("  %d %s %s\n", car->year, car->make, car->model);
    printf("  Color: %s\n", car->color);
    printf("  Mileage: %d miles\n", car->mileage);
    printf("  Price: $%.2f\n", car->price);
}

void apply_discount(Car *car, float percent) {
    car->price *= (1 - percent / 100);
}

void example10_real_world(void) {
    printf("=== Example 10: Real-World Example ===\n");
    
    // Create cars
    Car car1 = create_car(2022, "Toyota", "Camry", 28000.00, 15000, "Silver");
    Car car2 = create_car(2020, "Honda", "Civic", 22000.00, 35000, "Blue");
    
    print_car(&car1);
    printf("\n");
    print_car(&car2);
    
    // Apply discount
    printf("\nApplying 10%% discount to Toyota...\n");
    apply_discount(&car1, 10);
    printf("New price: $%.2f\n", car1.price);
    
    printf("\n");
}

// ============================================================
// EXAMPLE 11: Structure Memory Layout Visualization
// ============================================================

struct LayoutExample {
    char a;      // offset 0
    int b;       // offset 4 (padding after a)
    short c;     // offset 8
    char d;      // offset 10
    double e;    // offset 16 (padding after d)
    char f;      // offset 24
};

void example11_memory_layout(void) {
    printf("=== Example 11: Memory Layout Visualization ===\n");
    
    struct LayoutExample obj;
    
    printf("Structure LayoutExample:\n");
    printf("  Total size: %zu bytes\n\n", sizeof(struct LayoutExample));
    
    printf("  Member   Type      Offset   Size\n");
    printf("  ------   ------    ------   ----\n");
    printf("  a        char      %zu        %zu\n", 
           (size_t)((char*)&obj.a - (char*)&obj), sizeof(obj.a));
    printf("  b        int       %zu        %zu\n", 
           (size_t)((char*)&obj.b - (char*)&obj), sizeof(obj.b));
    printf("  c        short     %zu        %zu\n", 
           (size_t)((char*)&obj.c - (char*)&obj), sizeof(obj.c));
    printf("  d        char      %zu       %zu\n", 
           (size_t)((char*)&obj.d - (char*)&obj), sizeof(obj.d));
    printf("  e        double    %zu       %zu\n", 
           (size_t)((char*)&obj.e - (char*)&obj), sizeof(obj.e));
    printf("  f        char      %zu       %zu\n", 
           (size_t)((char*)&obj.f - (char*)&obj), sizeof(obj.f));
    
    printf("\nPadding bytes: %zu - %zu = %zu bytes\n",
           sizeof(struct LayoutExample),
           sizeof(char)*3 + sizeof(int) + sizeof(short) + sizeof(double),
           sizeof(struct LayoutExample) - (sizeof(char)*3 + sizeof(int) + sizeof(short) + sizeof(double)));
    
    printf("\n");
}

// ============================================================
// EXAMPLE 12: Copying Structures with Pointer Members
// ============================================================

struct StringHolder {
    char *str;
    int length;
};

void example12_shallow_copy_danger(void) {
    printf("=== Example 12: Shallow Copy Danger ===\n");
    
    // Create first structure with dynamically allocated string
    struct StringHolder s1;
    s1.str = malloc(50);
    strcpy(s1.str, "Hello, World!");
    s1.length = strlen(s1.str);
    
    printf("s1.str = \"%s\" (address: %p)\n", s1.str, (void*)s1.str);
    
    // Shallow copy
    struct StringHolder s2 = s1;
    printf("After s2 = s1 (shallow copy):\n");
    printf("s2.str = \"%s\" (address: %p)\n", s2.str, (void*)s2.str);
    printf("Both point to SAME memory!\n\n");
    
    // Modifying through s2 affects s1
    s2.str[0] = 'J';
    printf("After s2.str[0] = 'J':\n");
    printf("s1.str = \"%s\"\n", s1.str);
    printf("s2.str = \"%s\"\n", s2.str);
    printf("Both changed because they share memory!\n\n");
    
    // Deep copy solution
    struct StringHolder s3;
    s3.length = s1.length;
    s3.str = malloc(s3.length + 1);
    strcpy(s3.str, s1.str);
    
    printf("After deep copy to s3:\n");
    s3.str[0] = 'M';  // Modify s3
    printf("s1.str = \"%s\"\n", s1.str);  // s1 unchanged
    printf("s3.str = \"%s\"\n", s3.str);
    printf("s3 is independent!\n");
    
    // Clean up
    free(s1.str);  // Also frees s2.str (same pointer)
    free(s3.str);
    
    printf("\n");
}

// ============================================================
// Main Function
// ============================================================

int main(void) {
    printf("*********************************************\n");
    printf("*       Structure Basics in C              *\n");
    printf("*            Examples                      *\n");
    printf("*********************************************\n\n");
    
    example1_basic_structure();
    example2_mixed_types();
    example3_initialization();
    example4_size_and_padding();
    example5_typedef();
    example6_nested_structures();
    example7_functions();
    example8_comparison();
    example9_anonymous();
    example10_real_world();
    example11_memory_layout();
    example12_shallow_copy_danger();
    
    printf("=== All Examples Completed ===\n");
    
    return 0;
}
Examples - C Programming Tutorial | DeepML