Structures in c

Definition: Structure is a collection of one or more variables of different data types, grouped together under a single name.  By using structures we can make a group of variables, arrays, pointers, etc.

Features:

Declaration and Initialization

struct struct_type {
   Type variable1;
   Type variable2;
};
struct book1 {
  char book[30];
  int pages;
  float price;
};
struct book1 bk1;
strcpy(bk1.book, "Lets'c");
bk1.pages=500;
bk1.price=385.00;
struct emp {
  int id;
  char name[25];
  int sal;
} e1={101, "Balu Naik",10000};
struct emp {
   int id;
   char name[25];
   int sal;
}e1={101, "BALU",10000};
void main()
{
   struct emp e2={108,“JEEVAN”,5500};
}

[quote]Note that C language does not permit the initialization of individual structure members within the structure. The initialization must be done only in the declaration of actual variables.[/quote]

An array of structures

An array is a collection of similar data types. In the same way, we can also define an array of structures. In such type of array, elements are of structure type. In the below example t[3] is an array of 3 elements containing three objects of time structure.

struct time {
  int second;
  int minutes;
  int hour;
}t[3];

We use structure to describe the format of related variables. For example, in analyzing the marks obtained by a class of students, we may use a template to describe student name and marks obtained in various subjects and then declare all the students as structure variables. In such cases, we may declare an array of structures, each element of the array representing a structure variable. For example

struct class student[50];

Let’s defines an array called student that consists of 50 elements. Each element is defined to be of the type struct class. Consider the following declaration:

struct MyClass {
  int subject1;
  int subject2;
  int subject3;
};
void main()
{
  struct class students[3] = {
                               {75,85,95},
                               {95,75,85},
                               {99,88,77}
                            };
}

This declaration the student as an array of three elements student[0], student[1], and student[2] and initializes their member as follows:

student[0].subject1=75;

student[0].subject2=85;

student[0].subject3=95;

.................

.................

student[2].student3=77;

[quote]Note that the array is declared just as it would have been, with any other array. Since the student is an array, we use the usual array-accessing methods to access individual elements and then the member operator to access member.[/quote]

Structures within structures

We can take any data type for declaring structure members like int, float, char and etc. in the same way we can also take an object of one structure as a member in another structure. Thus, the structure within the structure can be used to create complex data applications. Structures within a structure mean nesting of structures. Nesting of structures is permitted in C.

struct time
{
  int second;
  int minute;
  int hour;
};
struct t
{ 
   int car;
   struct time st;
   struct time et;
};

Pointers to the structure

We know that pointer is a variable that holds the address of another data variable. The variable may be of any data type i.e. int, float or double. In the same way, we can also define a pointer to structure. Here, starting address of the member variables can be accessed. Thus, such pointers are called structure pointers.

struct book {
  char name[25];
  char author[25];
  int pages;
};
struct book *ptr;

In the above example *ptr is a pointer to structure book. The syntax for using the pointer with the member is as:

Structures and functions

Like variables of standard data type, structure variables also can be passed to the function by value or address. 

/* passing address of structure variable */

#include <stdio.h>
struct book
{
  char name[35];
  char author[35];
  int pages;
};
int main()
{
    struct book b1={"JAVA COMPLETE REFERENCE","P.NAUGHTON",886};
    show(&b1);
    
    return 0;
}

show(struct book *b2)
{
    printf("\n %s by %s of %d pages",b2->name,b2->author,b2-> pages);
}

There are different ways of passing structure type arguments to functions. These are given below:

Self-referential structures

The self-referential structure is one that includes within its structure at least one member which is a pointer to the same structure type. Self-referential structures are mainly used in the implementation of data structures. Ex: linked lists, trees, etc.

struct student
{
   char name[50];
   int rollno;
   struct student *ptr;
};

C programming Union

A union is a variable, which is similar to the structure. It contains the number of members like structure but it holds only one object at a time. In the structure each member has its own memory location whereas, members of unions have the same memory locations. It can accommodate one member at a time in a single area of storage. Union also contains members of types int, float, long, arrays, pointers, etc. it allocates fixed specific bytes of memory for access of data types irrespective of any data type.

Union requires bytes that are equal to the number of bytes required for the largest members. For example, the union contains char, integer, and long integer then the number of bytes reserved in the memory for the union is 4 bytes.

union Declaration

union tag_name  //tag_name is optional
{
  Datatype member1;
  Datatype member2;
  Datatype member n;
};

union member access

Accessing of members of union is done similar to that of structure, it is done by using dot(.) operator for unions and using ‘->’ for a pointer to unions.

union example

union organization
{
  char name[25];
  char designation[10];
  int sal;
};
union organization emp1={"Balu","secretary",8000};
union organization emp2={"gopal","manager",15000};

typedef

It is a keyword by using typedef we can create new data type (Eg: int, pointers, and structures). The declaration for the typedef keyword is

typedef <datatype> <newname>;

Example#1

 // creating new data type 'int'

typedef int integer;

integer x,y,z;

[quote]Now integer is the synonym for ‘int’. integer can be used in declarations.[/quote]

Example#2

// Using typedef for pointers.

typedef int* integer;

integer p1;

This statement makes integer as a data type which is similar to integer pointer (int *).

[quote]Now this integer can be used for the declaration of integer[/quote]

Example#3

 // Using typedef for structures.

typedef struct student* st_pointer;

struct student
{
   char name[50];
   int rollno;
   st_pointer ptr;
};

Bit-fields

Bit field provides the exact amount of bits required for storage of values. A bit-field is a set of adjacent bits within a single machine word. Bit-fields are mainly used to save the memory space or to combine several states of information within a single machine word.

To hold the information we use the variables. The variables occupy a minimum of one byte for char and two bytes for integer. Instead of using complete integer if bits are used, space of memory can be saved.

Declaring structure using bit-fields

struct student
{
  unsigned gender: 1;
  unsigned grade: 2;
};

The colon indicates the usage of bit-fields and the number following it represents (tells to the compiler) the width of the field in bits.

However, there are restrictions on bit fields when arrays are used. Arrays of bit fields are not permitted. Also, the pointer cannot be used for addressing the bit field directly, although the use of the member access operator (->) is acceptable.

Enumerated data type

The enum is a keyword. It is used for declaring enumeration types. The programmer can create his/her own data type and define what values the variables of these data types can hold. This enumeration data type helps in reading the program.

enum month {jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};

This statement creates a user defined data type. The enumerators are the identifiers jan, feb, mar, apr and so on. Their values are constant unsigned integers and start from 0. The identifier jan refers to 0, feb to 1 and so on.

The identifiers are not to be enclosed within quotation marks. Please also note that integer constants are also not permitted.

Advantages of structures over arrays

We can group items of different types within a single entity, which is not possible with arrays, an array stores similar elements. The position of a particular structure type variable within a group is not needed in order to access it, whereas the position of an array member in the group is required, in order to refer to it.

In order to store the data about a particular entity such as a ‘book’, using an array type, we need three arrays; one for storing name, another for price and a third one for the number of pages, etc., hence, the overhead is high. This overhead can be reduced by using structure type variable i.e. array of structures.

Once anew structure has been defined, one or more variables can be declared to be of that type. A structure type variable can be used as a normal variable for accepting the user’s input, for displaying the output, etc.

The assignment of one ‘struct’ variable to another, reduces the burden of the programmer in filling the variable’s fields again and again. It is possible to initialize some or all fields of a structure variable at once when it is declared. Structure type allows the efficient insertion and deletion of elements but arrays cause the inefficiently.

For random array accessing, large hash tables are needed. Hence, large storage space and costs are required. When a structure variable created, all of the member variables are created automatically and are grouped under the given variable’s name.

Structure Vs Union

Structure Union
Declaration

struct tag_name
{
  Data type member1;
  Data type member2;
};

Every structure member is allocated memory when a structure variable is defined.

struct {
  char c;
  int x;
  float y;
}s;

Memory allocated for s is 7 (1+2+4) bytes.

All the members can be assigned values at a time.

Values assigned to one member will not cause the change in other members.

All structure variables can be initialized at a time.

The usage of the structure is efficient when all members are actively used in the program.

Declaration

union tag_name
{
  Data type member1;
  Data type member2;
};

The memory equivalent to the largest item is allocated commonly for all members.

union {
  char c;
  int x;
  float y;
}u;

Memory allocated to us is 4 bytes.

Only one member can be assigned value at a time.

The value assigned to one member may cause a change in the value of other members.

Only one union member can be initialized at a time.

The usage of union is efficient when members of it are not required to be accessed at the same time.

sizeof:

We normally use structures, unions, and arrays to create variables of large sizes. The actual size of these variables in terms of bytes may be change from machine to machine. We may use the unary operator ‘sizeof’ to tell us the size of a structure. The expression sizeof(struct x) will evaluate the number of bytes required to hold all the member of the structure x.