Back to Curriculum

Structures and Unions

📚 Lesson 7 of 15 ⏱️ 40 min

Structures and Unions

40 min

Structures (structs) group related data of different types under a single name, enabling you to create custom data types that represent real-world entities. Structures enable organizing related data together, making programs more readable and maintainable. Structures are essential for building complex data models in C. Understanding structures enables effective data organization.

Structure definitions specify the struct name and member variables with their types. Structure variables are declared using the struct keyword. Members are accessed using the dot operator (.) for structure variables or the arrow operator (->) for structure pointers. Structures can contain other structures, enabling nested data organization. Understanding structure syntax enables proper structure usage.

Structures can be initialized at declaration using designated initializers or passed by value or reference to functions. Structures are passed by value by default (copied), which can be expensive for large structures. Passing structure pointers is more efficient. Understanding structure passing enables efficient function design.

Unions are similar to structures but all members share the same memory space. Only one member can be active at a time. Unions are useful for memory-efficient storage when you need to store different types in the same location. Unions are smaller than structures but require careful management of which member is active. Understanding unions enables memory-efficient programming.

Structure and union members can be accessed directly or through pointers. The dot operator (.) accesses members of structure variables, while the arrow operator (->) accesses members through pointers. Understanding member access enables proper structure manipulation.

Structures enable building complex data structures like linked lists, trees, and graphs. Structures can contain pointers to other structures, enabling dynamic data structures. Understanding structures enables implementing advanced data structures in C.

Key Concepts

  • Structures group related data of different types.
  • Structure members are accessed with . (dot) or -> (arrow) operators.
  • Unions share memory space among members.
  • Structures can be nested and contain pointers.
  • Structures enable complex data organization.

Learning Objectives

Master

  • Creating and using structures
  • Accessing structure members
  • Understanding unions and their use cases
  • Using structures with pointers

Develop

  • Understanding data organization in C
  • Designing custom data types
  • Implementing complex data structures

Tips

  • Define structures: struct Name { type member1; type member2; };
  • Access members: struct_var.member or struct_ptr->member.
  • Initialize structures: struct Person p = {"Name", 25, 1.75};
  • Use unions for memory efficiency: when only one member is needed at a time.

Common Pitfalls

  • Not understanding structure vs union, using wrong type.
  • Accessing union members incorrectly, reading wrong data.
  • Passing large structures by value, causing performance issues.
  • Not initializing structure members, causing undefined values.

Summary

  • Structures enable grouping related data of different types.
  • Unions share memory space for memory efficiency.
  • Structures enable complex data organization.
  • Understanding structures enables effective data modeling.

Exercise

Create structures and unions to organize data.

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

// Structure definition
struct Person {
    char name[50];
    int age;
    float height;
};

// Structure with nested structure
struct Address {
    char street[100];
    char city[50];
    char state[20];
    int zipCode;
};

struct Employee {
    struct Person person;
    struct Address address;
    float salary;
    int employeeId;
};

// Union example
union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    // Structure usage
    struct Person person1 = {"John Doe", 30, 1.75};
    
    printf("Person: %s, Age: %d, Height: %.2f
", 
           person1.name, person1.age, person1.height);
    
    // Structure with pointer
    struct Person *personPtr = &person1;
    printf("Via pointer: %s, Age: %d
", 
           personPtr->name, personPtr->age);
    
    // Nested structure
    struct Employee emp = {
        {"Jane Smith", 25, 1.65},
        {"123 Main St", "New York", "NY", 10001},
        50000.0,
        1001
    };
    
    printf("Employee: %s
", emp.person.name);
    printf("Address: %s, %s, %s %d
", 
           emp.address.street, emp.address.city, 
           emp.address.state, emp.address.zipCode);
    printf("Salary: $%.2f
", emp.salary);
    
    // Union usage
    union Data data;
    
    data.i = 10;
    printf("Union as int: %d
", data.i);
    
    data.f = 3.14;
    printf("Union as float: %.2f
", data.f);
    
    strcpy(data.str, "Hello");
    printf("Union as string: %s
", data.str);
    
    // Array of structures
    struct Person people[3] = {
        {"Alice", 25, 1.60},
        {"Bob", 30, 1.80},
        {"Charlie", 35, 1.70}
    };
    
    printf("People:
");
    for (int i = 0; i < 3; i++) {
        printf("%s, %d years old
", people[i].name, people[i].age);
    }
    
    return 0;
}

Exercise Tips

  • Use typedef for cleaner syntax: typedef struct Person Person; then use Person p;
  • Pass structure pointers: void func(struct Person *p) for efficiency.
  • Initialize structures: use designated initializers for clarity.
  • Use unions carefully: only one member is valid at a time.

Code Editor

Output