SrcForge

Lesson 19

Structures and Unions

Structures (struct) and unions (union) are user-defined data types in C that allow you to group multiple variables of different data types under a single name. A structure allocates separate memory for each member, while a union shares the same memory location among all its members.

C Track

Save progress as you learn.

44 lessons

Lesson content

Structures and Unions in C Programming: A Complete Beginner to Advanced Guide

What are Structures and Unions in C Programming?

Structures (struct) and unions (union) are user-defined data types in C that allow you to group multiple variables of different data types under a single name.

While both can store different types of data together, they differ in how memory is allocated: a structure allocates separate memory for each member, while a union shares the same memory location among all its members.

Think of a structure as a toolbox with separate compartments, where each tool has its own space. A union, on the other hand, is like one compartment that can hold only one tool at a time.

Why Do Structures and Unions Exist?

In real-world programs, related information often belongs together. For example, a student has a name, roll number, and marks. Instead of managing these as separate variables, structures and unions let you organize them into a single entity.

They help to:

  • Group related data
  • Improve code organization
  • Simplify data management
  • Save memory (using unions)
  • Model real-world objects

Real-World Use Cases

Structures and unions are widely used in:

  • Student and employee management systems
  • Banking applications
  • Inventory systems
  • File handling
  • Graphics programming
  • Network packet processing
  • Embedded systems
  • Operating systems

Prerequisites

Before learning Structures and Unions in C Programming, you should understand:

  • Variables and data types
  • Arrays
  • Functions
  • Pointers (recommended)
  • Input and output functions

Core Concepts of Structures and Unions in C Programming

What is a Structure?

A structure is a user-defined data type that groups variables of different data types into a single unit.

Syntax

struct StructureName
{
    dataType member1;
    dataType member2;
    dataType member3;
};

Example

struct Student
{
    int rollNo;
    char name[50];
    float marks;
};

Declaring Structure Variables

struct Student student1;

Or multiple variables:

struct Student student1, student2;

Accessing Structure Members

Use the dot (.) operator.

student1.rollNo = 101;

What is a Union?

A union is also a user-defined data type, but all its members share the same memory location.

Syntax

union UnionName
{
    dataType member1;
    dataType member2;
};

Example

union Data
{
    int number;
    float decimal;
    char letter;
};

Only one member contains a meaningful value at any given time because writing to one member overwrites the others.

Memory Difference

Structure: each member gets separate memory (rollNo, name, and marks each occupy their own space). Total size is approximately the sum of member sizes, plus possible padding for alignment.

Union: all members share the same memory. Total size equals the size of the largest member, plus alignment requirements.

Initializing Structures

struct Student student = {101, "Alice", 95.5};

Initializing Unions

union Data value = {.number = 100};

Nested Structures

A structure can contain another structure.

struct Address
{
    char city[30];
};

struct Student
{
    char name[30];
    struct Address address;
};

Access nested members using:

student.address.city

Array of Structures

struct Student students[3];

Useful for storing records.

Pointer to Structure

Use the arrow (->) operator.

struct Student student;

struct Student *ptr = &student;

ptr->rollNo = 10;

Structure vs Union

FeatureStructureUnion
Memory AllocationSeparate for each memberShared among all members
SizeSum of member sizes (plus padding)Size of the largest member (plus alignment)
MembersAll members can store values simultaneouslyOnly one member is valid at a time
Memory EfficiencyLowerHigher
Use CaseStore complete recordsSave memory for mutually exclusive data

Code Examples

Example 1: Beginner – Structure Example

#include <stdio.h>                              // Include standard input/output library

struct Student                                 // Define a structure
{
    int rollNo;                                // Student roll number
    char name[30];                             // Student name
    float marks;                               // Student marks
};

int main(void)                                 // Program entry point
{
    struct Student student;                    // Declare a structure variable

    student.rollNo = 101;                      // Assign the roll number

    snprintf(student.name, sizeof(student.name), "Alice"); // Copy a string safely into the name array

    student.marks = 95.5f;                     // Assign the marks

    printf("Roll No : %d\n", student.rollNo);  // Print the roll number

    printf("Name    : %s\n", student.name);    // Print the name

    printf("Marks   : %.1f\n", student.marks); // Print the marks

    return 0;                                  // End the program
}

Example 2: Beginner – Union Example

#include <stdio.h>                              // Include standard input/output library

union Data                                      // Define a union
{
    int number;                                 // Integer member
    float decimal;                              // Floating-point member
};

int main(void)                                  // Program entry point
{
    union Data value;                           // Declare a union variable

    value.number = 100;                         // Store an integer

    printf("Number = %d\n", value.number);      // Print the integer

    value.decimal = 25.5f;                      // Store a float (overwrites previous value)

    printf("Decimal = %.1f\n", value.decimal);  // Print the float

    return 0;                                   // End the program
}

Example 3: Intermediate – Array of Structures

#include <stdio.h>                               // Include standard input/output library

struct Student                                   // Define a structure
{
    int rollNo;                                  // Roll number
    char name[20];                               // Student name
};

int main(void)                                   // Program entry point
{
    struct Student students[2] =                 // Create an array of structures
    {
        {1, "Alice"},                            // Initialize first student
        {2, "Bob"}                               // Initialize second student
    };

    for (int i = 0; i < 2; i++)                  // Loop through the array
    {
        printf("%d %s\n",                        // Print student details
               students[i].rollNo,
               students[i].name);
    }

    return 0;                                    // End the program
}

Example 4: Intermediate – Pointer to Structure

#include <stdio.h>                               // Include standard input/output library

struct Employee                                  // Define a structure
{
    int id;                                      // Employee ID
    float salary;                                // Employee salary
};

int main(void)                                   // Program entry point
{
    struct Employee employee = {101, 50000.0f};  // Initialize the structure

    struct Employee *ptr = &employee;            // Create a pointer to the structure

    printf("ID = %d\n", ptr->id);                // Access member using the arrow operator

    printf("Salary = %.2f\n", ptr->salary);      // Access member using the arrow operator

    return 0;                                    // End the program
}

Example 5: Advanced – Nested Structure

#include <stdio.h>                               // Include standard input/output library

struct Address                                   // Define the Address structure
{
    char city[30];                               // City name
};

struct Student                                   // Define the Student structure
{
    char name[30];                               // Student name
    struct Address address;                      // Nested Address structure
};

int main(void)                                   // Program entry point
{
    struct Student student =                     // Initialize the nested structure
    {
        "Alice",
        {"Chennai"}
    };

    printf("Name : %s\n", student.name);         // Print the student's name

    printf("City : %s\n", student.address.city); // Print the city

    return 0;                                    // End the program
}

Common Mistakes and Pitfalls

WrongCorrect
Using . with a structure pointerUse ->
Assuming a union stores all member values simultaneouslyOnly one member is valid at a time
Forgetting to initialize membersInitialize before use
Accessing an inactive union memberRead only the most recently written member (except in implementation-specific scenarios)
Ignoring structure paddingBe aware that padding affects structure size

Wrong:

struct Student student;

struct Student *ptr = &student;

ptr.rollNo = 10;

Correct:

struct Student student;

struct Student *ptr = &student;

ptr->rollNo = 10;

Best Practices

  • Use structures for storing related data that must exist simultaneously.
  • Use unions only when members are mutually exclusive.
  • Give structures and unions meaningful names.
  • Initialize members before accessing them.
  • Use pointers for passing large structures to functions to avoid unnecessary copying.
  • Consider alignment and padding when working with memory-sensitive applications.
  • Use typedef to simplify complex structure declarations when appropriate.

When NOT to Use This

Avoid using structures or unions when:

  • A single variable is sufficient.
  • Dynamic collections are better represented by linked data structures or dynamic arrays.
  • Memory sharing is unnecessary (avoid unions if all values need to exist simultaneously).
  • Object-oriented features such as inheritance or polymorphism are required (not available in C).

Summary / Key Takeaways

  • Structures and Unions in C programming are user-defined data types.
  • Structures allocate separate memory for each member.
  • Unions share memory among all members.
  • Use the . operator to access structure or union members directly.
  • Use the -> operator to access members through a pointer.
  • Structures are ideal for storing complete records.
  • Unions are useful for saving memory when only one member is needed at a time.
  • Arrays, pointers, and nested structures work seamlessly with structures.
  • Understanding memory layout helps write efficient and reliable C programs.

FAQ About Structures and Unions in C

1. What is the difference between a structure and a union?

A structure allocates separate memory for each member, allowing all members to hold values simultaneously. A union shares the same memory among all members, so only one member's value is reliably stored at a time.

2. Why are unions memory efficient?

Because all members share the same memory location, a union's size is determined by its largest member (plus any alignment requirements), reducing memory usage when only one value is needed at a time.

3. Can a structure contain another structure?

Yes. This is called a nested structure, and it helps organize related data hierarchically.

4. What is the difference between the . and -> operators?

Use the . operator to access members of a structure or union variable, and use the -> operator to access members through a pointer to a structure or union.

5. When should I use a union instead of a structure?

Use a union when different data types are mutually exclusive, meaning only one of them needs to be stored at any given time—for example, representing different types of sensor readings or protocol messages where only one field is active.

Prev: PointersBack to hub