C Structures

Last Updated : 31 Aug, 2026

A structure in C is a user-defined data type that groups related variables of different data types under a single name. It is useful for representing real-world entities and organizing related data into a single unit.

  • The struct keyword is used to define a structure, and its variables are called members.
  • Structure members can be of different valid data types, including arrays, pointers and other structures.
  • Structures are widely used to represent entities such as students, employees and products, and to build data structures such as linked lists and trees.
C
#include <stdio.h>

// Defining a structure
struct A {
    int x;
};

int main() {
  
    // Creating a structure variable
    struct A a;
  	
  	// Initializing member
  	a.x = 11;

    printf("%d", a.x);
    return 0;
}

Output
11

Explanation: In the above example, a structure A is defined to hold an integer member x. A variable a of type struct A is created and its member x is initialized to 11 by accessing it using dot operator. The value of a.x is then printed to the console.

c_structure_1

Basic Operations of Structure

Following are the basic operations commonly used on structures:

1. Access Structure Members

  • To access or modify members of a structure, we use the ( . ) dot operator. This is applicable when we are using structure variables directly.
  • In the case where we have a pointer to the structure, we can also use the arrow operator to access the members.
C++
#include <stdio.h>

struct Student {
    int age;
    float marks;
};

int main() {

    struct Student s = {20, 85.5};

    // Accessing members using dot operator
    printf("Age: %d\n", s.age);
    printf("Marks: %.1f\n", s.marks);

    // Creating a pointer to the structure
    struct Student *ptr = &s;

    // Accessing members using arrow operator
    printf("Age using pointer: %d\n", ptr->age);
    printf("Marks using pointer: %.1f", ptr->marks);

    return 0;
}

Output
Age: 20
Marks: 85.5
Age using pointer: 20
Marks using pointer: 85.5

Explanation: In above example, s is a structure variable, while ptr stores its address. The code accesses the same age and marks members through both s and ptr and prints their values.

2. Initialize Structure Members

Structure members cannot be initialized inside the structure definition. However, they can be initialized at the time of declaring a structure variable using initializer lists.

C
#include <stdio.h>

// Defining a structure to represent a student
struct Student
{
    char name[50];
    int age;
    float grade;
};

int main()
{

    // Declaring and initializing a structure variable
    struct Student s1 = {"Rahul", 20, 18.5};

    // Designated Initializing another structure
    struct Student s2 = {.age = 18, .name = "Vikas", .grade = 22};

    // Accessing structure members
    printf("%s\t%d\t%.2f\n", s1.name, s1.age, s1.grade);
    printf("%s\t%d\t%.2f\n", s2.name, s2.age, s2.grade);

    return 0;
}

Output
Rahul	20	18.50
Vikas	18	22.00

Explanation: In the above example, the Student structure contains name, age, and grade members. s1 is initialized using an initializer list, while s2 uses designated initializers to assign values to specific members. The values of both structure variables are then accessed and printed using the dot (.) operator.

Types of Structure Initialization

We can initialize structure members in 4 ways which are as follows:

1. Default Initialization

  • By default, structure members are not automatically initialized to 0 or NULL.
  • Uninitialized structure members will contain garbage values. However, when a structure variable is declared with an initializer, all members not explicitly initialized are zero-initialized.

Note: We cannot initialize the arrays or strings using assignment operator after variable declaration.

2. Initialization using Initializer List

struct structure_name str = {value1, value2, value3 ....};

In this type of initialization, the values are assigned in sequential order as they are declared in the structure template.

3. Initialization using Designated Initializer List

Designated Initialization allows structure members to be initialized in any order. This feature has been added in the C99 standard.

struct structure_name str = { .member1 = value1, .member2 = value2, .member3 = value3 };

The Designated Initialization is only supported in C but not in C++.

3. Copy Structure

Copying structure is simple as copying any other variables. For example, s1 is copied into s2 using assignment operator.

s2 = s1;

But this method only creates a shallow copy of s1 i.e. if the structure s1 have some dynamic resources allocated by malloc, and it contains pointer to that resource, then only the pointer will be copied to s2. If the dynamic resource is also needed, then it has to be copied manually (deep copy).

C
#include <stdio.h>
#include <stdlib.h>

struct Student {
    int id;
  	char grade;
};

int main() {
    struct Student s1 = {1, 'A'};
  
  	// Create a copy of student s1
  	struct Student s1c = s1;

    printf("Student 1 ID: %d\n", s1c.id);
    printf("Student 1 Grade: %c", s1c.grade);
  	return 0;
}

Output
Student 1 ID: 1
Student 1 Grade: A

Explanation: In this example, s1 is initialized with an ID and grade, and s1c is created as a copy of s1 using the assignment operator. The copied values are then accessed through s1c and printed.

4. Passing Structure to Functions

Structure can be passed to a function in the same way as normal variables. Though, it is recommended to pass it as a pointer to avoid copying a large amount of data.

C
#include <stdio.h>

// Structure definition
struct A {
    int x;
};

// Function to increment values
void increment(struct A a, struct A* b) {
    a.x++;
  	b->x++;
}

int main() {
    struct A a  = { 10 };
  	struct A b  = { 10 };
  
  	// Passing a by value and b by pointer
  	increment(a, &b);
  
  	printf("a.x: %d \tb.x: %d", a.x, b.x);
    return 0;
}

Output
a.x: 10 	b.x: 11

Explanation: In this example, a is passed to the increment() function by value, while b is passed by pointer. The change to a.x affects only its copy, whereas b->x modifies the original structure.

5. typedef for Structures

  • The typedef keyword is used to define an alias for the already existing datatype. In structures, we have to use the struct keyword along with the structure name to define the variables.
  • Sometimes, this increases the length and complexity of the code. We can use the typedef to define some new shorter name for the structure.
C
#include <stdio.h>

// Defining structure
typedef struct {
    int a;
} str1;

// Another way of using typedef with structures
typedef struct {
    int x;
} str2;

int main() {
  
    // Creating structure variables using new names
    str1 var1 = { 20 };
    str2 var2 = { 314 };

    printf("var1.a = %d\n", var1.a);
    printf("var2.x = %d\n", var2.x);
    return 0;
}

Output
var1.a = 20
var2.x = 314

Explanation: In this code, str1 and str2 are defined as aliases for the unnamed structures, allowing the creation of structure variables (var1 and var2) using these new names. This simplifies the syntax when declaring variables of the structure.

Size of a Structure

The size of a structure is not necessarily equal to the sum of the sizes of its members because the compiler may add padding bytes to satisfy alignment requirements.

  • Structure Padding: Extra bytes inserted between or after members to properly align data in memory.
  • Structure Packing: A technique that reduces or removes padding to minimize memory usage.
  • Packing can be requested using compiler-specific features such as #pragma pack or __attribute__((packed)).

Nested Structures

In C, a nested structure refers to a structure that contains another structure as one of its members. This allows you to create more complex data types by grouping multiple structures together, which is useful when dealing with related data that needs to be grouped within a larger structure.

There are two ways in which we can nest one structure into another:

  • Embedded Structure Nesting: The structure being nested is also declared inside the parent structure.
  • Separate Structure Nesting: Two structures are declared separately and then the member structure is nested inside the parent structure.

Accessing Nested Members

We can access nested Members by using the same ( . ) dot operator two times.

C
#include <stdio.h>

// Child structure declaration
struct child {
    int x;
    char c;
};

// Parent structure declaration
struct parent {
    int a;
    struct child b;
};

int main() {
    struct parent p = { 25, 195, 'A' };

    // Accessing and printing nested members
    printf("p.a = %d\n", p.a);
    printf("p.b.x = %d\n", p.b.x);
    printf("p.b.c = %c", p.b.c);
    return 0;
}

Output
p.a = 25
p.b.x = 195
p.b.c = A

Explanation: In this code, the structure parent contains another structure child as a member. The parent structure is then initialized with values, including the values for the child structure's members.

Structure Pointer

A pointer to a structure allows us to access structure members using the ( -> ) arrow operator instead of the dot operator.

C
#include <stdio.h>

// Structure declaration
struct Point {
    int x, y;
};

int main() {
    struct Point p = { 1, 2 };

    // ptr is a pointer to structure p
    struct Point* ptr = &p;

    // Accessing structure members using structure pointer
    printf("%d %d", ptr->x, ptr->y);

    return 0;
}
Try It Yourself
redirect icon

Output
1 2

Explanation: In this example, ptr is a pointer to the structure Point. It holds the address of the structure variable p. The structure members x and y are accessed using the -> operator, which is used to dereference the pointer and access the members of the structure.

Self-Referential Structures

A self-referential structures contains a pointer member that points to another object of the same structure type. Self-referential structures are commonly used to implement dynamic data structures such as linked lists, trees and graphs.

struct Node {

int data;

struct Node *next;

};

Bit Fields

Bit Fields are used to specify the length of the structure members in bits. When we know the maximum length of the member, we can use bit fields to specify the size and reduce memory consumption.

struct Status {

unsigned int isReady : 1;

unsigned int error : 1;

};

Here, isReady and error are each allocated one bit.

Uses of Structure in C

Structures are widely used for organizing related data and building complex programs.

  • They allow programmers to create custom data types for entities such as students, employees, dates and complex numbers.
  • They group related data of different types into a single unit.
  • They are used to implement data structures such as linked lists, trees, stacks and graphs.
  • They can be passed to functions and used to return multiple related values from a function.
  • They are commonly used to model records in applications such as student management, employee management and banking systems.
Comment