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

  1. Structure Definition: The Student structure is defined with three members: id, name, and grade.
  2. Array Declaration: An array students of type struct Student is declared to hold 3 student records.
  3. Initialization: The array is initialized with data for 3 students.
  4. 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

  1. Function Definition: updateStudent takes a pointer to a Student structure, a new grade, and a new name as parameters. It updates the structure’s members.
  2. Function Call: In main, updateStudent is called with the address of student1 and 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

  1. Memory Allocation: The sizeof operator is used to determine the size of the union and its members.
  2. 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:

  1. Memory Optimization: Save memory when storing different types of data that are mutually exclusive.
  2. Type Interpretation: Interpreting a piece of data in multiple ways, such as in a variant record.
  3. 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;

Important Questions
Comments
Discussion
0 Comments
  Loading . . .