Definition of Structure
A structure in C is a user-defined data type that allows grouping related variables (of different types)
under one name. Structures are used to represent a record or an object by combining variables
(called members) into a single unit. This is especially useful when you need to handle complex data
like student records, employee details, or points in a coordinate system
Syntax for Structure Definition
struct StructureName {
DataType member1;
DataType member2;
};
Key Points:
1. struct Keyword: Used to define a structure.
2. Structure Name: Serves as an identifier for the structure type.
3. Members: Variables inside the structure can have different data types.
Declaration, Initialization, and Accessing Structure Members
1. Declaration of a Structure
When defining a structure, you specify its layout but do not allocate memory. For example:
struct Student {
int id; // Member to store student ID
char name[50]; // Member to store student name
float marks; // Member to store marks
};
2. Initialization of a Structure
You can create and initialize a variable of the structure type:
Direct Initialization:
struct Student student1 = {101, "John Doe", 95.5};
Using Assignment Statements:
struct Student student2;
student2.id = 102;
strcpy(student2.name, "Jane Smith"); // For string assignment
student2.marks = 88.0;
3. Accessing Structure Members
To access structure members:
Use the dot operator (.) when working with a structure variable.
Use the arrow operator (->) when working with a pointer to a structure.
Example Program with Explanation
#include <stdio.h>
#include <string.h> // For string operations like strcpy
// Define a structure
struct Student {
int id; // Member: student ID
char name[50]; // Member: student name
float marks; // Member: student marks
};
int main() {
// Declare and initialize a structure variable
struct Student student1 = {101, "John Doe", 95.5};
// Print structure members
printf("Student Details:\n");
printf("ID: %d\n", student1.id);
printf("Name: %s\n", student1.name);
printf("Marks: %.2f\n", student1.marks);
// Modify structure members
student1.marks = 98.0; // Update marks
printf("\nUpdated Marks: %.2f\n", student1.marks);
// Create another structure variable
struct Student student2;
student2.id = 102;
strcpy(student2.name, "Jane Smith"); // Assign a string
student2.marks = 88.0;
// Print details of the second student
printf("\nAnother Student Details:\n");
printf("ID: %d\n", student2.id);
printf("Name: %s\n", student2.name);
printf("Marks: %.2f\n", student2.marks);
return 0;
Explanation of the Program
1. Structure Definition:
o The Student structure is defined with three members: id (integer), name (character
array), and marks (floating-point number).
2. Initialization:
o student1 is initialized directly with values.
o student2 is initialized using individual assignments (including strcpy for the string).
3. Accessing Members:
o The dot operator (.) is used to access and modify members of the structure variables
(student1 and student2).
4. Output:
o The program prints the details of both students, including the updated marks for
student1.
Output
Student Details:
ID: 101
Name: John Doe
Marks: 95.50
Updated Marks: 98.00
Another Student Details:
ID: 102
Name: Jane Smith
Marks: 88.00
Structure assignment allows assigning one structure variable to another of the same type. Unlike
arrays, structures in C support direct assignment of one variable to another, provided they belong to
the same structure type.
Syntax
struct StructureName var1, var2;
// Assign one structure to another
var2 = var1;
Both var1 and var2 must be of the same structure type.
This assignment copies the values of all members from var1 to var2.
Example
Structure Assignment Example
#include <stdio.h>
// Define a structure
struct Point {
int x; // Member: x-coordinate
int y; // Member: y-coordinate
};
int main() {
// Declare and initialize a structure variable
struct Point p1 = {10, 20};
// Declare another structure variable
struct Point p2;
// Assign p1 to p2
p2 = p1;
// Display values of both structures
printf("Point 1: (%d, %d)\n", p1.x, p1.y);
printf("Point 2: (%d, %d)\n", p2.x, p2.y);
// Modify p2 and show that p1 is unaffected
p2.x = 30;
printf("\nAfter modifying p2:\n");
printf("Point 1: (%d, %d)\n", p1.x, p1.y);
printf("Point 2: (%d, %d)\n", p2.x, p2.y);
return 0;
Explanation
1. Structure Declaration:
o The Point structure has two integer members, x and y.
2. Initialization:
o p1 is initialized with {10, 20}.
o p2 is declared without initialization.
3. Structure Assignment:
o p2 = p1; copies the values of p1 into p2.
4. Verification:
o Both p1 and p2 initially have the same values.
o Modifying p2 does not affect p1, demonstrating that a new copy is created.
Output
Point 1: (10, 20)
Point 2: (10, 20)
After modifying p2:
Point 1: (10, 20)
Point 2: (30, 20)
Key Points
1. Deep Copy:
o Structure assignment creates a deep copy, meaning each member is copied from the
source to the destination.
o Changes in one structure variable do not affect the other.
2. Conditions for Assignment:
o Both variables must be of the same structure type.
o The structure cannot contain members that are arrays with incomplete types (e.g.,
flexible array members).
Array of Structures
An array of structures is a collection of structure variables organized in a contiguous block of
memory. Each element of the array is a structure variable, and you can access members of each
structure using array indexing and the dot (.) operator.
Syntax
struct StructureName {
DataType member1;
DataType member2;
// More members...
};
struct StructureName arrayName[size]; // Declaring an array of structures
Example Program: Array of Structures
#include <stdio.h>
struct Student {
int id;
char name[50];
float marks;
};
int main() {
// Declare an array of structures
struct Student students[3];
// Input values for each student
for (int i = 0; i < 3; i++) {
printf("Enter details for student %d:\n", i + 1);
printf("ID: ");
scanf("%d", &students[i].id);
printf("Name: ");
scanf("%s", students[i].name);
printf("Marks: ");
scanf("%f", &students[i].marks);
// Display details of all students
printf("\nStudent Details:\n");
for (int i = 0; i < 3; i++) {
printf("Student %d: ID=%d, Name=%s, Marks=%.2f\n",
i + 1, students[i].id, students[i].name, students[i].marks);
return 0;
Output
Enter details for student 1:
ID: 101
Name: John
Marks: 95.5
Enter details for student 2:
ID: 102
Name: Jane
Marks: 88.0
Enter details for student 3:
ID: 103
Name: Mike
Marks: 76.5
Student Details:
Student 1: ID=101, Name=John, Marks=95.50
Student 2: ID=102, Name=Jane, Marks=88.00
Student 3: ID=103, Name=Mike, Marks=76.50
2. Self-Referential Structures
A self-referential structure is a structure that contains a pointer to itself. These structures are
commonly used to create linked lists, trees, and other dynamic data structures.
Syntax
struct StructureName {
DataType member1;
struct StructureName* next; // Pointer to a structure of the same type
};
Example Program: Self-Referential Structure
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next; // Self-referential structure
};
int main() {
// Create three nodes
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;
// Allocate memory for nodes in the heap
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
// Assign data and link nodes
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
// Traverse the linked list
struct Node* temp = head;
printf("Linked List: ");
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
// Free allocated memory
free(head);
free(second);
free(third);
return 0;
Output
Linked List: 1 -> 2 -> 3 -> NULL
Key Points
Array of Structures:
Useful for grouping similar records together (e.g., multiple students, employees).
Members of individual structures are accessed using array[index].member.
Self-Referential Structures:
Contains pointers to instances of the same structure type.
Used to create dynamic data structures like linked lists, trees, etc.
Memory management (e.g., malloc and free) is crucial when dealing with dynamic
structures.
Definition of Dynamic Memory Allocation
Dynamic Memory Allocation is the process of allocating memory during program runtime rather than
at compile time. This is particularly useful when the size or number of variables is not known in
advance. In C, memory is allocated dynamically using functions from the <stdlib.h> library, and
pointers are used to manage dynamically allocated memory.
Types of Dynamic Memory Allocation Functions in C
1. malloc (Memory Allocation):
o Allocates a block of memory of the specified size (in bytes).
o Memory is uninitialized.
o Syntax:
void* malloc(size_t size);
2. calloc (Contiguous Allocation):
o Allocates memory for an array of elements and initializes all bytes to zero.
o Syntax:
void* calloc(size_t num, size_t size);
3. realloc (Reallocation):
o Resizes a previously allocated memory block.
o Syntax:
void* realloc(void* ptr, size_t newSize);
4. free:
o Deallocates memory that was previously allocated dynamically.
o Syntax:
void free(void* ptr);
Example 1: Single Structure with Dynamic Memory Allocation
#include <stdio.h>
#include <stdlib.h>
// Define a structure
struct Student {
int id;
char name[50];
float marks;
};
int main() {
struct Student* studentPtr;
// Allocate memory dynamically for one structure
studentPtr = (struct Student*)malloc(sizeof(struct Student));
if (studentPtr == NULL) {
printf("Memory allocation failed.\n");
return 1;
// Input details
printf("Enter student details:\n");
printf("ID: ");
scanf("%d", &studentPtr->id);
printf("Name: ");
scanf("%s", studentPtr->name);
printf("Marks: ");
scanf("%f", &studentPtr->marks);
// Display details
printf("\nStudent Details:\n");
printf("ID: %d\n", studentPtr->id);
printf("Name: %s\n", studentPtr->name);
printf("Marks: %.2f\n", studentPtr->marks);
// Free allocated memory
free(studentPtr);
return 0;
Explanation
1. Memory is allocated dynamically using malloc.
2. The -> operator is used to access members of the structure.
3. Memory is freed using free after use.
Output
Enter student details:
ID: 101
Name: John
Marks: 95.5
Student Details:
ID: 101
Name: John
Marks: 95.50
Example 2: Dynamic Array of Structures
#include <stdio.h>
#include <stdlib.h>
// Define a structure
struct Student {
int id;
char name[50];
float marks;
};
int main() {
struct Student* students;
int n;
// Input the number of students
printf("Enter the number of students: ");
scanf("%d", &n);
// Allocate memory for an array of structures
students = (struct Student*)malloc(n * sizeof(struct Student));
if (students == NULL) {
printf("Memory allocation failed.\n");
return 1;
// Input details for each student
for (int i = 0; i < n; i++) {
printf("\nEnter details for student %d:\n", i + 1);
printf("ID: ");
scanf("%d", &students[i].id);
printf("Name: ");
scanf("%s", students[i].name);
printf("Marks: ");
scanf("%f", &students[i].marks);
// Display details of each student
printf("\nStudent Details:\n");
for (int i = 0; i < n; i++) {
printf("Student %d: ID=%d, Name=%s, Marks=%.2f\n",
i + 1, students[i].id, students[i].name, students[i].marks);
// Free the allocated memory
free(students);
return 0;
}
Explanation
1. Memory is dynamically allocated for an array of Student structures using malloc.
2. Each structure is accessed using the array index (e.g., students[i].id).
3. Memory is released using free.
Output
Enter the number of students: 2
Enter details for student 1:
ID: 101
Name: John
Marks: 95.5
Enter details for student 2:
ID: 102
Name: Jane
Marks: 88.0
Student Details:
Student 1: ID=101, Name=John, Marks=95.50
Student 2: ID=102, Name=Jane, Marks=88.00
Key Points
1. Dynamic Memory Advantages:
o Saves memory when the number of structure variables is unknown during compile
time.
o Can be resized dynamically if needed (realloc).
2. Memory Management:
o Always deallocate memory using free to avoid memory leaks.
o Check if the pointer returned by malloc or calloc is NULL before use.
Dynamic memory allocation provides flexibility in memory usage, making it essential for efficient
resource management in C programs.