Structures In C

It has the following syntax:

Example

struct structure_name   

{  

    data_type member1;  

    data_type member2;  

    .

    .  

    data_type memberN;  

};

In this syntax,

  • structure_name: It represents the name of structure.
  • data_type: It represents the type of data.
  • member1, member2: It represents the member names.

Let's examine an illustration to establish a blueprint for an entity representing an employee in the C programming language.

Example

struct employee  

{   int id;  

    char name[20];  

    float salary;  

};

The image below displays the memory allocation of the employee structure as defined in the preceding example.

Why use Structures in C?

In C programming, situations arise where there is a need to preserve various characteristics of an object. It is common for an object to possess diverse attributes of varying data types, rather than being limited to a single type. For instance, considering a Student object, it could encompass attributes like name (string), roll number (integer), and marks (floating-point number). When faced with the task of storing such multifaceted information related to a student entity, the following strategies can be employed:

  • Create separate arrays dedicated to storing names, roll numbers, and marks.
  • Opt for a specialized data structure designed to accommodate a mix of different data types efficiently.
  • Declaring Structure Variable

We can define a variable to represent the structure, enabling convenient access to its members. There are two methods to declare a structure variable:

  • Using the struct keyword inside the main function
  • Declaring a variable while defining the structure.

Syntax 1: Define Structure Variables within the main function

Example

struct structure_name

 {

    // member declarations

};

struct structure_name var;

Syntax 2: Defining Structure Variables using Declaration

Example

struct structure_name

{

// member declarations

} var1, var2;

Explanation:

In this instance, the structure variables var1 and var2 are initialized immediately after defining the structure, offering a succinct approach to declare and initialize structure usage simultaneously.

Both methods are valid, and the decision is based on the program's architecture and readability preferences.

Accessing Members of the Structure

There are two methods to retrieve structure members:

  • Employing . (member or dot operator)
  • Utilizing -> (structure pointer operator)
  • Using Dot (.) Operator

In C programming, the dot (.) operator is primarily employed to access or modify the data members within a structure. This operator proves to be highly beneficial when we directly work with structure variables in C.

C Example to access the members of the structure using dot (.) operator

Let's consider a basic example to demonstrate how to retrieve structure members using the dot (.) operator in the C programming language.

Example

Example

#include<stdio.h>  

#include <string.h>    

struct employee      

{   int id;      

    char name[50];      

}e1;  //declaring e1 variable for structure    

int main( )    //main function

{    

   //store first employee information    

   e1.id=101;    

   strcpy(e1.name, "John");//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;  

} 

</string.h></stdio.h>

Output:

Output

employee 1 id : 101

employee 1 name : John

Using -> (Structure Pointer Operator)

In C programming, the -> operator is primarily employed to retrieve members of a structure using a pointer to that specific structure. When dealing with a pointer to a structure, direct usage of the dot (.) operator is not feasible. Hence, the -> operator must be utilized to dereference the pointer and access the member in a single step.

In C programming, we can access the members of a structure using the -> operator, also known as the Structure Pointer Operator.

Let's consider a basic example to demonstrate how to retrieve structure elements using the structure pointer operator in the C programming language.

Example

Example

#include <stdio.h>

struct Employee {  

    int emp_id;

    char emp_name[45];

};

int main() {

    struct Employee e1 = {201, "Peter"};

    struct Employee *ptr = &e1

    // Accessing members using structure pointer operator

    printf("Employee ID: %d\n", ptr->emp_id);

    printf("Employee Name: %s\n", ptr->emp_name);

    return 0;

}

</stdio.h>

Output:

Output

Employee ID: 201

Employee Name: Peter

Basic Structure Operations

There are various fundamental structure manipulations in C programming. Here are a few primary operations in C:

Copying Structures

Copying is a fundamental operation when working with structures in C programming. The assignment operator (=) is employed to transfer the value of one structure variable to another, mirroring its use with basic data types.

This process generates a superficial duplicate, meaning that if the arrangement includes references to memory generated dynamically, only the reference values are duplicated, not the actual memory data they point to. To reproduce the dynamically allocated data, it's necessary to produce a deep duplicate by assigning new memory and moving the data over.

C Example to Copying Structure

The upcoming examples demonstrate fundamental copying structures in the C programming language.

Example

Example

#include <stdio.h>

struct emp

{

    int emp_Id;

    char depart_ment;

};

int main()   //main function

{

    struct emp e1 = {1, 'D'};

    struct emp e2 = e1;

    printf("Employee ID is: %d\n", e2.emp_Id);

    printf("Department is: %c\n", e2.depart_ment);

    return 0;

}

</stdio.h>

Output:

Output

Employee ID is: 1

Department is: D

Explanation:

In this instance, we are examining the structure emp, comprising of two components: an integer empId and a character department. Within the main function, we create an object e1, followed by duplicating it to another object e2 using the assignment operator, showcasing shallow copying. Subsequently, the contents of e2 are outputted, revealing the replicated employee ID and department.

Passing Structures to Functions

In C programming, structures can be transmitted to functions either by value or by reference (using pointers). When passed by value, a duplicate of the structure is transferred, and any alterations made within the function do not impact the original data.

When aiming to minimize redundant duplication, particularly in the case of extensive data structures, it is more effective to provide a pointer that allows direct entry to and alteration of the initial data.

C Example to Pass Structures to Functions

Let's consider a scenario to demonstrate the fundamental concept of passing parameters to functions in the C programming language.

Example

Example

#include <stdio.h>

struct Product

{

    int st;

};

void Display(struct Product item, struct Product* item_copy) 

{

    item.st++;

    item_copy->st++;

}

int main()

{

    struct Product p1 = {50};

    struct Product p2 = {50};

    Display(p1, &p2);

    printf("Product-1 Stock: %d\nProduct-2 Stock: %d\n", p1.st, p2.st);

    return 0;

}

</stdio.h>

Output:

Output

Product-1 Stock: 50

Product-2 Stock: 51

Explanation:

In this instance, we are introducing a construct labeled Product, containing an integer attribute named "st" to signify stock levels. The primary function creates and sets values for two product instances, p1 and p2, then passes them to the Display function (p1 as a copy and p2 as a pointer). Within the function, modifications are applied solely to p2. Consequently, the outcome exhibits p1 remaining unaltered at 50 while p2 is raised to 51.

Using typedef with Structure

In C Programming, the typedef keyword enables the creation of a shorter nickname for an existing data type. When applied to structures, it removes the necessity of repeatedly typing the struct keyword when declaring variables. This feature enhances the clarity and ease of maintaining code, especially in extensive programs that heavily rely on structures.

C Example using Typedef with Structure

Let's consider an instance to demonstrate the application of typedef with structures in the C programming language.

Example

Example

#include <stdio.h>

typedef struct

{

    int vehicle_Id;

} Vehicle;

typedef struct 

{

    int order_no;

} Order;

int main()  //main function

{

    Vehicle v = {11};

    Order o = {5};

    printf("Vehicle ID is: %d\n", v.vehicle_Id);

    printf("Order Number is: %d\n", o.order_no);

    return 0;

}

</stdio.h>

Output:

Output

Vehicle ID is: 11

Order Number is: 5

Explanation:

In this instance, we employ typedef to create aliases Vehicle and Order for distinct structures, each containing a solitary integer element. Variables v and o are instantiated utilizing these aliases within the main function and given values. Subsequently, the printf statements exhibit the vehicle ID and order number saved in the respective structure variables.

Size of Structures

In C programming, it is crucial that the size of a structure equals the sum of its individual members. Nonetheless, this equality isn't always achieved because of structural padding. Padding refers to the practice of adding additional bytes between members to align data in memory based on the system's architecture. This alignment is beneficial as it improves access efficiency and reduces the number of CPU cycles required for data retrieval.

Structure alignment is implemented to prevent unnecessary padding in scenarios where memory consumption is restricted. In C, there are two common methods for tightly packing structures:

  • Employing #pragma pack (1)
  • Utilizing attribute(packed)

C Example for Size of Structures

Let's consider an example to demonstrate the scale of data structures in the C programming language.

Example

Example

#include <stdio.h>

#pragma pack(1)

typedef struct 

{

    char code;

    int quantity;

    float price;

} Packed_Item;

typedef struct

{

    char code;

    int quantity;

    float price;

} Regular_Item;

int main() 

{

    printf("The size of the PackedItem is: %lu bytes\n", sizeof(Packed_Item));

    printf("The size of the RegularItem is: %lu bytes\n", sizeof(Regular_Item));

    return 0;

}

</stdio.h>

Output:

Output

The size of the PackedItem is: 9 bytes

The size of the RegularItem is: 9 bytes

Explanation:

In this instance, we are showcasing two constructs: PackedItem, which employs #pragma pack(1) to eliminate padding, and RegularItem, which adheres to the default padding. Both consist of a char, an integer, and a float, yet their resulting sizes are 9 bytes, suggesting that the compiler mandated strict alignment or that padding was suppressed due to optimization configurations.

Nested Structures:

In C programming, a nested structure is a powerful concept that merges one structure with another, allowing for the representation of intricate, hierarchical data. This approach involves organizing interconnected subgroups within a larger structure, enhancing the clarity of code, maintaining a logical data arrangement, and facilitating modular development. The two primary methods for struct nesting include:

  • Embedded Structure

A nested structure in C, known as an embedded structure, involves defining a structure within another structure. This nested structure is confined to the parent structure and cannot be accessed outside of it.

Embedded Structure Example in C

Example

struct Student 

{

    char name[25];

    struct 

   {

        int day, month, year;

    } dateofbirth;

};
  • Separate Structure

A unique configuration is a nested arrangement where the internal framework is defined separately and then integrated into the outer framework. This setup enables the internal structure to be utilized across different frameworks.

Separate Structure Example

Example

struct Date 

{

    int day, month, year;

};

struct Student 

{

    char name[50];

    struct Date dateofbirth;

};

Accessing Nested Structure Members

When a structure is embedded within another in the C programming language, we can utilize the dot (.) operator to repeatedly access the properties of the inner (child) structure. This functionality enables us to retrieve and update data from deeply nested structures in a clean and organized fashion.

Accessing Nested Structure Members Example

Let's consider an instance to demonstrate how we can retrieve nested structure elements in C.

Example

Example

#include <stdio.h>

struct Dept 

{

    int d_id;

    char d_name[40];

};

struct Emp 

{

    int emp_id;

    char emp_name[60];

    struct Dept d;

};

int main()   //main function

{

    struct Emp e = {1, "Peter", {13, "Computer science"}};

    printf("Employee ID is: %d\n", e.emp_id);

    printf("Employee Name is: %s\n", e.emp_name);

    printf("Department ID is: %d\n", e.d.d_id);

    printf("Department Name is: %s\n", e.d.d_name);

    return 0;

}

</stdio.h>

Output:

Output

Employee ID is: 1

Employee Name is: Peter

Department ID is: 13

Department Name is: Computer science

Explanation:

In this instance, we are working with two constructs: Dept and Emp. Within the main function, the Emp object is instantiated with details regarding both the employee and the department. Subsequently, the dot notation is employed to retrieve the nested attributes.

Self-Referential Structures

A self-referential design is characterized by having a reference to its own type within its components. This feature enables the design to point to or connect with instances of the identical type, proving particularly beneficial in the development of interconnected data structures like linked lists, trees, and graphs.

These formations are essential for allocating dynamic memory and are frequently employed in sophisticated algorithms and data structures.

Self-Referential Structure Example in C

Let's consider an example to demonstrate self-referential structures in the C programming language.

Example

Example

#include <stdio.h>

struct Node

{

    int d;

    struct Node* next;  

};

int main() 

{

    struct Node n1 = {10, NULL};

    struct Node n2 = {20, NULL};

    n1.next = &n2

    printf("Node-1 Data is: %d\n", n1.d);

    printf("Node-2 Data is: %d\n", n1.next->d);

    return 0;

}

</stdio.h>

Output:

Output

Node-1 Data is: 10

Node-2 Data is: 20

Explanation:

In this instance, we establish a self-referential Node construct, where each node holds information (d) and a reference to the subsequent node (next). We instantiate two nodes, link them together, and subsequently display the information stored in both nodes utilizing the nexLogic Practiceer.

Uses of Structures

Several usage of structures in C are as follows:

  • Create custom data types in C, including dates, times, and complex numbers that are not supported natively.
  • Organize similar information into a single unit for easy access and administration.
  • Create complicated data structures like linked lists, trees, and graphs.
  • In order to return several values from a function, encapsulate diverse data types in one structure.
  • Structure in C MCQs

  1. Which keyword is used to define a structure in C?
  • struct
  • structure
  • record
  • class
  1. What is the syntax for accessing a structure member via a structure variable?
  • Using -> operator
  • Using . operator
  • Using :: operator
  • Using , operator

Which operator is utilized to retrieve members of a structure using a pointer?

  1. What is the size of an empty structure in C (assuming standard C)?
  • Compiler-dependent
  • Not allowed
  1. Can a structure contain another structure in C?
  • Only with typedef
  • Only pointers

Input Required

This code uses input(). Please provide values below: