Back to C Programming
2026-04-218 min read

Structure/Union

Learn Structure/Union step by step with clear examples and exercises.

Title: Structures and Unions in C Programming - A full guide

Why This Matters

In this tutorial, we will delve deep into the world of structures (struct) and unions in C programming. These data types are essential for managing complex data structures and optimizing memory usage in your programs. Understanding them can help you solve real-world problems, ace coding interviews, and avoid common bugs that trip up many programmers.

Prerequisites

Before we dive into the core concept of structs and unions, it is essential to have a solid grasp of the following topics:

  1. Basic C programming concepts such as variables, operators, control structures, functions, and arrays.
  2. Understanding pointers in C.
  3. Knowledge of data types and their usage.
  4. Familiarity with standard library functions like printf, scanf, etc.
  5. A good understanding of memory management concepts in C.

Core Concept

Structures (Struct)

A structure is a user-defined data type that allows you to combine different data types into a single entity. You can define your own structure by using the struct keyword, followed by a name for the new data type and enclosed in curly braces {}. Each element within the structure is called a member or field.

Here's an example of defining a simple structure to represent a point in a 2D plane:

struct Point {
int x;
int y;
};

In this example, we have created a new data type called Point, which consists of two members: x and y. To create an instance of the Point structure, you can use the following syntax:

struct Point p1; // Declaring a variable of type Point
p1.x = 3; // Assigning values to the members of the structure
p1.y = 4;

Initializing Structures

When initializing a structure, you can either assign values to each member explicitly or use an initializer list with comma-separated values for each member:

struct Point p2 = { .x = 5, .y = 6 }; // Using an initializer list

In the above example, we have initialized a new Point structure called p2 with the x-coordinate set to 5 and the y-coordinate set to 6.

Accessing Struct Members

You can access members of a structure using the dot notation (.) or pointer arithmetic (->). The dot notation is preferred for easier readability:

struct Point p3 = { .x = 7, .y = 8 };
printf("The x-coordinate of p3 is %d\n", p3.x); // Using dot notation
printf("The y-coordinate of p3 is %d\n", p3.y);

Array of Structures

You can create an array of structures by specifying the number of elements and their type:

struct Point points[10]; // Creating an array of 10 Point structures
points[0].x = 1; // Accessing the first element in the array
points[0].y = 2;

Passing Structures to Functions

To pass a structure to a function, you can either pass it by value or by reference. Passing by value creates a copy of the structure, while passing by reference allows the function to modify the original data:

void swap(struct Point *p1, struct Point *p2) {
struct Point temp = *p1;
*p1 = *p2;
*p2 = temp;
}

struct Point p4 = { .x = 9, .y = 10 };
struct Point p5 = { .x = 11, .y = 12 };
swap(&p4, &p5); // Swapping the values of p4 and p5 using a function

Unions

A union is another user-defined data type that allows you to store different data types in the same memory location, depending on the current state of the program. This can help optimize memory usage when dealing with data structures where some members are not always needed or when working with small data types like booleans.

To define a union, use the union keyword followed by a name for the new data type and enclosed in curly braces {}. You can then define the individual members within the union:

union Data {
int i;
float f;
char str[10];
};

In this example, we have defined a new data type called Data, which can store an integer, a floating-point number, or a character string. To access the members of a union, you use the same dot notation as with structures:

union Data myData; // Declaring a variable of type Data
myData.i = 10; // Assigning values to the members of the union

Initializing Unions

When initializing a union, you must provide an initial value for the first member:

union Data myData = { .i = 20 }; // Initializing a union with an integer value

In this example, we have initialized a new Data union called myData with an integer value of 20. You can then access the other members of the union as needed:

myData.f = 3.14; // Assigning a floating-point value to myData
printf("The float value is: %.2f\n", myData.f);

Accessing Union Members

You can access members of a union using the dot notation (.) or pointer arithmetic (->). However, since all union members share the same memory location, you must be careful not to read or write invalid data:

union Data myData2 = { .i = 40 };
printf("The integer value is: %d\n", myData2.i); // Reading the integer value from myData2
myData2.f = 5.1; // Writing a floating-point value to myData2, overwriting the integer value
printf("The float value is: %.2f\n", myData2.f);

Array of Unions

You can create an array of unions by specifying the number of elements and their type:

union Data dataArray[3]; // Creating an array of 3 Data unions
dataArray[0].i = 1; // Accessing the first element in the array
dataArray[0].f = 2.5; // Overwriting the integer value with a floating-point value

Worked Example

Let's create a simple program that defines a Person structure, initializes it with some data, and prints the person's details:

#include <stdio.h>

struct Person {
char first_name[20];
char last_name[20];
int age;
};

int main() {
struct Person john = {"John", "Doe", 30}; // Initializing a Person structure with John Doe, aged 30

printf("First name: %s\n", john.first_name);
printf("Last name: %s\n", john.last_name);
printf("Age: %d\n", john.age);

return 0;
}

In this example, we have defined a Person structure with three members: first_name, last_name, and age. We then create an instance of the Person structure called john and initialize it with John Doe's details. Finally, we print the person's first name, last name, and age using the dot notation.

Common Mistakes

  1. Forgetting to include the necessary header files (e.g., stdio.h) for standard input/output functions like printf.
  2. Using incorrect syntax when defining structures or unions, such as missing curly braces or forgetting to declare members with their data types.
  3. Failing to initialize all members of a structure or union, which can lead to undefined behavior or runtime errors.
  4. Trying to access members of an uninitialized structure or union, leading to segmentation faults or other runtime errors.
  5. Forgetting the dot notation when accessing members of structures and unions.
  6. Assuming that all members of a union are always accessible, which can lead to reading or writing invalid data if not careful.
  7. Not understanding the memory layout of unions, leading to unexpected behavior when accessing different members.
  8. Forgetting to use pointers when passing structures or unions to functions by reference.

Practice Questions

  1. Define a Rectangle structure with members for width (w) and height (h). Write a program that creates a Rectangle object, calculates its area, and prints the result.
  2. Modify the previous example to create a union called Value, which can store either an integer or a floating-point number. Write a program that initializes a Value union with both an integer and a float value and prints them.
  3. Define a Student structure with members for name (name), roll number (roll_no), and marks obtained in three subjects (sub1, sub2, sub3). Write a program that creates a Student object, calculates the total marks, and prints the result.
  4. Write a function called swapStruct that swaps the values of two Person structures using pointer arithmetic. Test your function by creating two Person objects and calling the swapStruct function to swap their details.
  5. Create an array of 10 Rectangle structures, initialize them with random widths and heights, calculate their areas, and print the results.
  6. Write a program that defines a union called Boolean which can store either a boolean value (true or false) or an integer value (0 or 1). Create a function called getBoolValue that takes a Boolean union as input and returns its boolean value if it is set, or -1 if it is an integer.

FAQ

What happens if I forget to initialize all members of a structure or union?

  • If you forget to initialize all members of a structure or union, some members may be left with indeterminate values (garbage values), which can lead to unexpected behavior and runtime errors.

Can I access the members of a structure or union using array indexing instead of dot notation?

  • No, you cannot access the members of a structure or union using array indexing. Instead, use the dot notation to access individual members by their names.

Is it possible to create an array of structures or unions in C?

  • Yes, it is possible to create arrays of both structures and unions in C. To do this, simply declare the array using the desired data type (e.g., struct Person[] or union Data[]) and initialize each element with a separate instance of the structure or union.

What is the difference between structures and records in C?

  • There is no difference between structures and records in C. The terms are used interchangeably to describe user-defined data types that combine multiple data elements into a single entity.

How can I ensure that my program uses the correct memory layout for unions?

  • To ensure your program uses the correct memory layout for unions, always initialize the union with the desired data type first and then access or modify other members accordingly. This will help avoid reading or writing invalid data due to memory alignment issues.

Can I use bit fields in my structures or unions?

  • Yes, you can use bit fields in your structures or unions by specifying their width in bits instead of bytes. Bit fields can help optimize memory usage when dealing with small data types like booleans or flags.