• Home
  • Struct vs Union in C: Understanding When and Why to Use Each

Struct vs Union in C: Understanding When and Why to Use Each

Struct vs Union in C: Understanding When and Why to Use Each
  • Raja Gupta
  • May 31, 2026

If you’ve been learning C for a while, you’ve probably come across both struct and union.

At first glance, they look almost identical.

Both allow you to group multiple data types together. Both use similar syntax. Both are commonly used in embedded systems.

So naturally, many beginners ask:

“If structs and unions look so similar, why does C have both?”

The answer becomes clear when you understand how memory is allocated internally.

And once you start working with embedded systems, communication protocols, sensor data, or memory-constrained microcontrollers, unions suddenly become much more interesting than they first appear.

Why Structs Are Easy to Understand

Imagine you’re building a small weather station.

For each sensor reading, you want to store:

  • temperature
  • humidity
  • pressure

A structure is perfect for this.

struct SensorData
{
    float temperature;
    float humidity;
    int pressure;
};

Now you can create a variable:

struct SensorData sensor;

and access individual members:

sensor.temperature = 28.5;
sensor.humidity = 65.0;
sensor.pressure = 1013;

Simple.

Every piece of information gets its own dedicated storage location in memory.

That is the key idea behind structures:

Every member exists independently at the same time.

If you store temperature, humidity, and pressure, all three values remain available simultaneously.

What Actually Happens in Memory

Let’s look at a smaller example.

struct Example
{
    char a;
    int b;
};

Assume:

char = 1 byte
int  = 4 bytes

The structure allocates memory for both variables.

+----+----+----+----+----+
| a  |       b        |
+----+----+----+----+----+

Both members get their own storage.

This means:

example.a = 'A';
example.b = 100;

Both values coexist safely.

You can access either one whenever needed.

This is why structures are used so frequently in software development.

They represent real-world objects containing multiple properties.

Examples include:

  • employee records
  • sensor data
  • student information
  • device configuration
  • communication packets

Where Beginners Get Confused About Unions

Now let’s look at a union.

union Example
{
    char a;
    int b;
};

The syntax looks almost identical.

Many beginners assume memory works the same way.

It doesn’t.

This is where things become interesting.

Unlike structures, a union does not allocate separate memory for every member.

Instead:

All members share the same memory location.

Think of a union as one storage box that can be used in different ways.

Visualizing a Union

Consider:

union Data
{
    char ch;
    int num;
    float value;
};

The compiler examines all members.

char  = 1 byte
int   = 4 bytes
float = 4 bytes

The largest member is 4 bytes.

Therefore, the entire union occupies only 4 bytes.

+----+----+----+----+
| Shared Memory Area |
+----+----+----+----+

Every member uses this same memory block.

That means:

union Data d;

d.num = 100;

stores 100 in memory.

But then:

d.value = 25.5;

overwrites the same memory.

The previous integer value is gone.

Only the most recently written member remains valid.

The Simplest Way to Remember the Difference

A good mental model is:

Structure

One room per member
Temperature Room
Humidity Room
Pressure Room

All values can exist together.

Union

One room shared by everyone

Only one member can reliably occupy the room at a time.

This single idea explains almost everything about structs and unions.

Why Would Anyone Use a Union Then?

This is usually the next question.

If unions overwrite data, why use them at all?

The answer is memory efficiency.

Consider a microcontroller with:

2 KB RAM

This is common on smaller embedded devices.

Every byte matters.

Suppose a communication packet can contain either:

  • a temperature value
  • a pressure value
  • an error code

But never all three at the same time.

Using a structure:

struct Packet
{
    float temperature;
    float pressure;
    int errorCode;
};

allocates memory for all members.

Even though only one is used.

A union:

union Packet
{
    float temperature;
    float pressure;
    int errorCode;
};

stores only one active value.

This reduces memory consumption significantly.

In embedded systems, those savings add up quickly.

A Real Embedded Systems Example

Suppose an ADC provides a 16-bit sensor value.

You want to access:

  • the full 16-bit value
  • individual bytes separately

One solution is a union.

union ADCData
{
    uint16_t value;

    struct
    {
        uint8_t lowByte;
        uint8_t highByte;
    };
};

Usage:

union ADCData adc;

adc.value = 0x1234;

Now:

adc.lowByte

contains:

0x34

and:

adc.highByte

contains:

0x12

This technique is extremely common in:

  • communication protocols
  • sensor interfaces
  • bootloaders
  • device drivers
  • register manipulation

When to Use a Structure

Use a structure when:

  • all members are needed simultaneously
  • you are representing an object
  • memory is not extremely constrained
  • readability is important

Examples:

  • sensor information
  • employee database
  • GPS coordinates
  • configuration settings

Structures are the default choice most of the time.

When to Use a Union

Use a union when:

  • only one member is active at a time
  • memory conservation matters
  • interpreting raw bytes differently
  • working with hardware registers
  • parsing communication packets

Common embedded applications include:

  • CAN packets
  • UART frames
  • ADC data
  • protocol parsers
  • register-level programming

Common Beginner Mistakes

One mistake appears frequently.

union Data
{
    int num;
    float value;
};

Data.num = 100;
Data.value = 25.5;

Then the programmer expects:

Data.num

to still contain 100.

It won’t.

The float write overwrote the same memory.

Remember:

A union stores multiple interpretations of the same memory, not multiple independent values.

Another common mistake is using unions when a structure would be simpler.

If all values need to exist together, use a structure.

Don’t use a union just because it saves memory.

Why Embedded Engineers Love Structs and Unions Together

Interestingly, embedded projects often combine both.

Example:

typedef union
{
    uint32_t reg;

    struct
    {
        uint32_t enable : 1;
        uint32_t mode   : 2;
        uint32_t error  : 1;
        uint32_t unused : 28;
    };

} ControlRegister;

This gives two views of the same memory:

control.reg

Access the complete register.

Or:

control.enable
control.mode

Access individual bits.

This pattern appears everywhere in low-level embedded development.

Final Thoughts

Structures and unions may look similar, but they solve very different problems.

A structure gives every member its own memory location.

A union makes all members share the same memory.

If you need multiple pieces of information available at the same time, use a structure.

If you need different ways to interpret the same memory while conserving RAM, use a union.

Most beginners encounter unions much later than structures because their usefulness becomes clearer when dealing with hardware, communication protocols, and memory optimization.

And once you start building embedded systems, you’ll discover that unions are one of those features that initially seem strange but become surprisingly useful in real projects.

Leave a Reply

Your email address will not be published. Required fields are marked *