C Structure
By Paribesh Sapkota
Introduction to Structures
A structure in C is a user-defined data type that allows the grouping of variables of different types under a single name. It is used to represent a record.
Why use structure?
In C, there are cases where we need to store multiple attributes of an entity. It is not necessary that an entity has all the information of one type only. It can have different attributes of different data types. For example, an entity Student may have its name (string), roll number (int), marks (float). To store such type of information regarding an entity student, we have the following approaches.
- Construct individual arrays for storing names, roll numbers, and marks.
- Use a special data structure to store the collection of different data types.
#include<stdio.h>
void main ()
{
char names[2][10],dummy; // 2-dimensioanal character array names is used to store the names of the students
int roll_numbers[2],i;
float marks[2];
for (i=0;i<3;i++)
{
printf("Enter the name, roll number, and marks of the student %d",i+1);
scanf("%s %d %f",&names[i],&roll_numbers[i],&marks[i]);
scanf("%c",&dummy); // enter will be stored into dummy character at each iteration
}
printf("Printing the Student details ...\n");
for (i=0;i<3;i++)
{
printf("%s %d %f\n",names[i],roll_numbers[i],marks[i]);
}
}
the syntax to define the structure in c.
struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
};

Declaring structure variable
We can declare a variable for the structure so that we can access the member of the structure easily. There are two ways to declare structure variable:
1st way:
Let’s see the example to declare the structure variable by struct keyword. It should be declared within the main function.
struct employee
{ int id;
char name[50];
float salary;
};
2nd way:
Let’s see another way to declare variable at the time of defining the structure.
struct employee
{ int id;
char name[50];
float salary;
}e1,e2;
Let’s see a simple example of structure in C language.
#include<stdio.h>
#include <string.h>
struct employee
{ int id;
char name[50];
}e1; //declaring e1 variable for structure
int main( )
{
//store first employee information
e1.id=101;
strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
//printing first employee information
printf( "employee 1 id : %d\n", e1.id);
printf( "employee 1 name : %s\n", e1.name);
return 0;
}
Array of Structures
Why use an array of structures?
Consider a case, where we need to store the data of 5 students. We can store it by using the structure as given below.
#include<stdio.h>
struct student
{
char name[20];
int id;
float marks;
};
void main()
{
struct student s1,s2,s3;
int dummy;
printf("Enter the name, id, and marks of student 1 ");
scanf("%s %d %f",s1.name,&s1.id,&s1.marks);
scanf("%c",&dummy);
printf("Enter the name, id, and marks of student 2 ");
scanf("%s %d %f",s2.name,&s2.id,&s2.marks);
scanf("%c",&dummy);
printf("Enter the name, id, and marks of student 3 ");
scanf("%s %d %f",s3.name,&s3.id,&s3.marks);
scanf("%c",&dummy);
printf("Printing the details....\n");
printf("%s %d %f\n",s1.name,s1.id,s1.marks);
printf("%s %d %f\n",s2.name,s2.id,s2.marks);
printf("%s %d %f\n",s3.name,s3.id,s3.marks);
}
An array of structures allows you to store multiple records of the same structure type, making it easier to manage and manipulate related sets of data. This is particularly useful when dealing with records such as students, employees, or coordinates. Each element of the array is a structure of the same type.
Managing Student Records
Let’s consider an example where we want to manage records of students using an array of structures.
Define the Structure
First, define a structure to represent a student.
#include <stdio.h>
// Define a structure to hold student information
struct Student {
int id;
char name[50];
float grade;
};
Declare and Initialize an Array of Structures
Next, declare an array of structures to hold multiple student records and initialize it.
int main() {
// Declare an array of 3 Student structures
struct Student students[3] = {
{1, "Alice", 85.5},
{2, "Bob", 92.3},
{3, "Charlie", 78.9}
};
// Print student records
for (int i = 0; i < 3; i++) {
printf("ID: %d, Name: %s, Grade: %.2f\n", students[i].id, students[i].name, students[i].grade);
}
return 0;
}
Explanation
- Structure Definition: The
Studentstructure is defined with three members:id,name, andgrade. - Array Declaration: An array
studentsof typestruct Studentis declared to hold 3 student records. - Initialization: The array is initialized with data for 3 students.
- Access and Print: A loop iterates over the array and prints the details of each student.
Using Functions with Arrays of Structures
You can pass arrays of structures to functions to perform operations such as printing records, modifying data, or calculating statistics.
#include <stdio.h>
// Define a structure to hold student information
struct Student {
int id;
char name[50];
float grade;
};
// Function to print student records
void printStudents(struct Student students[], int size) {
for (int i = 0; i < size; i++) {
printf("ID: %d, Name: %s, Grade: %.2f\n", students[i].id, students[i].name, students[i].grade);
}
}
int main() {
// Declare and initialize an array of 3 Student structures
struct Student students[3] = {
{1, "Alice", 85.5},
{2, "Bob", 92.3},
{3, "Charlie", 78.9}
};
// Call the function to print student records
printStudents(students, 3);
return 0;
}
Modifying Records in an Array of Structures
You can also write functions to modify records in an array of structures.
#include <stdio.h>
#include <string.h>
// Define a structure to hold student information
struct Student {
int id;
char name[50];
float grade;
};
// Function to update a student's grade
void updateGrade(struct Student students[], int size, int id, float newGrade) {
for (int i = 0; i < size; i++) {
if (students[i].id == id) {
students[i].grade = newGrade;
return;
}
}
printf("Student with ID %d not found.\n", id);
}
int main() {
// Declare and initialize an array of 3 Student structures
struct Student students[3] = {
{1, "Alice", 85.5},
{2, "Bob", 92.3},
{3, "Charlie", 78.9}
};
// Update Bob's grade
updateGrade(students, 3, 2, 95.0);
// Print student records
for (int i = 0; i < 3; i++) {
printf("ID: %d, Name: %s, Grade: %.2f\n", students[i].id, students[i].name, students[i].grade);
}
return 0;
}
Passing structures to functions
Passing structures to functions in C can be done either by value or by reference (using pointers). Each method has its own advantages and use cases.
Passing Structures by Value
When you pass a structure by value, a copy of the entire structure is made. This is useful when you want to ensure that the function cannot modify the original structure.
Example
#include <stdio.h>
// Define a structure to hold student information
struct Student {
int id;
char name[50];
float grade;
};
// Function to print student details
void printStudent(struct Student s) {
printf("ID: %d, Name: %s, Grade: %.2f\n", s.id, s.name, s.grade);
}
int main() {
// Declare and initialize a Student structure
struct Student student1 = {1, "Alice", 85.5};
// Pass the structure by value to the function
printStudent(student1);
return 0;
}
Passing Structures by Reference
When you pass a structure by reference, you pass a pointer to the structure. This allows the function to modify the original structure.
#include <stdio.h>
// Define a structure to hold student information
struct Student {
int id;
char name[50];
float grade;
};
// Function to modify student details
void updateStudent(struct Student *s) {
s->grade = 90.0;
sprintf(s->name, "Updated Name");
}
int main() {
// Declare and initialize a Student structure
struct Student student1 = {1, "Alice", 85.5};
// Pass the structure by reference to the function
updateStudent(&student1);
// Print updated student details
printf("ID: %d, Name: %s, Grade: %.2f\n", student1.id, student1.name, student1.grade);
return 0;
}
Advantages and Disadvantages
Passing by Value
- Advantages:
- Ensures the original structure is not modified.
- Safe for read-only operations.
- Disadvantages:
- Can be inefficient for large structures due to the overhead of copying.
- Limited to read-only operations within the function.
Passing by Reference
- Advantages:
- More efficient for large structures as it avoids copying.
- Allows modification of the original structure.
- Disadvantages:
- The original structure can be unintentionally modified.
- Requires careful handling of pointers to avoid errors.
Use Cases
- Passing by Value: Use when you want to ensure the function cannot modify the original structure and when dealing with small structures where the overhead of copying is negligible.
- Passing by Reference: Use when the structure is large or when the function needs to modify the original structure.
Nested Structures
Nested structures in C are structures that contain other structures as members. This is useful for organizing complex data and creating hierarchical relationships between different data elements.
Example of Nested Structures
Consider an example where we want to store information about a student, including their personal details and academic details. We can define nested structures to represent this information.
Defining Nested Structures
#include <stdio.h>
// Define a structure for personal details
struct PersonalDetails {
char name[50];
int age;
char address[100];
};
// Define a structure for academic details
struct AcademicDetails {
int id;
float grade;
};
// Define a structure for student that includes nested structures
struct Student {
struct PersonalDetails personal;
struct AcademicDetails academic;
};
int main() {
// Declare and initialize a Student structure
struct Student student = {
{"Alice", 20, "123 Main St"},
{1, 85.5}
};
// Print student details
printf("Name: %s\n", student.personal.name);
printf("Age: %d\n", student.personal.age);
printf("Address: %s\n", student.personal.address);
printf("ID: %d\n", student.academic.id);
printf("Grade: %.2f\n", student.academic.grade);
return 0;
}
Passing Nested Structures to Functions
You can pass nested structures to functions just like any other structure. You can pass them by value or by reference.
#include <stdio.h>
// Define a structure for personal details
struct PersonalDetails {
char name[50];
int age;
char address[100];
};
// Define a structure for academic details
struct AcademicDetails {
int id;
float grade;
};
// Define a structure for student that includes nested structures
struct Student {
struct PersonalDetails personal;
struct AcademicDetails academic;
};
// Function to update student grade
void updateGrade(struct Student *student, float newGrade) {
student->academic.grade = newGrade;
}
int main() {
// Declare and initialize a Student structure
struct Student student = {
{"Alice", 20, "123 Main St"},
{1, 85.5}
};
// Update the student's grade
updateGrade(&student, 95.0);
// Print updated student details
printf("Updated Grade: %.2f\n", student.academic.grade);
return 0;
}
Pointer to structure
Using pointers to structures in C allows for efficient manipulation of structure data, especially when passing structures to functions. This avoids the overhead of copying large structures and enables direct modification of the original data.
Basic Usage of Pointers to Structures
Defining a Structure
#include <stdio.h>
// Define a structure for student information
struct Student {
int id;
char name[50];
float grade;
};
Using a Pointer to a Structure
You can declare a pointer to a structure and use it to access and modify the structure’s members.
Example
#include <stdio.h>
// Define a structure for student information
struct Student {
int id;
char name[50];
float grade;
};
int main() {
// Declare and initialize a Student structure
struct Student student1 = {1, "Alice", 85.5};
// Declare a pointer to the Student structure
struct Student *ptr;
// Assign the address of student1 to the pointer
ptr = &student1;
// Access structure members using the pointer
printf("ID: %d\n", ptr->id);
printf("Name: %s\n", ptr->name);
printf("Grade: %.2f\n", ptr->grade);
// Modify structure members using the pointer
ptr->grade = 90.0;
sprintf(ptr->name, "Alice Smith");
// Print updated student details
printf("Updated Name: %s\n", student1.name);
printf("Updated Grade: %.2f\n", student1.grade);
return 0;
}
Passing Pointers to Structures to Functions
Passing a pointer to a structure to a function allows the function to modify the original structure.
Example: Function to Modify Structure Members
#include <stdio.h>
// Define a structure for student information
struct Student {
int id;
char name[50];
float grade;
};
// Function to update student grade and name
void updateStudent(struct Student *s, float newGrade, const char *newName) {
s->grade = newGrade;
sprintf(s->name, "%s", newName);
}
int main() {
// Declare and initialize a Student structure
struct Student student1 = {1, "Alice", 85.5};
// Update student details using a function
updateStudent(&student1, 95.0, "Alice Smith");
// Print updated student details
printf("Updated ID: %d\n", student1.id);
printf("Updated Name: %s\n", student1.name);
printf("Updated Grade: %.2f\n", student1.grade);
return 0;
}
Explanation
- Function Definition:
updateStudenttakes a pointer to aStudentstructure, a new grade, and a new name as parameters. It updates the structure’s members. - Function Call: In
main,updateStudentis called with the address ofstudent1and the new grade and name
Introduction to Union
A union in C is a user-defined data type similar to a structure, but with a key difference: all members of a union share the same memory location. This means that at any given time, a union can store only one of its members’ values. The size of a union is determined by the size of its largest member. Unions are used when you need to store different data types in the same memory location.
Defining a Union
To define a union, use the union keyword followed by the union name and the body enclosed in braces, similar to how structures are defined.
#include <stdio.h>
// Define a union to hold different types of data
union Data {
int i;
float f;
char str[20];
};
int main() {
// Declare a union variable
union Data data;
// Access and modify the union members
data.i = 10;
printf("data.i: %d\n", data.i);
data.f = 220.5;
printf("data.f: %.2f\n", data.f);
// Note: When assigning a new value, the previous value is overwritten
strcpy(data.str, "C Programming");
printf("data.str: %s\n", data.str);
return 0;
}
Memory Allocation
The memory allocated for a union is the size of its largest member. This allows the union to store any one of its members at a time, but only one value is stored.
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
printf("Size of union: %lu bytes\n", sizeof(data));
printf("Size of int: %lu bytes\n", sizeof(data.i));
printf("Size of float: %lu bytes\n", sizeof(data.f));
printf("Size of char array: %lu bytes\n", sizeof(data.str));
return 0;
}
Explanation
- Memory Allocation: The
sizeofoperator is used to determine the size of the union and its members. - Output: The size of the union is equal to the size of its largest member (
char str[20]).
Use Cases for Unions
Unions are useful in situations where you need to work with different types of data but only one type at a time. Common use cases include:
- Memory Optimization: Save memory when storing different types of data that are mutually exclusive.
- Type Interpretation: Interpreting a piece of data in multiple ways, such as in a variant record.
- Hardware Interfacing: Efficiently managing different types of data received from hardware devices.
Using Unions in a Variant Record
A variant record is a common use case for unions, where different types of data are stored in the same memory location.
#include <stdio.h>
// Define a union to hold different types of data
union Data {
int i;
float f;
char str[20];
};
// Define a structure that includes a union for variant record
struct Variant {
int type;
union Data data;
};
int main() {
struct Variant v;
// Store an integer
v.type = 0;
v.data.i = 42;
printf("Type: %d, Integer: %d\n", v.type, v.data.i);
// Store a float
v.type = 1;
v.data.f = 3.14;
printf("Type: %d, Float: %.2f\n", v.type, v.data.f);
// Store a string
v.type = 2;
strcpy(v.data.str, "Hello, World!");
printf("Type: %d, String: %s\n", v.type, v.data.str);
return 0;
}
Difference Between Structure and Union in C
Defining a structure: To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than or equal to one member. The format of the struct statement is as follows:
struct [structure name]
{
member definition;
member definition;
...
member definition;
};
(OR)
struct [structure name]
{
member definition;
member definition;
...
member definition;
}structure variable declaration;
Defining a Union: To define a union, you must use the union statement in the same way as you did while defining a structure. The union statement defines a new data type with more than one member for your program. The format of the union statement is as follows:
union [union name]
{
member definition;
member definition;
...
member definition;
};
(OR)
union [union name]
{
member definition;
member definition;
...
member definition;
}union variable declaration;
