- C Programming Tutorial
- C - Home
- Basics of C
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Tokens
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Type Conversion
- C - Type Casting
- C - Booleans
- Constants and Literals in C
- C - Constants
- C - Literals
- C - Escape sequences
- C - Format Specifiers
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Unary Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Misc Operators
- Decision Making in C
- C - Decision Making
- C - if statement
- C - if...else statement
- C - nested if statements
- C - switch statement
- C - nested switch statements
- Loops in C
- C - Loops
- C - While loop
- C - For loop
- C - Do...while loop
- C - Nested loop
- C - Infinite loop
- C - Break Statement
- C - Continue Statement
- C - goto Statement
- Functions in C
- C - Functions
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Function Pointers
- C - Pointer to an Array
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Initialization of Pointer Arrays
- C - Pointers vs. Multi-dimensional Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Special Characters
- C Structures and Unions
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Lookup Tables
- C - Dot (.) Operator
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- File Handling in C
- C - Input & Output
- C - File I/O (File Handling)
- C Preprocessors
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- C - Macros
- C - Header Files
- Memory Management in C
- C - Memory Management
- C - Memory Address
- C - Storage Classes
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
Nested Structures in C
What is a Nested Structure in C?
A structure within a structure is known as nested structure in C. When one of the elements in the definition of a struct type is of another struct type, then we call it a 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.
Nested Structure Declaration
A nested structure can be declared by using a structure as a member of another structure.
Syntax
A general syntax of a nested structure is as follows −
struct struct1{ type var1; type var2; struct struct2 strvar; }
Example
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 another struct type called "course" that is characterized by "course ID", "title", and "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 |
Accessing Members of a Nested Structure
The structure's members can be accessed by using the dot (.) operator. In the case of nested structures, there can be multiple levels of structures. So, you need to use the dot (.) operator for each level of the structure to access the members of the nested structure.
Syntax
Below is the syntax to access members of nested structure –
level1.level2.member_name;
Here, level1 represents the structure variable of the outer (parent) structure, and level2 represents the structure variable of the inner (child) structure.
Example
Consider the following nested structure definition –
struct employee{ char name[10]; float salary; struct dob{ int d, m, y; } d1; }e1;
Here, e1 is the structure variable of the outer (level 1) structure "employee" and d1 is the structure variable of the inner (level 2) structure "dob".
To access the members of the employee structure, use e1.member_name.
printf("Name: %s\n", e1.name); printf("Salary: %f\n", e1.salary);
To access the members of the dob structure, use e1.d1.member_name.
printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
The nesting of structures can be performed in two different ways −
- Defining an inline structure
- Including the element of a structure already defined
Let us learn these methods using suitable examples.
Nested Structure by Defining Inline Structure
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 type for "date". 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
Take a look at the following 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
When you run this code, it will produce the following 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.
Nested Structure by Defining Separate Structure
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.
Example 1
Since "dob" is already defined, we can have an element of its type inside "employee".
#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
Run the code and check its 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 2
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 −
#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
When you run this code, it will produce the following 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 a pointer.
In case of a nested structure, the elements of the inner struct elements are accessed by "ptr → inner_struct_var.element;"
Example
In this example, 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.
#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
When you run this code, it will produce the following output −
Name: Kiran Salary: 25000.000000 Date of Birth: 12-5-1990