Introduction to Structures and Unions
In this lesson, we will introduce the basic concepts of structures and unions, explain their differences, and show their practical use in C++ and other programming languages. We will also see how structures are applied in algorithms and data structures to achieve more organized and efficient programming.
In programming, there is often a need to treat several different pieces of data as a single logical entity. For example, a student's data can be seen as a collection — name, surname, student ID number, and GPA. Instead of storing each of these values in separate variables, we can group them together into one structure.
What Are Structures?
A structure (struct) is a composite data type that allows grouping of variables of different data types under a single name.
Each element inside a structure is called a member or field.
Structures make it easier to organize complex data and provide a convenient way to represent real-world entities in programs.
// Example of a structure in C++
#include <iostream>
using namespace std;
struct Student {
string firstName;
string lastName;
int studentID;
double gpa;
};
int main() {
Student s1;
s1.firstName = "Mark";
s1.lastName = "Peterson";
s1.studentID = 123;
s1.gpa = 9.4;
cout << "Student: " << s1.firstName << " " << s1.lastName << endl;
cout << "Student ID: " << s1.studentID << endl;
cout << "GPA: " << s1.gpa << endl;
return 0;
}
Structure in Memory (C++)
Figure 1 illustrates the Student structure in the C++ programming language.
Two instances of this structure — s1 and s2 — are shown.
The purpose of the illustration is to clearly demonstrate that each structure instance has its own, separate memory space.
Structure Definition
struct Student {
int id;
float gpa;
};
Explanation of members:
id— an integer identifier of the student (inttype), typically occupies 4 bytes.gpa— grade point average (floattype), typically occupies 4 bytes.
What the Figure Shows
The diagram displays two separate memory blocks: one for s1 and one for s2.
Each block contains the fields id and gpa in the same order.
This means:
- The values
s1.idands1.gpado not affects2— they are physically stored at different memory addresses. - The size of one structure instance equals the sum (with possible alignment) of its member sizes — in this example, about 8 bytes.
- The order of members usually determines how the data is laid out in memory (the compiler may insert padding for alignment).
Example of Initialization (C++)
Student s1 = {101, 9.5f};
Student s2 = {102, 8.7f};
After this initialization, memory contains:
s1.id= 101 ands1.gpa= 9.5 in thes1block;s2.id= 102 ands2.gpa= 8.7 in thes2block;- Both instances have the same byte layout but occupy different memory locations.
Important Notes
- This example helps illustrate why modifying a field in
s1does not affects2. - If you need to save memory and know that both values won’t be used simultaneously, use a
union— but remember that its members share the same memory space. - On some architectures, padding may be added between members for alignment; this means the actual size of a structure may be larger than the simple sum of its members’ sizes.
What Are Unions?
A union (union) is similar to a structure, but its members overlap in memory.
This means that all members of a union share the same memory space, so at any given moment the union can hold only one active value.
Unions are used when memory saving is important, or when the same memory area needs to be interpreted in different ways.
// Example of a union in C++
#include <iostream>
using namespace std;
union Number {
int integerValue;
float realValue;
};
int main() {
Number n;
n.integerValue = 10;
cout << "Integer value: " << n.integerValue << endl;
n.realValue = 3.14;
cout << "Real value: " << n.realValue << endl;
// Note: the value of 'n.integerValue' is no longer valid
return 0;
}
Differences Between Structures and Unions
- A structure stores all members simultaneously, while a union uses shared memory space for all members.
- A structure requires more memory (sum of all member sizes), while a union takes up memory equal to the size of its largest member.
- Structures are used to model complex entities, while unions are used for optimization and special data interpretation cases.
Use in Algorithms
In the field of algorithms and data structures, structures are used to define complex types such as tree nodes, list elements, or table records. Unions are less common but can be useful in systems programming and when dealing with binary data formats.
Further Topics
- Structures with pointers (for creating linked lists)
- Nested structures and arrays of structures
- Passing structures as function parameters
- Combining structures and unions
Structures in Different Programming Languages
The concept of a struct (structure) exists in many programming languages because it allows multiple related pieces of data
to be grouped into a single logical unit.
Structures are especially characteristic of languages such as C and C++, but they are also used in modern languages like
C#, Go, and Rust, where they serve to model more complex data types.
In the C programming language, structures are used purely for data storage, while in C++ they can also include methods, constructors, and destructors, making them similar to classes. The following example demonstrates the definition and usage of a simple structure in C.
// Example: Structure in C
#include <stdio.h>
// Structure definition
struct Student {
char name[50];
int year;
float average;
};
int main() {
// Declare a variable of type struct
struct Student s1;
// Assign values to structure fields
printf("Enter student's name: ");
scanf("%s", s1.name);
printf("Enter year of study: ");
scanf("%d", &s1.year);
printf("Enter student's GPA: ");
scanf("%f", &s1.average);
// Print the entered data
printf("\nStudent: %s\nYear: %d\nGPA: %.2f\n", s1.name, s1.year, s1.average);
return 0;
}
In this example, the Student structure groups three different pieces of data — a text field, an integer, and a floating-point value.
This approach allows data that logically belongs together to be organized as a single entity, without the need for multiple separate variables.
Illustration Explanation: Union (Example — Sensor Data)
The image illustrates a union (C++ union) that models the data of a single sensor — specifically,
its members are temperature, humidity, and status.
The goal of the illustration is to show the key concept: all union members share the same memory space.
What does “share the same memory space” mean?
- All members (e.g.,
float temperature,float humidity,char status[10]) occupy the same addresses in RAM — they physically overlap. - When you write a value to one member, it overwrites the bytes that previously belonged to another member.
- Therefore, at any given time, only one member holds a meaningful (valid) value — the one that was written last.
How is this used in practice?
Unions are useful when you know that at a given time you only need to store one of several possible data representations. Typical use cases include:
- A device that sometimes returns temperature, sometimes humidity, and sometimes a textual status;
- Reinterpreting the same bytes as different data types (for example, for bitwise operations or type conversion);
- In microcontrollers — viewing registers as a single byte or as individual bits.
Short Code Example (C++)
union SensorData {
float temperature; // e.g. 4 bytes
float humidity; // e.g. 4 bytes (same memory as temperature)
char status[10]; // e.g. 10 bytes -> union will take at least 10 bytes
};
SensorData d;
d.temperature = 23.5f; // now the temperature is valid
// d.humidity and d.status are invalid until written
d.humidity = 55.2f; // overwrites the same memory area
Important Notes and Explanations
- The size of a union equals the size of its largest member — in this case, the 10-byte character array.
- The last written value determines what is “valid” inside the union — reading another member without writing to it first may produce unpredictable results.
- To store multiple values at once (e.g.,
idandaveragefor a student), you should use astruct, not aunion. - Unions are ideal for saving memory when it’s critical to minimize RAM usage and when only one data interpretation is active at a time.
- By combining a structure with a union, you can have both permanent (independent) fields and one “variable” section, for example:
struct Measurement {
int sensorId;
union {
float temp;
float hum;
char status[10];
} data;
};
Summary
The illustration clearly demonstrates the core idea: a union does not store all its members simultaneously — it provides only one active interpretation of the same memory block. When used correctly, this feature is powerful: it saves space and simplifies handling different data formats, but it requires care when reading and writing values.
Structures in C++ — Advanced Features and Comparison with Classes
In the C++ programming language, structures (struct) are extended compared to those in C.
They are no longer just simple collections of data — a structure in C++ can also include functions (methods),
as well as constructors, destructors, static members, and even private and public sections.
The main difference between a structure and a class in C++ is minimal:
in a structure, members are public by default, while in a class, they are private.
// Example: Structure in C++
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int year;
double average;
// Constructor
Student(string n, int y, double a) {
name = n;
year = y;
average = a;
}
// Method for displaying information
void show() {
cout << "Student: " << name << endl;
cout << "Year: " << year << endl;
cout << "Average: " << average << endl;
}
};
int main() {
// Creating an object using the constructor
Student s1("Ana", 2, 9.3);
// Calling the method
s1.show();
return 0;
}
As seen in the example, the Student structure now includes a constructor and a show() method.
This demonstrates that structures in C++ behave almost identically to classes.
In modern C++ programming, structures are typically used for simple data types (data structures),
while classes are preferred for more complex objects and program logic.
This approach makes C++ extremely flexible — it allows the same object-oriented programming principles to be applied even to simple data representations.
Unions (union) — Shared Memory for Different Data Types
In C and C++, a union is a special kind of structure that allows multiple variables to share the same memory location. In other words, all members of a union use the same block of memory, but only one of them can hold a valid value at a time.
Unions are typically used when memory needs to be conserved or when a variable can represent different data types depending on the context.
// Example: Using a union
#include <iostream>
#include <cstring>
using namespace std;
union Data {
int integerValue;
float floatValue;
char text[20];
};
int main() {
Data d;
d.integerValue = 42;
cout << "Integer: " << d.integerValue << endl;
d.floatValue = 3.14;
cout << "Float: " << d.floatValue << endl;
strcpy(d.text, "Union test");
cout << "Text: " << d.text << endl;
return 0;
}
In this example, all members (integerValue, floatValue, and text)
occupy the same memory location.
Each new assignment overwrites the previous value,
so at any given time only the last assigned member contains valid data.
Differences Between a Structure and a Union
- In a structure, each member has its own memory — all members can exist simultaneously.
- In a union, all members share the same memory — only one member is active at a time.
- The size of a union is equal to the size of its largest member.
Practical Uses of Unions
Unions are particularly useful in:
- Device drivers — when the same data may need to be interpreted in different ways.
- Binary data processing — for example, interpreting the same bytes as numbers, text, or structures.
- Low-level programming — when managing memory or communicating with hardware.
Conclusion
Unions are powerful but potentially risky constructs. Because their members share memory, careless use can lead to data loss or undefined behavior. However, when memory efficiency is critical, unions are extremely useful and often combined with structures for more flexible data representations.
Combining Structures and Unions — A Practical Example
In practice, structures and unions are often combined to achieve flexible and memory-efficient data organization. A union can be a member of a structure, allowing certain parts of the structure to share memory, while others remain independent.
// Example: Structure with a union
#include <iostream>
#include <cstring>
using namespace std;
struct Employee {
char name[30];
int payType; // 0 = fixed, 1 = hourly
union Salary {
int fixed;
float hourly;
} salary;
};
int main() {
Employee e;
strcpy(e.name, "Marko");
e.payType = 0; // Fixed salary
e.salary.fixed = 3000;
cout << "Name: " << e.name << endl;
if (e.payType == 0)
cout << "Fixed salary: " << e.salary.fixed << endl;
else
cout << "Hourly rate: " << e.salary.hourly << endl;
e.payType = 1; // Switch to hourly pay
e.salary.hourly = 15.5;
if (e.payType == 0)
cout << "Fixed salary: " << e.salary.fixed << endl;
else
cout << "Hourly rate: " << e.salary.hourly << endl;
return 0;
}
Memory Layout Analysis
- The members of the
Salaryunion share the same memory space — the union’s size equals the size of its largest member (eitherfloatorint). - The other structure members (
nameandpayType) occupy their own independent memory locations. - This approach saves memory and provides a flexible way to represent different salary types within a single structure.
Advantages of Combining Structures and Unions
- Efficient memory usage when certain data fields are not active at the same time.
- Clear and logical data organization within a single structure.
- Improved readability and modularity, making the code easier to maintain.
Conclusion
Combining structures and unions is a powerful technique in C and C++ for handling complex data. By using these constructs together, a programmer can achieve both flexibility and memory efficiency — especially valuable in systems programming and competitive programming.
Unions in C and C++
A union is a special data structure that allows multiple data types to share the same memory location. For beginners, it can be confusing to understand when and why unions should be used — that’s why it’s important to explore their practical applications.
Warning: Be careful when working with unions, as accessing multiple members at the same time can lead to unpredictable results. Use them only when you know that at any given moment, only one member will be active.
Example: Using a union in C/C++
// Definition of a union
union Data {
int integer_value;
float real_value;
char character;
};
#include <iostream>
using namespace std;
int main() {
Data d;
d.integer_value = 42;
cout << "Integer: " << d.integer_value << endl;
// Now we assign a float value, which overwrites the same memory
d.real_value = 3.14;
cout << "Float: " << d.real_value << endl;
// Accessing the previous member is now unreliable
cout << "Integer after assigning float: " << d.integer_value << endl;
return 0;
}
When to use unions:
- When memory savings are important and only one data type is used at a time.
- Inside structures that combine multiple data types, but never activate more than one member simultaneously.
When not to use unions:
- When you need to store multiple values of different types at the same time.
- When there’s a risk of unintentionally accessing the wrong member, which may cause errors or unpredictable program behavior.
Composition of Structures and Unions
In practice, structures that contain unions are often used when a certain group of related data needs to share memory while still remaining logically connected. This allows for more efficient memory usage and better data organization.
Example in C/C++
// Structure that contains a union
#include <iostream>
using namespace std;
struct Measurement {
int type; // 0 = integer, 1 = float, 2 = character
union {
int int_value;
float float_value;
char character;
} value;
};
int main() {
Measurement m;
// Integer measurement
m.type = 0;
m.value.int_value = 100;
cout << "Type: " << m.type << ", Integer: " << m.value.int_value << endl;
// Floating-point measurement
m.type = 1;
m.value.float_value = 3.14;
cout << "Type: " << m.type << ", Float: " << m.value.float_value << endl;
// Character measurement
m.type = 2;
m.value.character = 'A';
cout << "Type: " << m.type << ", Character: " << m.value.character << endl;
return 0;
}
Explanation:
- The
Measurementstructure includes information about which type of data is currently being used. - The
valueunion ensures that only one data type occupies the shared memory space at any given time. - This combination is useful when you want to logically group data while saving memory.
Usage tips:
- Always check the
typefield before accessing the union to avoid unexpected results. - This approach is common in system programming, protocol encoding, and applications where memory usage is critical.
Memory Layout Diagram
Below is a visual representation of how the Measurement structure uses the value union.
Each line represents a memory location:
+-----------------+ | type (int) | // stores the data type: 0=int, 1=float, 2=char +-----------------+ | value | // union: shares the same memory for all types | +-----------+ | | | int_value | // if type = 0 | +-----------+ | | | float_value | // if type = 1 | +-----------+ | | | character | // if type = 2 | +-----------+ | +-----------------+
Note: The union shares the same memory space among all its members, so only one data type can be used at a time.
This saves memory but requires that the type field is always checked before accessing the data.
This diagram helps students visualize how data is stored in memory and understand why combining structures and unions can be useful in practical applications such as systems programming and protocol handling.
Dedicated Section: Unions
Unions are an advanced topic, and it can be challenging for students to understand when and how to use them. In essence, a union allows different data types to share the same memory location, but only one type can be active at any given moment.
Warnings and Recommendations
- Always check the control field (e.g.,
type) before accessing union members to avoid unpredictable results. - Do not use unions when multiple types of data need to be stored simultaneously — in such cases, a structure is a better choice.
- Unions are useful when memory efficiency is critical or when working with low-level data (e.g., protocol encoding, systems programming).
Practical Use Cases for Unions
- A measurement system where each value can be an
int,float, orchar, but never more than one type at the same time. - Protocol packet decoding where different field types share the same memory depending on the message type.
- Competitive programming problems that require efficient memory use when simulating different data types.
Conclusion: Unions are best used when you want to logically group data while saving memory, but proper type control is essential. Combining structures and unions often provides an optimal balance between flexibility and efficiency.
Using Structures and Unions in C#
In C#, the struct keyword is used to create value types that group multiple fields together.
Although C# does not support unions directly like C/C++, you can achieve similar behavior by using the attributes [StructLayout(LayoutKind.Explicit)] and [FieldOffset].
Example of a Structure in C#
// Structure in C# containing different data types
using System;
struct Measurement {
public int Type; // 0 = int, 1 = float, 2 = char
public int IntegerValue;
public float FloatValue;
public char CharacterValue;
}
class Program {
static void Main() {
Measurement m;
// Integer measurement
m.Type = 0;
m.IntegerValue = 100;
Console.WriteLine($"Type: {m.Type}, Integer: {m.IntegerValue}");
// Floating-point measurement
m.Type = 1;
m.FloatValue = 3.14f;
Console.WriteLine($"Type: {m.Type}, Float: {m.FloatValue}");
// Character measurement
m.Type = 2;
m.CharacterValue = 'A';
Console.WriteLine($"Type: {m.Type}, Character: {m.CharacterValue}");
}
}
Simulating Unions in C#
// Using Explicit Layout to simulate a union
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct MeasurementUnion {
[FieldOffset(0)] public int IntegerValue;
[FieldOffset(0)] public float FloatValue;
[FieldOffset(0)] public char CharacterValue;
[FieldOffset(4)] public int Type; // control field
}
class Program {
static void Main() {
MeasurementUnion m;
m.Type = 0;
m.IntegerValue = 42;
Console.WriteLine($"Type: {m.Type}, Integer: {m.IntegerValue}");
m.Type = 1;
m.FloatValue = 3.14f;
Console.WriteLine($"Type: {m.Type}, Float: {m.FloatValue}");
m.Type = 2;
m.CharacterValue = 'Z';
Console.WriteLine($"Type: {m.Type}, Character: {m.CharacterValue}");
}
}
Note:
- In C#, it’s important to use a control field like Type to track which member currently holds valid data.
- This technique can be useful when optimizing memory usage, especially in low-level or performance-critical applications.
Practical Exercises with Structures and Unions
This section contains a collection of example exercises that help you learn and practice working with structures and unions in C/C++ and C#.
Exercises
- Define a structure for a car:
Create a structure that stores information about a car: make, model, year of production, and price.
Goal: Practice creating structures that contain different data types.
- Define a union for multiple data types:
Create a union that can hold an
int,float, orchar, along with a structure that tracks which data type is currently active.Goal: Understand how unions work and how control fields can be used to manage the active data type.
- Structure containing an internal union:
Create a structure that stores an employee’s name and a union for holding additional data (number of working hours, performance percentage, or initial character).
Goal: Practice combining structures and unions for efficient memory organization.
- C# structure and union simulation:
Define a C#
structwith multiple fields and simulate a union using[StructLayout(LayoutKind.Explicit)]and[FieldOffset].Goal: Learn how C# allows memory layout control and how unions can be simulated effectively.
Note: These exercises are an excellent preparation for practical applications in algorithms and systems programming. Once completed, you’ll be able to visualize how data is stored in memory and how different data types affect the size and layout of structures.
Solutions to Practical Exercises with Structures and Unions
1. Structure for a Car (C/C++)
// Defining a structure for a car
#include <iostream>
#include <string>
using namespace std;
struct Car {
string make;
string model;
int year;
double price;
};
int main() {
Car c;
// Assigning values
c.make = "Toyota";
c.model = "Corolla";
c.year = 2020;
c.price = 15000.50;
// Displaying values
cout << "Make: " << c.make << ", Model: " << c.model
<< ", Year: " << c.year << ", Price: " << c.price << endl;
return 0;
}
2. Union for Multiple Data Types (C/C++)
// Defining a union and a structure that tracks the active type
#include <iostream>
using namespace std;
struct Value {
int type; // 0=int, 1=float, 2=char
union {
int intValue;
float floatValue;
char charValue;
} data;
};
int main() {
Value v;
v.type = 0;
v.data.intValue = 42;
cout << "Type: " << v.type << ", Int: " << v.data.intValue << endl;
v.type = 1;
v.data.floatValue = 3.14;
cout << "Type: " << v.type << ", Float: " << v.data.floatValue << endl;
v.type = 2;
v.data.charValue = 'A';
cout << "Type: " << v.type << ", Char: " << v.data.charValue << endl;
return 0;
}
3. Structure Containing an Internal Union (C/C++)
// Structured record with an internal union
#include <iostream>
#include <string>
using namespace std;
struct Employee {
string name;
int type; // 0=int hours, 1=float percentage, 2=char initial
union {
int hours;
float percentage;
char initial;
} extra;
};
int main() {
Employee e;
e.name = "Marko";
// Example with hours
e.type = 0;
e.extra.hours = 40;
cout << e.name << ", Type: " << e.type << ", Hours: " << e.extra.hours << endl;
// Example with percentage
e.type = 1;
e.extra.percentage = 95.5;
cout << e.name << ", Type: " << e.type << ", Percentage: " << e.extra.percentage << endl;
return 0;
}
4. C# Structure and Union Simulation
// Structure and union simulation in C#
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct Value {
[FieldOffset(0)] public int intValue;
[FieldOffset(0)] public float floatValue;
[FieldOffset(0)] public char charValue;
}
struct Measurement {
public int type; // 0=int, 1=float, 2=char
public Value data;
}
class Program {
static void Main() {
Measurement m;
m.type = 0;
m.data.intValue = 100;
Console.WriteLine($"Type: {m.type}, Int: {m.data.intValue}");
m.type = 1;
m.data.floatValue = 3.14f;
Console.WriteLine($"Type: {m.type}, Float: {m.data.floatValue}");
m.type = 2;
m.data.charValue = 'A';
Console.WriteLine($"Type: {m.type}, Char: {m.data.charValue}");
}
}
Comment:
These examples demonstrate how structures and unions are used in different languages.
In C/C++, a union directly shares memory between its members, while in C#, we simulate the same behavior using StructLayout(LayoutKind.Explicit).
Practicing these examples helps students better understand memory organization and the practical use of combining structures and unions.
Exercises and Practice Tasks
These exercises are designed to help students apply their knowledge of structures and unions in practice. Each task includes a short description and a clear implementation goal.
1. Define a Structure for a Car
- Create a structure
Carthat contains the following fields:make,model,year, andprice. - Write a program that inputs data for 3 cars and prints them on the screen.
- Optional: sort the cars by year or price.
2. Define a Union for Multiple Data Types
- Create a union that can store an
int,float, orchar. - Combine it with a structure that keeps track of the currently active data type.
- Write a program that demonstrates the usage of all data types within the union.
3. Structure Containing an Internal Union
- Create a structure
Employeethat contains a name and a union with the following members:hours,percentage, andinitial. - The program should input and display values of different types.
- Students should always check the type before accessing the union to avoid errors.
4. C# Exercise – Simulating a Union
- Create a structure
Measurementthat contains atypefield and a simulated unionValueusingStructLayout(LayoutKind.Explicit). - The program should demonstrate storing and displaying
int,float, andcharvalues. - Goal: understand how memory is shared in a union and how type tracking works in C#.
Tips for Students
- Always check the
typebefore accessing union members to avoid unexpected results. - Think about memory efficiency and when it makes sense to use unions.
- Try combining multiple structures and unions to gain hands-on experience.
|
Previous
|< Fast Exponentiation Algorithm Explained |
Next
Basic data structures >| |

