STRUCTURES
INTRODUCTION:We have seen that arrays can be used to represent a group of data items that belong to the same type, such as int or float. However, if we want to represent a collection of data items of different types using a single name, then we cannot use an array. Fortunately, C supports a constructed data type known as structure; which is a method for packing data of different types.
USE OF STRUCTURES:
Suppose, we want to store data about a book, we might want to store its name (a string), its price (a float) and number of pages in it (an int). If data about say 3 such books is to be stored, then we can follow two approaches.
i) Construct individual arrays, one for storing names, another for storing prices and still another for storing no. of pages.
ii) Use of structure variable.
In first approach, the program becomes more difficult to handle as the no. of items relating to the book go on increasing. For example, we would be re required to use a number of arrays, if we also decide to store name of the publisher, date of purchase of book etc. To solve this problem, C provides a special data type, called structure.
A structure declaration starts with the keyword struct, which introduces the declaration. The declaration then follows with a list of variables enclosed within curly braces. These variables are called members. Members can be accessed using the member access operator . (dot).
Syntax for structure declaration statement:
struct
data_type element1;
data_type element2;’
. . . . . . . . . . . . . . . .
data_type elementn;
};
Once the new structure data type has been defined one or more variables can be declared to be of that type. This is as follows:
struct <struct_name> <str_var1>, <str_var2>, . . . .<str_varn>;
We can combine the declaration of the structure type and the structure variables in one statement.
For example:
struct book
{
char name;
float price;
int pages;
};
struct book b1,b2,b3;
is same as . . .
struct book
{
char name;
float price;
int pages;
}b1,b2,b3;
Like primary variables and arrays, structure variables can also be initialised where they are declared. The format used is quite similar to that used to initiate arrays.
struct book
{
char name[20];
float price;
int pages;
};
struct book b1 = { “MATHS”, 130.00, 550 };
struct book b2 = { “COMPUTER”, 150.00, 800 };
The following program illustrates the use of the structure.
/* EX-53: ILLUSTRATES THE USE OF THE STRUCTURE */ |
#include<stdio.h> main() { struct book { char name; float price; int pages; }; struct book b1,b2,b3; clrscr(); printf("\n Enter name, prices and no. of pages of 3 books: \n"); scanf("%c %f %d", &b1.name, &b1.price, &b1.pages); fflush(stdin); scanf("%c %f %d", &b2.name, &b2.price, &b2.pages); fflush(stdin); scanf("%c %f %d", &b3.name, &b3.price, &b3.pages); printf("\n\t The 3 records you have entered:\n"); printf("\n\t %c %f %d", b1.name, b1.price, b1.pages); printf("\n\t %c %f %d", b2.name, b2.price, b2.pages); printf("\n\t %c %f %d", b3.name, b3.price, b3.pages); getch(); } |
MEMORY MAP OF STRUCTURE ELEMENTS:
Whatever be the elements of a structure, they are always stored in contiguous memory locations. The following program can illustrate this.
/* EX-54: MEMORY MAP OF STRUCTURE ELEMENT */ |
main() { struct book { char *name; float price; int pages; }; struct book b={ "SARASWATHY",81.25,408 }; clrscr(); printf("\n\n\n\n\n"); printf("\n\t STRUCT_ELEMENT VALUE \t MEMORY_LOCATION\n\n\n"); printf("\t b.name \t %s \t %u (1 byte)\n\n",b.name,&b.name); printf("\t b.price \t %f \t %u (4 bytes)\n\n",b.price,&b.price); printf("\t b.pages \t %d \t %u (2 bytes)\n\n",b.pages,&b.pages); getch(); } |
Here, the program output (in memory) may be as follows according to the size of the data type.
STRUCT_ELEMENT | VALUE | MEMORY_LOCATION |
b.name | SARASWATHY | 65484 (1 byte) |
b.price | 81.250000 | 65486 (4 bytes) |
b.pages | 408 | 65490 (2 bytes) |
ARRAY OF STRUCTURES:
In above program, to store data of 100 books, we would be required to use 50 different structure variables from b1 to b50, which is definitely not very convenient. A better approach would be to use an array of structures.
Following program shows how to use an array of structures. /*
/* EX-55: USAGE OF AN ARRAY OF STRUCTURES */ |
#include<string.h> main() { struct employee { int empno; char name[50]; int salary; }; struct employee e[3]; int i; clrscr(); for(i=0;i<=2;i++) { printf("\nEnter Emp.no, Name and Salary:\n"); scanf("%d %s %d", &e[i].empno,&e[i].name,&e[i].salary); /* scanf("\n%d",&e[i].empno); scanf("\n%s",&e[i].name); scanf("\n%d",&e[i].salary);*/ } for(i=0;i<=2;i++) printf("\n %d \t %s \t %d", e[i].empno, e[i].name, e[i].salary); getch(); } |
COPYING BETWEEN STRUCTURE:
The values of a structure variable can be assigned to another structure variable of the same type using the assignment operator. It is not necessary to copy the structure elements in field-wise (piece-meal copying). Obviously, programmers prefer assignment to piece-meal copying. The following program shown, copying between field-wise as well as record-wise.
/* EX-56: COPYING BETWEEN STRUCTURE */ |
main() { struct employee { char name[20]; int age; float salary; }; struct employee e1 = { "MANICKAM", 10, 7584.75 }; struct employee e2,e3; clrscr(); /* Copying Fieldwise */ strcpy(e2.name,e1.name); e2.age=e1.age; e2.salary=e1.salary; /* Copying Recordwise */ e3=e2; printf("\n\tORIGINAL VALUE : %s %d %f", e1.name,e1.age,e1.salary); printf("\n\tAFTER COPIED FIELDWISE : %s %d %f", e2.name,e2.age,e2.salary); printf("\n\tAFTER COPIED RECORDWISE: %s %d %f", e3.name,e3.age,e3.salary); getch(); } |
NESTED STRUCTURES: One structure can be nested within another structure. Using this facility complete data types can be created. The following program shows nested structures.
/* EX-57: PGM ILLUSTRATES NESTED STRUCTURES */ |
main() { struct emp { char *name; struct emp_add { int no; char *street; char *area; long int pincode; }add; char *desig; float salary; }; struct emp e={"KISHORE",98,"KOIL STREET","ERASAI",625515,"PROGRAMMER",12560.75}; clrscr(); printf("\n\t Name = %s",e.name); printf("\n\t No = %d",e.add.no); printf("\n\t Street = %s",e.add.street); printf("\n\t Area = %s",e.add.area); printf("\n\t PINCode = %ld",e.add.pincode); printf("\n\t Designation = %s",e.desig); printf("\n\t Salary = %0.2f",e.salary); getch(); } |
NOTE:
%ld is an access specifier for long integer.
UNIONS
Union is a concept derived from structures and therefore follows the same syntax as structures. However, there is major distinction between them in terms of storage. In structures, each member has its own storage location, whereas all the members of a union use the same location. This implies that, although a union may contain many members of different types, it can handle only one member at a time. Like structures, a union can be declared using the keyword union as follows:union product
{
int pno;
float price;
char code;
}prod;
This declares a variable prod of type union product. The union contains three members, each with a different data type. However, we can use only one of them at a time. This is due to the fact that only one location is allocated for a union variable, irrespective of its size.
The compiler allocates a piece of storage that is large enough to hold the largest variable type in the union. In the declaration above, the member price requires 4 bytes which is the largest among the members. Figure shows how all the three variables share the same address. This assumes that a float variable requires 4 bytes of storage.
/* EX-58: ILLUSTRATING UNION */ |
#include<stdio.h> union course { int major; char minor[10]; }; struct student { char name[20]; int rollno; union course course_no; }student1; main() { char c_name; clrscr(); printf("\n Enter the name of the student: "); scanf("%s",student1.name); fflush(stdin); printf("\n Enter the roll no. of the student: "); scanf("%d",&student1.rollno); fflush(stdin); printf("\n Enter the course ('M' for major or 'm' for minor): "); scanf("%c",&c_name); fflush(stdin); if(c_name=='M') { printf("\n Enter the course('1' or '2'): "); scanf("%d",&student1.course_no.major); fflush(stdin); } else strcpy(student1.course_no.minor,"others"); printf("%s",student1.course_no.minor); getch(); } |