• C Programming Video Tutorials

C - Nested Structures



In the programming context, the term “nesting” refers to enclosing a particular programming element inside the similar element. For example, nested loops and nested conditional statements, etc. In this chapter, we shall learn about nested structures. When one of the elements in the definition of a struct type is of another struct type, the we call it as nested structure in C.

Nested structures are defined when one of the elements of a struct type is itself a composite representation of one or more types.

A general syntax of nested structure is as follows −

struct struct1{
   type var1;
   type var2;
   struct struct2 strvar;
}

We can think of nested structures in the following situation.

If we want to define a struct type representing a student with name and age as its elements, and other element is the course that is characterized by the course ID, the title, and the credit points. Here, the student structure has an inner course structure.

struct student{
   char *name;
   int age;
   struct course c1;
};

The student variable will be stored in the memory as follows −

Name Age Course
kiran 25 001 C Programming 6

The nesting of structures can be performed by two methods −

  • Defining inline structure
  • Including the element of a structure already defined

Let us learn these methods by suitable examples.

Method 1

In this method, we shall define an employee data type, with one of its elements being date of birth. C doesn’t have a built−in date type. We shall declare the dob struct with three int types d, m and y inside the employee structure and its variable d1 is one of the elements of the outer type.

Example

#include <stdio.h>
#include <string.h>
struct employee{
   char name[10];
   float salary;
   struct dob{
      int d, m, y;
   } d1;
};
int main(){
   struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
   printf("Name: %s\n", e1.name);
   printf("Salary: %f\n", e1.salary);
   printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
   return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

You can see that the variable of employee type is initialized with its date element having another pair of curly brackets.

Method 2

The other approach for using nested structures is to define the inner struct type first, and then use its variable as one of the elements in the outer struct type, which is defined afterwards.

Here, the dob type is defined in the beginning, it has three int elements − d, m and y. The employee struct type is defined afterwards. Since dob is already defined, we can have an element of its type inside employee.

Example

#include <stdio.h>
#include <string.h>
struct dob{
   int d, m, y;
};
struct employee{
   char name[10];
   float salary;
   struct dob d1;
};
int main(){
   struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
   printf("Name: %s\n", e1.name);
   printf("Salary: %f\n", e1.salary);
   printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
   return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

Note that the inner struct type should be defined before the outer type. We can also declare a variable of dob type and then include it in the initialization of employee type variable, as shown below −

struct dob d1 = {12, 5, 1990};
struct employee e1 = {"Kiran", 25000, d1};

Example

In the following code, the nesting of structure goes upto two levels. In other words, the outer struct type employee has one element that is a variable of experience struct type. In turn, the experience structure has two elements of another struct type called date.

Hence, the memory allocation for employee variable can be understood with the following illustration −

Name Salary Designation from to
kiran 25000 Clerk 12 5 1990 31 3 2021

Here is the complete code −

Example

#include <stdio.h>
#include <string.h>
struct date{
   int d, m, y;
};
struct experience{
   char designation[10];
   struct date from;
   struct date to;
};
struct employee{
   char name[10];
   float salary;
   struct experience exp;
};
int main(){
   struct date d1 = {12, 5, 1990};
   struct date d2 = {31, 3, 2021};
   struct experience exp = {"Clerk", d1, d2};
   struct employee e1 = {"Kiran", 25000, exp};
   printf("Name: %s\n", e1.name);
   printf("Salary: %f\n", e1.salary);
   printf("Experience: Designation: %s\n", e1.exp.designation);
   printf("From :  %d-%d-%d\n", e1.exp.from.d,e1.exp.from.m, e1.exp.from.y );
   printf("To : %d-%d-%d\n", e1.exp.to.d, e1.exp.to.m, e1.exp.to.y );
   return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Experience: Designation: Clerk
From :  12-5-1990
To : 31-3-2021

Pointer to nested structure

We know that the address of a struct variable can be stored in a pointer variable. Further, C uses the indirection operator -> to access the elements of a variable that is referenced by the pointer. In case of the nested structure, the elements of the inner struct elements are accessed by ptr->inner_struct_var.element;

In the example below, we have declared a pointer ptr to an employee struct variable. the date, month and year elements of inner dob struct variable are accessed as ptr->d1.d, ptr->d1.m and ptr->d1.y expressions.

Example

#include <stdio.h>
#include <string.h>
struct employee{
   char name[10];
   float salary;
   struct dob{
      int d, m, y;
   } d1;
};
int main(){
   struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
   struct employee *ptr = &e1;
   printf("Name: %s\n", ptr->name);
   printf("Salary: %f\n", ptr->salary);
   printf("Date of Birth: %d-%d-%d\n", ptr->d1.d, ptr->d1.m, ptr->d1.y);
   return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990
Advertisements