Structures In C Language


A structure is a customised user-defined data type in C. It is by definition a collection of variables of any type that are referenced under one name, providing a convenient means of keeping related information together.

Some terminology :-

structure definition :- the template used to create structure variables.
structure elements :- the member variables of the structure type

Defining Structures

struct  tag   {
   type  var_1 ;
   type var_2 ;
   type var_n ;
 }  ;

The keyword struct tells the compiler we are dealing with a structure and must be present whenever we refer to the new type, tag is an identifier which is the name given to the customised 'type'.

A variable of this new type can now be defined as follows for example. Note that the keyword struct has to be used in conjunction with our own name for the structure, tag.

struct tag variable ; 

For Example :-

struct RECORD {
	int rec_no ;
	char name[30] ;
	char town[40] ;
	char country[ 20 ]
	} ;
struct RECORD person ;

The compiler will automatically allocate enough storage to accommodate all the elements. To find out how much storage is required one might do the following

size = sizeof ( person ) ;
size = sizeof( struct RECORD ) ;

NOTE : The name of a structure is not the address of the structure as with array names.

Accessing Structure Elements:

For example define a complex type structure as follows.

struct complex {
  double real ;
  double imaginary ;        // Note that a variable may also be
} cplx ;                // defined at structure definition time

The elements of the structure are accessed using the dot operator, . , as follows

cplx.real  =  10.0 ;
cplx.imag  =  20.23 ;
scanf ( "%lf", &cplx.real ) ;

or if we want to access struct RECORD already defined

puts( ) ;

or character by character

Syntax[i] = 'a' ;

Thus we treat structure elements exactly as normal variables and view the dot operator as just another appendage like the indirection operator or an array index.

Initialising Structures :

Structure elements or fields can be initialised to specific values as follows :-

struct id {
	char name[30] ;
	int id_no ;
	} ;
struct id student = { "John", 4563 } ;

Structure Assignment:

The name of a structure variable can be used on its own to reference the complete structure. So instead of having to assign all structure element values separately, a single assignment statement may be used to assign the values of one structure to another structure of the same type.

For Example :

struct {
	int a, b ;
	}  x = {1, 2 }, y ;
	y = x ;        // assigns values of all fields in x to fields in y

Creating more Complex Structures with Structures:

Once again emphasising that structures are just like any other type in C we can create arrays of structures, nest structures, pass structures as arguments to functions, etc.

For example we can nest structures as follows creating a structure employee_log that has another structure as one of its members.

struct time {
	int hour ;
	int min ;
	int sec ;
} ;
struct employee_log {
	char name[30] ;
	struct time start, finish ;
	} employee_1 ;

To access the hour field of time in the variable employee_1 just apply the dot operator twice

employee_1.start.hour = 9 ;

Typically a company will need to keep track of more than one employee so that an array of employee_log would be useful.

struct employee_log  workers[100] ;

To access specific employees we simply index using square braces as normal, e.g. workers[10]. To access specific members of this structure we simply apply the dot operator on top of the index.

workers[10].finish.hour = 10 ;

When structures or arrays of structures are not global they must be passed to functions as parameters subject to the usual rules. For example

function1( employee_1 ) ;

implements a call to function1 which might be prototyped as follows

void  function1( struct employee_log emp ) ;

Note however that a full local copy of the structure passed is made so if a large structure is involved memory the overhead to simply copy the parameter will be high so we should employ call by reference instead as we will see in the next section.

Passing an array of structures to a function also follows the normal rules but note that in this case as it is impossible to pass an array by value no heavy initialisation penalty is paid - we essentially have call by reference. For example

function2( workers ) ;

passes an array of structures to function2 where the function is prototyped as follows.

function2( struct employee_log staff[ ] ) ;

Structure Pointers:

As we have said already we need call by reference calls which are much more efficient than normal call by value calls when passing structures as parameters. This applies even if we do not intend the function to change the structure argument.

A structure pointer is declared in the same way as any pointer for example

struct address {
	char name[20] ;
	char street[20] ;
} ;
struct address person ;
	 struct address *addr_ptr ;

declares a pointer addr_ptr to data type struct address.

To point to the variable person declared above we simply write

addr_ptr =  &person ;

which assigns the address of person to addr_ptr.

To access the elements using a pointer we need a new operator called the arrow operator, ->, which can be used only with structure pointers. For example

puts( addr_ptr -> name ) ;

For Example :- Program using a structure to store time values.

#include <stdio.h>
struct time_var {
	int hours, minutes, seconds ;
	} ;
void display ( const struct time_var * ) ;  /* note structure pointer and const */

void main()
struct time_var time ;

time.hours = 12 ;
time.minutes = 0 ;
time.seconds = 0 ;
display( &time ) ;
void display( const struct time_var *t )
printf( "%2d:%2d;%2d\n", t -> hours, t -> minutes, t -> seconds ) ;

Note that even though we are not changing any values in the structure variable we still employ call by reference for speed and efficiency. To clarify this situation the const keyword has been employed.

Dynamic allocation of structures:

The memory allocation functions may also be used to allocate memory for user defined types such as structures. All malloc() basically needs to know is how much memory to reserve.

struct coordinate {
		int x, y, z ;
		} ;
	struct coordinate *ptr ;

	ptr = (struct coordinate * ) malloc( sizeof ( struct coordinate )  ) ;
#structures_in_c_language #structures_in_c # structures_in_c #Accessing_Structure_Elements_in_c #Initialising_Structures_in_c #Structure_Assignment_in_c #Structure_Pointers_in_c #Dynamic_allocation_of_structures_in_c

(New page will open, for Comment)

Not yet commented...