Structures and Unions in C

In C programming language, we can construct a custom data type in five ways. In this section of the tutorial, we will discuss these five ways of creating a custom data type that can be used to write complex programs.

Now let’s move further to the introduction of the first custom data type, i.e. Structures.

What are Structures in C?

Structures are a collection of variables of different data types referenced under a single name. It makes a structure that packs data items of different data types. It provides a convenient means of collecting a group of logically related information together.

  • Structures help create any complex data items in a much meaningful and organized way.
  • It is often used in creating a complex program that provides an analogous concept of maintaining a record.
  • When we declare a Structure, it forms a template that is used to create Structure objects (i.e. instances of a Structure).
  • The variables inside the Structure are called members(also called elements or fields).

How to define a Structure in C?

As we discussed earlier, a Structure must be defined first, and then it can be used to declare Structure variables.
The general form of Structure definition is:

struct tag_name;

{

   data_type   member1;


   data_type   member2;


   data_type   member3;


   .


   .


};

Now let us understand how we can declare a Structure and create Structure variables, through an example.

Example:

struct addr


{


   char name[20];


   char street[50];


   char city[15];


   char state[10];


   unsigned long int zip;


};

 

  • Here, the keyword struct declares a structure to hold the details of the five data fields, i.e. name, street, city, state, and zip.
  • These data fields are called Structure elements or members.
  • Each member maybe belongs to a different data type.
  • addr is the name of the Structure and it is called the Structure tag.
  • The tag name may be used to declare variables that have the tag’s structure.
  • The declaration is terminated by a semicolon ‘;‘ because a Structure declaration is a statement.

How to declare Structure Variables?

In the example given above, note that no variables were declared, only a form of data was defined.

To declare a variable of type addr, we can write:

struct addr addr1;

Here, addr1 is a variable of type addr.

addr describes the form of Structure and addr1 is an object of the Structure.

More than one object can be declared when we declare a Structure.

Now Structure and objects can be combined and declared as follows:

struct addr

{


   char name[20];


   char street[50];


   char city[15];


   char state[10];


   unsigned long int zip;


} addr1;

 

The memory structure of addr1 is represented below:

typedef  Keyword in C

Keyword typedef can be used to define a Structure, like:

typedef struct

{

   .   .   .   .   .

   type member1;

   type member2;

   type member3;

   .   .   .   .   .

   .   .   .   .   .

} type_name;

Here, the type_name represents Structure definition related to it and it can be used to declare Structure variables, like:

type_name var1, var2, var3, . . . ;

Important note:

  1. The name type_name is the type definition name, and not a variable.
  2. Variable cannot be defined with a typedef declaration.

How to initialize a Structure in C?

A Structure variable can be initialized at compile time.
Example:

main()


{


   struct


   {


      int roll;


      float marks;


      int rank;


   }


   student = {17, 90.25, 3};


   . . . .


   . . . .


}
  • Here, value 17 is assigned to student.roll.
  • Value 90.25 is assigned to student.marks.
  • Value 3 is assigned to student.rank.
  • A member operator.‘ is used to link Structure members to the Structure variables.
  • We have not used any tag name for initializing one Structure variables.
  • But for more than one Structure variable we must use a tag name.
main()

{


   struct info


   {


      int roll;


      float marks;


      int rank;


   };


   struct info student1 = {17, 90.25, 3};


   struct info student2 = {19, 74.65, 16};


   . . . .


   . . . .


}

Here, info is the tag name used to initialize Structure variables.

How to access Structure Members?

In order to access Structure members, it should be linked to the Structure variables. To give an idea, we will look into an example given below:

Example:

struct info


{


   int roll;


   float marks;


   int rank;


} student1;

Here, the word student1 has no meaning whereas the phrase marks of student1 have a meaning.

The link between them is established using the member operator ‘.’ which is also known as dot operator. And now using this operator, we can access Structure members.

Example: student1.roll is a variable that can be used to access the information of the roll number of some students.

We can assign value to this variable:

student1.roll = 17;

We can use functions scanf() and printf() to read and write the value of the variable:

scanf(“%d”, &student1.roll);


printf(“%d”,student1.roll);   

Now, we will look into an example to understand how we can define and access Structure members in a program.

Example: Program to print student examination result.

Code:

#include<stdio.h>
struct info
{
    char name[20];
    int roll;
    float marks;
    int rank;
};
int main()
{
    struct info student1;
    printf("Enter the values: ");
    scanf("%s",student1.name);
    scanf("%d",&student1.roll);
    scanf("%f",&student1.marks);
    scanf("%d",&student1.rank);

    printf("Name: %s\n",student1.name);
    printf("Roll: %d\n",student1.roll);
    printf("Marks: %f\n",student1.marks);
    printf("Rank: %d\n",student1.rank);
    
    return 0;
}

Output:

Enter the values: Shahbaz
17
90
4
Name: Shahbaz
Roll: 17
Marks: 90.000000
Rank: 4

Operations on Structure Members

Any member of a Structure can be identified using the member operator or dot operator ‘.’. When a Structure member and Structure variable is linked using the member operator, it can be treated like any other variable, and hence any type of expressional and operational manipulation can be done on it.
Example:

if(student1.roll == 17)


student1.marks += 20.00;


float sum = student1.marks + student2.marks;


student1.marks * = 1.5;

Increment and decrement operators can also be used for manipulating numeric type members.
Example:

student1.marks ++;


++ student1.marks;

Important note: Member operator has higher precedence than any arithmetic and relational operators and hence no parentheses are required.

Copy Structure Variables

Variables under the same Structure type can be copied to each other in the same way that we do with an ordinary variable.

Example:

student1 = student2;

student 2 = student 1;

student 1 = student3;

Here, student1, student2 and student3 are the variables having a common Structure type.

Compare Structure Variables

We can compare each member individually. We cannot compare two Structure variables as it is invalid to perform any logical operations on Structure variables.

Valid operations:

student1.marks == student2.marks;

student2.marks != student3.marks;

Invalid operations:

student1 == student2;

student2 != student3;

Arrays of Structures in C

We can declare an Array of Structures, where each element of the Array represents a Structure variable. This property helps in writing a program where we want to create a Structure having multiple variables for individual members of Structures. We will look into an example to understand it.

Example:

struct class student[80]

{

   int subject1;


   int subject2;


   int subject3;


};


main()


{


   struct score student[3] = { {65, 70, 80}, {75, 55, 85}, {90, 60, 50} };


}
  • Here, an Array named student is declared of three elements namely, student[0], student[1], and student[2].
  • The elements are initialized with their members.
  • The Array is declared in its standard form just like any other Array.

Array initialization with their Structure members are given below:

student[0].subject1 = 65;

student[0].subject2 = 70;

student[0].subject3 = 80;

student[1].subject1 = 75;

student[1].subject2 = 55;

student[1].subject3 = 85;

student[2].subject1 = 90;

student[2].subject2 = 60;

student[2].subject3 = 50;

  • Here, each element of student Array is a Structure variable with three members.
  • For Array student, elements will be accessed using Array accessing methods.
  • And the Structure members will be accessed using the member operator.

The memory distribution of the above Array is like this:

Now, we will look into an example to understand how we can use an Array of Structure in a program.

C Program to print the total marks of a student.

Code:

#include<stdio.h>
struct score
{
    int subject1;
    int subject2;
    int subject3;
    int result;
};
int main()
{
    int i;
    struct score student[3] = {{70,80,90},{75,85,95},{45,55,65}};
    struct score result;

    for(i=0;i<=2;i++)
    {
        student[i].result = student[i].subject1+student[i].subject2+student[i].subject3;
        printf("Total marks of Student %d: %d\n",i+1,student[i].result);
    }
    return 0;
}

Output:

Total marks of Student 1: 240
Total marks of Student 2: 255
Total marks of Student 3: 165

Arrays within Structures

In the C programming language, we can use Arrays as Structure members. This means we can create one-dimensional or multi-dimensional Arrays of type integer or float inside a Structure type.

Example:

struct score


{


   int number;


   float subjects[3];


} student[3];
  • Here, subject is a Structure member which is also an Array that contains three elements i.e. subject[0], subject[1], and subject[2].
  • These elements can be accessed using standard Arrays accessing methods with member operators.

Structures and Functions In C

In C programming language, we can pass Structure values as arguments to Functions. There are multiple ways through which we can pass the Structure values from one Function to another.

We will now discuss the first method that involves passing a copy of the entire Structure to the called Function.

As we learned that a copy of the whole Structure is passed to the called Function, then the changes are only made to that copy of Structure. No changes are reflected in the original Structure in the calling function. After the changes are made, the called Function returns the entire Structure back to the calling function.

The general form of passing a copy of a Structure to a called Function is:

function_name (structure_variable_name);

The general form of the called Function having the Structure as the argument is:

data_type function_name (structure_variable_name)


{


   . . . . .


   . . . . .


   return (expression);


}

Below is an example to demonstrate how we can pass a Structure to a Function.

Example:

Important note:

  • The called Function must be declared with an appropriate type which must be relevant to the data type it is expected to return.
  • The Structure variable in the actual argument and the corresponding formal argument in the called Function must be of the same struct type.
  • We may only use a return statement when the called Function is expected to return some data value back to the calling Function.
  • When the called function returns a Structure, it must be assigned to an identical Structure type in the calling Function.

Structures and Pointers in C

Just like the name of an Array holds the address of its 0th element, likewise, the name of Arrays of Structure variables also holds the address of its 0th element. We will understand this with the help of an example given below.

Example:

struct collection


{


   char genre[20];


   int volumes;


   float price;


} book[2], *ptr;

  • Here, book is an Array of two elements of type struct collection.
  • And ptr is a Pointer to data objects of type struct collection.

ptr = book;

  • Now we assign the address of the 0th element of the book to ptr.
  • ptr will now point to the book[0].

Now we can access the Structure member by using the following notations:

ptr -> genre


ptr -> volumes


ptr -> price

or

(*ptr).genre


(*ptr).volumes


(*ptr).price

or

book[0].genre


book[0].volumes


book[0].price

Here, the symbol -> is called the arrow operator or member selection operator.

Now, we will look into an example to understand how we can use a Structure Pointer in a program.

C Program to store and print details of stocks.

Code:

#include<stdio.h>
struct invent
{
    char *name[15];
    int number;
    float price;
};
int main()
{
    struct invent product[3],*ptr;
    ptr = &product[3];
    printf("Enter the values: \n");
    scanf("%s", ptr->name);
    scanf("%d", &ptr->number);
    scanf("%f", &ptr->price);
    printf("Your entered value:\n");
    printf("Item name: %s\n",ptr->name);
    printf("Quantity: %d\n",ptr->number);
    printf("Price per item: %f\n",ptr->price);
    return 0;
}

Output:

Enter the values: 
Shirts
70
1200
Your entered value:
Item name: Shirts
Quantity: 70
Price per item: 1200.000000

What are Unions in C?

Unions have a concept similar to that of Structures and hence it has the exact same syntax as Structures. Unions can be declared using the keyword union.

The only main difference between Structure and Union is that each member of a Structure has its own storage location whereas all the members of a Union have the same location.

The compiler allocates a piece of storage to the Union that is large enough to hold the largest variable type in the Union.

A Union having multiple members of different types can handle only one member at a time.

How to declare a Union in C?

We can declare a Union using the keyword union. Now let’s look into an example to understand how we can declare a Union in a program.

Example:

union stock;
{
char a;
float b;
int c;
} item;

  • Here, item is a variable of type union stock.
  • This Union contains three members having different data types.
  • Only one member can be used at once.

The storage distribution is represented below:

How to access Union Members in C?

We can access the Union members by using the same syntax that we have used for Structures in the above headings.

Example:

union stock;
{
char a;
float b;
int c;
} item;

Now, to access Union members we can use the following notations:

item.a
item.b
item.c

A Unions creates a storage location that can be used by any of the Union members but only one at a time.
Also, when a different Union member is assigned a new value, it supersedes the value of the previous member.

How to initialize a Union in C?

Unions can be initialized when the variable is declared. But it can be initialized only with a value of the same type as the first Union member, unlike the initialization in a Structure.

Example:

union stock xyz = {80};

But the following initialization is invalid:

union stock xyz = {80.25};

Here, the initialization of the Union variable is invalid because the value is not the same as the type of the first member i.e. int.

Difference between Structures and Unions

STRUCTURE

UNION

Keyword struct is used to define a Structure

Keyword union is used to define a Union

Object of a Structure will get memory equal to the sum of memory of all the members

Object of a Union will get memory equal to the memory of the highest member of the union

All the members can be used simultaneously

Only one member can store valid value

Any changes made in one member will not reflect in other members

Any changes made in one member will reflect in other members too

Multiple members can be initialized at once

The first member can be initialized only

C programs on Structures and Unions.

Program to print employee details using Nested Structure.

Code:

#include<stdio.h>

struct employee
{
    struct date
    {
        int d;
        int m;
        int y;
    };
    int id;
    struct date dob;
    struct date doj;
};

int main()
{
    struct employee e1;
 printf("Enter id of a employee: ");
 scanf("%d",&e1.id);
 printf("Enter date of birth: \n");
 scanf("%d%d%d",&e1.dob.d, &e1.dob.m,&e1.dob.y);
 printf("\nEmployee ID: %d\n",e1.id);
 printf("Date of birth: %d/%d/%d\n",e1.dob.d,e1.dob.m,e1.dob.y);
 return 0;
}

Output:

Enter id of a employee: 1542
Enter date of birth: 
12 
05
1998

Employee ID: 1542
Date of birth: 12/5/1998

C Program to print student records.

Code:

#include <stdio.h>
#include <string.h>
struct student
{
 int roll;
 char name[15];
 float marks;
};
int main()
{
 struct student record = {0};
 record.roll=17;
 strcpy(record.name, "John");
 record.marks = 92.6;
 printf(" Name: %s \n", record.name);
 printf(" Roll: %d \n", record.roll);
 printf(" Marks: %f \n", record.marks);
 return 0;
}

Output:

Name: John 
Roll: 17 
Marks: 92.599998

C Program to display player scorecard.

Code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
struct cricket {
   char name1[20];
   char name2[20];
   int wins;
} player[4], x;
 
int main()
{
   int i, j, n=4;
 
   for (i = 0; i <=3; i++) {
      printf("\nPlayer: ");
      scanf("%s", player[i].name1);
      printf("\nTeam: ");
      scanf("%s", player[i].name2);
      printf("\nTotal wins: ");
      scanf("%d", &player[i].wins);
      printf("\n");
   }
 
   for (i = 1; i < n; i++)
      for (j = 0; j < n - i; j++)
      {
         if (strcmp(player[j].name2, player[j + 1].name2) > 0)
         {
            x = player[j];
            player[j] = player[j + 1];
            player[j + 1] = x;
         }
      }
 
   for (i = 0; i < n; i++)
   {
      printf("\n%s\t%s\t%d",player[i].name1,player[i].name2,player[i].wins);
   }
   printf("\n");
   return 0;
}

Output:

Player: Niel

Team: KKR

Total wins: 10


Player: Nitin 

Team: RCB

Total wins: 0


Player: Mukesh

Team: MI

Total wins: 15


Player: Dhoni

Team: CSK

Total wins: 100


Dhoni   CSK     100
Niel    KKR     10
Mukesh  MI      15
Nitin   RCB     0