Grouping related data with structs, sharing memory with unions
Grade XII • Computer Science ⏱️ ~20 minBrief Intro — Structures & Unions
In C, structures allow you to group different types of data — like a person's name, age, and salary — under a single name, making it easier to manage complex records. Unions take this further by letting different data types share the exact same memory space.
In this activity, you'll learn how to define and use structs and unions to organize your program's data efficiently and manage computer memory effectively.
Structures are the building blocks of complex data management in C, allowing you to create your own custom data types.
Task 1: Why Structs?
In C, a struct (structure) is a collection of variables (can be of different types) under a single name. To store information about one person you can use separate variables name, citNo and salary — but for many people you would need name1, citNo1, salary1, name2, citNo2, salary2, ... A better approach is a single struct Person used for every person.
Structures group related data of possibly different types under one name, avoiding separate variables per record.
Task 2: Defining a Struct
To define a structure, the struct keyword is used:
struct structureName {
dataType member1;
dataType member2;
...
};
Example:
struct Person {
char name[50];
int citNo;
float salary;
};
struct defines a derived type; here struct Person has name, citNo, and salary members.
Task 3: Creating Struct Variables
When a struct type is declared, no storage or memory is allocated. To allocate memory and work with it, we need to create variables. Two equivalent ways:
int main() {
struct Person person1, person2, p[20];
return 0;
}
or, naming variables right after the closing brace:
struct Person { ... } person1, person2, p[20];
Both create two variables and an array of 20 elements.
The type declaration allocates nothing; variables allocate the memory.
Task 4: Accessing Members
Two operators access structure members:
person2.salary.. for normal variables, -> for pointers.
The notes' feet + inches example, live. Enter two distances and press Add.
Task 5: The Distance Program Trace
The notes' program reads two distances (feet + inches), adds the feet and inches, then converts excess inches with:
while (sum.inch >= 12) {
++sum.feet;
sum.inch = sum.inch - 12;
}
Output: Sum of distances = 15'-5.7". Try the Distance Adder above with 12ft 7.9in and 2ft 9.8in.
12 + 2 = 14 ft; 7.9 + 9.8 = 17.7 in; the loop converts 17.7 in into 1 ft + 5.7 in → 15ft 5.7in.
Using typedef simplifies your code with aliases, while nested structures allow you to build even more complex data models.
Task 6: The typedef Keyword
typedef creates an alias name for data types. It is commonly used with structures to simplify declaring variables. struct Distance { ... } with struct Distance d1, d2; is equivalent to typedef struct Distance { ... } distances; with distances d1, d2;.
distances is an alias for struct Distance.
Task 7: Nested Structures
You can create structures within a structure:
struct complex {
int imag;
float real;
};
struct number {
struct complex comp;
int integers;
} num1, num2;
struct number contains a struct complex member called comp.
Task 8: Nested Member Access
To set the imag of num2 to 11, chain the dots:
num2.comp.imag = 11;
Each dot moves one level deeper into the nested structure.
num2.comp.imag reaches the inner imag member of the nested comp structure.
Unions provide a way to save memory by allowing different variables to use the same space, though only one can be used at a time.
Task 9: Defining a Union
A union is a user-defined type similar to structs except for one key difference: structures allocate space to store all their members, whereas unions allocate space to store only the largest member. The union keyword defines one:
union car {
char name[50];
int price;
};
Union variables are created the same ways as struct variables (union car car1, car2, *car3;).
union car defines the derived type; variables allocate memory.
Task 10: Accessing Union Members
Use the dot (.) operator to access union members through a variable, and the -> operator through a pointer. For example: car1.price; through the pointer car3 either (*car3).price or car3->price.
car1.price and car3->price both reach the price member.
The same three members — name[32], salary (4), workerNo (4) — as a struct vs a union.
Task 11: Struct vs Union Memory
With name[32] (32 bytes), salary (4 bytes), workerNo (4 bytes): the struct sJob is 40 bytes (all members side by side), but the union uJob is 32 bytes — the size of a union variable is always the size of its largest element. Output: Size of union = 32, Size of structure = 40.
Struct: 32 + 4 + 4 = 40. Union: max(32, 4, 4) = 32.
Task 12: Sharing Memory
With a union, all members share the same memory. After j.salary = 12.3; then j.workerNo = 100;, salary no longer holds 12.3 — the program prints Salary = 0.0 and Number of workers = 100. Use the layout buttons above to watch the overwrite.
Writing workerNo overwrites the shared memory, so salary reads 0.0.
Ready to test your knowledge?
Take the Assessment →