The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

Structures and Union

Structures
Suppose you want to store information about a student ( name, roll no., marks ). You need a character array or a string to store the name, integer variable to store roll no. and a float variable to store marks. To access the information, the string, int and float variables needs to be accessed separately. Structures provide a mechanism to combine all the information under a single data type. In simple words, we have seen atomic variables ( int, char, float, etc. ) storing single piece of information, arrays store multiple pieces of information of same data type, but structures can hold multiple pieces of information of dissimilar data types. See the following program to understand how structures are defined, initialized and how data in a structure is accessed :

#include <stdio.h>

/* define a structure to hold student information
 * Dissimilar data types are combined under a single user defined data type 
 */
struct student {
   char name[30];
   int roll;
   float marks;
};

int main() {
   /* declare and initialize variables of type struct student */
   struct student s1 = { "Anjali", 1, 92.5 }; /* initialize s1 */
   struct student s2 = { "Rahul", 2, 87 }; /* initialize s2 */

   /* Display the student information */
   printf("Roll Number : %d\n", s1.roll);
   printf("Name : %s\tMarks : %f\n", s1.name, s1.marks);
   printf("Roll Number : %d\n", s2.roll);
   printf("Name : %s\tMarks : %f", s2.name, s2.marks);
   return 0;
}

Please note that s1 and s2 are variables of a user defined data type struct student. The members of struct student data type are name, roll and marks and they are accessed using dot ( . ) operator.

Array of Structures
In the above program, we stored information about 2 students in variables s1 and s2. What if you want to store information about 100 students ? We will simply use an array of structures. Following program demonstrate the use of array of structures. Also, it illustrates how array of structures is passed to a function. Structure variables are passed in the same way as variables of other data types are passed.

#include <stdio.h>

/* define a structure to hold student information
 * Since we are using typedef, now struct student is same as 'stud'. 
 * Now instead of declaring a variable as 'struct student s1;',
 * we can declare it as 'stud s1;' 
 */
typedef struct student {
   char name[30];
   int roll;
   float marks;
}stud;

/* Function to display the student information
 * params : Array of structures ( s[] ) and no. of students ( n )
 */
void displayInfo(stud s[], int n) {
   int i;
   printf("\nStudent Information :- \n");
   for ( i = 0; i < n; i++ ) {
      printf("Roll Number : %d\n", s[i].roll);
      puts(s[i].name);
      printf("Marks : %f\n", s[i].marks);
   }
}

int main() {
   stud s[3]; // array of structure to hold information about 3 students
   int i;
   printf("Enter the student information one by one :- \n");
   for ( i = 0; i < 3; i++ ) {
      printf("\nStudent %d :-\n", i + 1);
      printf("Roll No. : ");
      scanf("%d", &s[i].roll);           /* input Roll No. */
      fflush(stdin);                     /* flush the input buffer */
      printf("Name : ");
      fgets(s[i].name, 30, stdin);       /* input Name */
      printf("Marks : ");
      scanf("%f", &s[i].marks);          /* input Marks */
   }

   /* display the student information */
   displayInfo(s, 3); /* call the display function */
   return 0;
}
Run this program in your system to take input at run-time  


Nesting of Structures
We can declare a structure variable inside another structure. This is known as nesting of structures. In order to access one of the members of nested structures, dot operator is used until the member is reached in the structure hierarchy. Following program illustrates the nesting of structures :

#include <stdio.h>
#include <string.h>

/* define a structure to hold information about a person */
typedef struct Person {
   char name[30];
   int age;
}person;

/* define a structure to hold information about an employee */
typedef struct employee {
   person p; /* declare a variable 'p' of type 'person' */
   float salary;
}emp;

int main() {
   emp e; /* declare a variable 'e' of type 'employee' */
   /* populate the members of 'emp' structure */
   strcpy(e.p.name, "Rahul");
   e.p.age = 24;
   e.salary = 25000.94;

   /* display the employee information */
   printf("Employee Name : %s\n", e.p.name);
   printf("Employee Age : %d\n", e.p.age);
   printf("Employee Salary : %f\n", e.salary);
   return 0;
}

In the above program, structure person has been defined outside and a variable p of type person is declared inside structure employee. We can actually define the the complete structure inside another structure.

Pointer to structures
A pointer variable stores the address of some other variable. Same principle applies to structure variables also. We can declare a pointer which points to a structure variable and then the members of that structure can be accessed using the pointer. The only difference being the use of arrow ( -> ) operator while using pointers.
See the program below :

#include <stdio.h>

/* define a structure to hold employee information */
typedef struct employee {
   int id; /* employee id */
   float salary; /* employee salary */
}emp;

int main() {
   emp e = { 101, 72000.67 }; /*declare and initialize a variable of type emp*/
   emp *ptr; /* declare a pointer variable 'ptr' of type 'emp' */
   ptr = &e; /* 'ptr' holds the address of variable 'e' */

   /* access the values of variable 'e' */
   printf("%d\t%f\n", e.id, e.salary);        /* usual manner */
   printf("%d\t%f\n", ptr->id, ptr->salary);  /* using pointers */
   return 0;
}


Union
Union is similar to a structure in terms of declaration and usage but all the members of a union occupy the same space in memory i.e, memory location is shared among the union members. The size of the union is
that of the greatest member in terms of size. Since all the members of a union share the same memory space, modification of one member affects other. The value of one member gets overwritten by the value of other member. See the program below :

#include <stdio.h>

/* define a union with two variables */
typedef union type {
   int a;
   float b;
}my_type;

int main() {
   my_type x;
   x.a = 5; // member 'a' initialized
   printf("a : %d\n", x.a); // prints a : 5
   x.b = 7.3; // member 'b' initialized, overwrites 'a'
   printf("a : %d\n", x.a); // now 'a' has garbage value
   printf("b : %f\n", x.b); // prints b : 7.3
   return 0;
}

Back | Next