Structure in C Programming Language with practical examples

It is often convenient to organize related pieces of information together while working with real life entities. In C programming language, structure provides a way to do that by grouping several related variables into one place as structs. Structure may contain different data types such as char, integer, float and group them together to create a user-defined data type.

Declaring Structure in C

To declare a structure, we use the keyword struct followed by an identifier as the structure name. Inside the curly braces we list the member variables with their respective data types.
Here, we are creating a structure for devices that contains information about the device’s name, price, and quantity.

// declaration of structure Device
struct Device
{
    char name[20]; // device name
    float price; // device price
    int quantity; // device quantity
};

Notice we put a semicolon after the curly braces unlike the function declaration we have seen previously.

Declaring Structure Variable

A structure is a kind of blueprint or template in which we get to decide what types of data we want to keep. To use it, we need to create an instance (variable) of it.
Let’s create two structure variables of Device type. We can do that in the following ways,

Variable Declaration with Structure Template

We can create instances of the structure with the template in the following way.

// declaration of structure  Device 
struct Device
{
    char name[20]; // device name
    float price; // device price
    int quantity; // device quantity
} laptop, phone; // declaring variables

Variable Declaration after Structure Template

We can also create instances of the structure after the template in the following way

struct Device laptop, phone; // structure variables

Notice that we use the keyword struct followed by the name of the structure we want to create an instance of, and then the variable names.
Structure also allows to create array of structure like other data types with the similar syntax.

Initializing Structure Variable

Since a structure is just a blueprint not an actual data placeholder, it doesn’t occupy any memory space when declared until an instance is created. Also, structures do not support constructors or functions inside their body. Therefore, we can not initialize member variables within the curly braces. However, we can initialize or assign values to member variables in the following ways:

Initializing by Accessing Member Variables

To assign or access the value of the member variables of an instance we can access them using dot (.) operator then assign value using assignment operator (=)

int main()
{
    struct Device laptop; // structure variables
    laptop.price = 100000.0; // assigning  price
    laptop.quantity = 3; // assigning quantity
    strcpy(laptop.name, "msi"); // assigning name

    printf("Device name : %s\n", laptop.name);
    printf("Device price : %f\n", laptop.price);
    printf("Device quantity : %d\n", laptop.quantity);
    return 0;
}

Notice that we assigned name variable differently from others because, C string is an array of characters which does not support using assignment operator directly. That’s why we used the function strcpy() from string.h header file to achieve the same goal.

Initializing through Initializer List

We could achieve the same result when declaring an instance of the structure through an initializer list in the following way,

int main()
{
    struct Device laptop = {"msi", 100000.0, 3}; // structure variables with initializer list

    printf("Device name : %s\n", laptop.name);
    printf("Device price : %f\n", laptop.price);
    printf("Device quantity : %d\n", laptop.quantity);
    return 0;
}

Nested Structures

When a structure is used as a member variable of another structure or declared inside another structure, it is referred to as the nesting of structures. Nesting of a structure can be done in the following two ways,

Structure as a Member Variable

We can use a structure as a member variable of another structure as well. We have to declare the structure of the member variable before the structure in which we are nesting our structure.

// declaration of structure  Model
struct Model
{
    char deviceName[20]; //  device name
    char deviceModel[20]; // device model
};
// declaration of structure   Device
struct Device
{
    struct Model device; // device model structure 
    float price; // device price
    int quantity; // device quantity
};

We have nested our structure Model as a member variable inside the structure Device. We can access and initialize the members of the both structures Device and Model in the same way we have seen before.

int main()
{
    struct Device laptop;
    laptop.price = 100000.00;
    laptop.quantity = 3;
    strcpy(laptop.device.deviceName, "msi");
    strcpy(laptop.device.deviceModel, "modern 15");

    printf("Device name : %s\n", laptop.device.deviceName);
    printf("Device model : %s\n", laptop.device.deviceModel);
    printf("Device price : %f\n", laptop.price);
    printf("Device quantity : %d\n", laptop.quantity);
    return 0;
}

Declaring Inside Another Structure

We can also declare a structure inside the body of another structure.

// declaration of Device structure 
struct Device
{
    // declaration of Model structure 
    struct Model
    {
        char deviceName[20]; // device name
        char deviceModel[20]; // device model
    } device; // device model structure  
     
    float price; // device price
    int quantity; // device quantity
};

We can access and assign member variables in the same way we have seen before.

Structure Pointers

Similar to other data types, we can use a pointer to refer to the memory address of a structure. To access the member variables, the arrow operator (->) is used with the structure pointer.

int main()
{
    struct Device device = {"msi", 100000, 3}; // structure variable
    struct Device* ptr = &device; // structure pointer
    
    printf("Device name : %s\n", ptr->name);    
    printf("Device price : %f\n", ptr->price);    
    printf("Device quantity : %d\n", ptr->quantity);    
    return 0;
}

We can also use pointers as member variables. Sometimes, it is useful to have a pointer member that points to another instance of the same structure, creating a self-referential structure.

Consider a scenario where we want to manage desktop information along with the GPU details used in that desktop. We can define a Device structure with an additional pointer member that points to another instance of the same Device structure. In this example, both the desktop and GPU are instances of the Device structure, and a desktop Device structure can point to another Device structure, representing the associated GPU, through a self-referential pointer.

#include<stdio.h>
#include<string.h>

// declaration of structure Device
struct Device
{
    char name[20]; // device name
    float price; // device price
    int quantity; // device quantity
    struct Device* ptr; // self-referential member
};

int main()
{
    struct Device gpu = {"AMD Radeon", 20000, 1, NULL}; // structure variable
    struct Device desktop = {"msi", 100000, 1, &gpu}; // structure variable

    printf("Device name : %s\n", desktop.name);    
    printf("Device price : %f\n", desktop.price);    
    printf("Device quantity : %d\n", desktop.quantity);

    printf("Device gpu name : %s\n", desktop.ptr->name);    
    printf("Device gpu price : %f\n", desktop.ptr->price);    
    printf("Device gpu quantity : %d\n", desktop.ptr->quantity);    
    return 0;
}
Output:
Device name : msi
Device price : 100000
Device quantity : 1
Device gpu name : AMD Radeon
Device gpu price : 20000
Device gpu quantity : 1

Passing Structure to a Function

we can pass a structure to a function by the structure itself (pass by value) or a reference to the structure (pass by reference). When we pass by the reference we can modify the actual instance members from inside the function.

void fnc(struct Device parameter)
{
   // price does not change
   parameter.price = -1;
}

void fnc(struct Device* parameter)
{
   // price changes
   parameter->price = -1;
}

In the C programming language, directly returning multiple values from a function is not allowed. One workaround is to return a structure from a function.

struct Device fnc()
{
   struct Device laptop = {"msi", 100000, 1}; ;

   // do somthing here

   return laptop;
}

Run C Programming Online Compiler

To make your learning more effective, exercise the coding examples in the text editor below.

Run C programming online

Previous
Recursion in C Programming Language with Practical Examples
Next
File Handling in C Programming Language with Practical Examples