Structures and Unions

Oracle Certification Program Candidate GuideStructures and Unions

The structure is a commonly used data structure in C programming language. Unlike the data structure arrays, whose elements are all of the same data type, the structure may comprise of individual elements of different data types. Thus, a single structure may contain integer, float and character elements. A structure can contain elements of type pointer, arrays and even structures too. The individual structure elements are referred to as members. That is why a structure declaration includes the definition of each of its members that constitute the structure.

10.1 STRUCTURE DECLARATION

The composition of a structure may be defined as follows,

struct tag {

member 1;

member 2;

:

:

member n;

};

In this declaration, the keyword struct declares a structure of type tag and member 1, member 2 till member n are the members of the structure. Two members of the same structure however, cannot have a common name. Moreover, separate storage classes cannot be assigned to the members. The storage class if defined for the structure applies to all its elements. Again, the elements of a structure cannot be independently initialised.

The structure declaration defines a structure type tag (with a tag name) that is simply a template for which no memory has been allocated. To create variables (for which memory space would be allocated) of the structure tag type the following declaration can be used.

struct tag variable 1, variable 2,......, variable n;

To get a more clear idea let us discuss some examples on structure,

Example 10.1 :

struct student {

int enrolment_no;

char name[21];

char course_name[11];

float module_marks[4];

char grade;

};

struct student medical, engineering;

Here the structure student consists of five members such as enrolment number (of integer type), name (character string), course name (which is a string of length 10), marks (a floating point array that maintains marks attained in four lecture modules) and grade. Two variables are defined as medical and engineering of type student. The above declaration could also have been written in the following way :

struct student {

int enrolment_no;

char name[21];

char course_name[11];

float module_marks[4];

char grade;

} medical, engineering;

Now each member of the structure student can be accessed using the variable name (since memory space has been allocated only for the variables) followed by the member name separated by a period (variable.member) e.g. medical.enrolment_no. The period operator (.) is a member of the highest precedence group. Similarly the marks for the second module of an engineering student can be referred to by engineering.module_marks[1].

The members of a structure can be assigned some initial values in a manner similar to the way we did it, in case of an array. A structure variable can be initialised only if its storage class is either extern or static.

static struct student medical={

10001, “Rakesh Mishra”, “MBBS”,99.00,78.50,67.77, ‘B’

};

As we have mentioned before, a structure member can again be of type structure.

struct name {

char first_name[21];

char middle_name[21];

char last_name[21];

};

struct student {

int enrolment_no;

struct name stud_name ;

char course_name[11];

float module_marks[4];

char grade;

} medical, engineering;

It is also possible to define an array of structures where each element of the array is a structure. To declare an array of 4 students of structure student type the following declaration can be used.

struct student all_students[4];

In order to access the details of the first student which happens to be the first element (element 0) of the array of structures (all_students) we can use the following combinations of variable and member names.

all_student[0].enrolment_no - refers to the enrolment_no of the students

all_student[0].stud_name.first_name - refers to the first name

The array of structures can be assigned some initial values in the following manner.

static struct student some_students[] ={

10002, “Subir”, “Kumar”, “Roy”, “Computer”, 100.00, 99.56, 89.99, “A’,

10003, “Sunirmal”, “ ”, “ Mitra”, “Civil”, 95.78, 76.55, 90.00, ‘B’

};

1. Match the followings :

a. Structure i) is a keyword used for declaring a structure

b. Array ii) consists of elements of different data types

c. struct iii) returns the amount of memory space occupied by its parameter

d. Member iv) consists of homogenous elements

e. sizeof v) constituents of a structure

2. Identify errors(if any) in the following C program:

# include

struct employee{

char name[31];

char dept[21];

float basic;

};

struct employee *record;

main()

{

printf(“\nEnter name :”);

gets(record.name);

printf(“\nEnter department :”);

gets(record.dept);

printf(“\nEnter basic :”);

scanf(“%f”,&record.basic);

}


10.2 POINTERS TO STRUCTURES

One can declare pointers which can point to a structure. The syntax for such a declaration is given below :

*ptvar;

Example 10.2 :

typedef struct {

char first_name[21];

char middle_name[21];

char last_name[21];

}name;

typedef struct {

name *sname;

int roll.no;

float score;

char grade[3];

} student;

struct student *ps,a; /* here a is a variable for which memory is allocated to accommodate student information; ps is a pointer to a structure but not having any valid address to point to */

The proper initialisation of the pointer variable ps with valid memory space can be performed by assigning the address of a structure variable e.g.,

ps=&a;

Alternatively ps can be assigned a valid address using the malloc function.

ps=(student *) malloc (sizeof (student));

A member of the student structure, can be located by the pointer variable, followed by the symbol (->) and the member name, e.g.,

ps->score /* to access score */

Since sname is a pointer to typedef structure name, memory space need to be allocated for that variable also.

ps->sname=(name *) malloc(sizeof(name));

In the above statement, the malloc allocates memory space having size equal to the size of the structure name. The type casting of the output of the function malloc to student type ((student*)) ensures proper initialisation of the pointer ps.

Example 10.3 :

/* read student information and print the same */

# include

main()

{

int i,j;

float x,y;

char a;

typedef struct {

char name[26];

char roll_no[8];

float sgpa[8];

float cgpa[8];

}stud_rec;

stud_rec *std;

std=(stud_rec *)malloc(sizeof(stud_rec));

printf(“\nEnter the name of the student :”);

for(i=0;(a=getchar()) != ‘\n’;std->name[i++]=a);

std->name[i]=‘\0’;

printf(“\nEnter the roll number of the student :”);

for(i=0;(a=getchar()) != ‘\n’;std->roll_no[i++]=a);

std->name[i]=‘\0’;

printf(“\nEnter the number of semesters :”);

scanf(“%d”,&j);

fflush(stdin);

for(i=0;i <>

{

scanf(“%f”,&(std->sgpa[i]));

fflush(stdin);

}

for(x=0.0,i=0;i <>

{

x += (std->sgpa[i]);

cgpa[i]= x / (i + 1);

printf(“The CGPA in Sem. %d is %5.2f\n”,i+1,std->cgpa[i]);

i++;

}

}

3. Identify errors(if any) in the following C program:

# include

struct employee{

struct emp_name *name;

char dept[21];

float basic;

};

struct emp_name{

char first_name[21];

char mid_name[21];

char last_name[21];

};

struct employee *record;

main()

{

char rep=‘y’;

do{

record=malloc(sizeof(employee));

printf(“\nEnter first name :”);

gets(record.name->first_name);

printf(“\nEnter middle name :”);

gets(record.name->mid_name);

printf(“\nEnter last name :”);

gets(record.name->last_name);

printf(“\nEnter department :”);

gets(record.dept);

printf(“\nEnter basic :”);

scanf(“%f”,&record.basic);

printf(“\nEnter reply :”);

rep=getchar();

}while(rep == ‘y’);

}


10.3 UNIONS IN C

Unions are structures that contain members whose individual data types may differ from one another. Moreover, the members that comprise a union share the same storage area. Thus if we consider the structure to be a road map to access memory of the computer for storing and accessing data objects, then a union provides various road maps for the same memory space.

Let us consider an example that illustrates the usage of unions. Here we need to store student information (student record), that consists of two parts, fixed and variable. For every student, name, roll number, grade and status form the fixed part, whereas the variable data is an union of jee_marks and gate_score depending on whether the student is a undergraduate student or a graduate student. Thus only one of the members of the union can be accessed at a given point of time depending on the status of the student (status is ‘G’ for graduates, ‘U’ for undergraduates). For students who have already graduated gate_score is to be considered, while jee_marks is considered of undergraduates. Though union may consist of two members of different data types, the memory space of same size is always reserved. The memory space allocated (reserved) equals to the size of the member whose storage space requirement is maximum among all the members in the union.

Example 10.4 :

typedef struct {

char first_name[21];

char middle_name[21];

char last_name[21];

}name;

struct student {

name student_name;

int roll-no;

float grade;

char status;

union {

int jee_marks;

float gate_score;

} level;

} a,b,c;

A group of contiguous structures as elements including unions can be implemented using arrays. The declaration,

struct student {

:

} class [50];

defines an array class of 50 students.

Example 10.5 :

/demonstration of array of structures that include unions */
# include

#define MAX_SUB 100

struct pname{

char fname[21];

char lname[21];

};

struct oname {

char orgname[31];

};

struct tele{

char sub_type; /* ‘P’ for person; ‘O’ for organisation */

union {

struct pname pn;

struct oname on;

}p_or_o;

char address[31];

int no_connections;

char (*telephones)[8];

};

struct tele subscriber[MAX_SUB];

main()

{

int no_sub=0,connections=0;

char rep=‘Y‘;

do{

printf(“\nEnter subscriber’s type (P/O) :”);

scanf(“%c”,&subscriber[no_sub].sub_type);

fflush(stdin);

switch(subscriber[no_sub].sub_type)

{

case ‘P’ :

printf(“\nEnter First name :”);

gets(subscriber[no_sub].p_or_o.pn.fname);

fflush(stdin);

printf(“\nEnter Last name :”);

gets(subscriber[no_sub].p_or_o.pn.lname);

fflush(stdin);

break;

case ‘O’ :

printf(“\nEnter Organisation name :”);

gets(subscriber[no_sub].p_or_o.on.orgname);

fflush(stdin);

break;

default :

printf(“|nWrong subscriber type entered\n”);

continue;

}

printf(“\nEnter address :”);

gets(subscriber[no_sub].address);

fflush(stdin);

printf(“\nEnter number of connections :”);

scanf(“%d”,&subscriber[no_sub].no_connections);

fflush(stdin);

if(sub[no_sub].no_conn > 0)

{

printf(“\nEnter Telephone numbers :”);

printf(“Maximum number of connections %d\n”, subscriber[no_sub].no_connections);

printf(“Enter 0 to finish entering telephone numbers...\n”);

*(subscriber[no_sub].telephones)=(char *)malloc(no_connections* 8);

connections=-1;

do{

connections++;

printf(“\nConnection number %d :”,connections + 1);

scanf(“%s”,subscriber[no_sub].telephones[connections]);

fflush(stdin);

} while(connections != (no_connections - 1) && *(*(subscriber[no_sub].telephones + connections)) != ‘0’);

}

no_sub++;

printf(“\nDo you want to continue ?”);

rep=getchar();

fflush(stdin);

}while((rep == ‘y’ || rep == ‘Y’) && (no_sub <>

}

4. Identify errors(if any) in the following C program:

# include

struct temporary{

int year_contract;

float annual_salary;

float annual_benefits;

};

struct permanent{

float basic;

float hra_rt;

float ded_rt;

};

struct emp_name{

char first_name[21];

char mid_name[21];

char last_name[21];

};

struct employee{

struct emp_name *name;

char dept[21];

char nature_employee;

union{

struct temporary temp_emp;

struct permanent perm_emp;

}t_or_p;

};

struct employee *record;

main()

{

char rep=‘y’;

do{

record=malloc(sizeof(employee));

printf(“\nEnter first name :”);

gets(record.name->first_name);

printf(“\nEnter middle name :”);

gets(record.name->mid_name);

printf(“\nEnter last name :”);

gets(record.name->last_name);

printf(“\nEnter department :”);

gets(record.dept);

printf(“Enter ‘P’ (for permanent employee) or ‘T’ (for temporary employee) :”);

record.nature_employee=getchar();

switch(nature_employee)

{

case ‘T’ :

printf(“\nEnter basic :”);

scanf(“%f”,&record.t_or_p->temp_emp.basic);

printf(“\nEnter house rent allowance rate :”);

scanf(“%f”,&record.t_or_p->temp_emp.hra_rt);

printf(“\nEnter deduction rate :”);

scanf(“%f”,&record.t_or_p->temp_emp.ded_rt);

break;

case ‘P’ :

printf(“\nEnter number of years contracted :”);

scanf(“%f”,&record.t_or_p->perm_emp.year_contract);

printf(“\nEnter annual salary :”);

scanf(“%f”,&record.t_or_p->perm_emp.annual_salary);

printf(“\nEnter annual benefits :”);

scanf(“%f”,&record.t_or_p->perm_emp.annual_benefits);

}

printf(“\nEnter reply :”);

rep=getchar();

}while(rep == ‘y’);

}


10.4 PASSING STRUCTURES AS PARAMETERS TO A FUNCTION

An entire structure or its members can be transferred to as parameters to functions. Such a transfer is done using the call by value scheme. A function can also return an instance of a structure using the return statement.

Example 10.6 :

# include

struct name {

char first_name[21];

char middle_name[21];

char last_name[21];

};

typedef struct {

int enrolment_no;

struct name stud_name ;

char course_name[11];

float module_marks[4];

char grade;

} a;

main()

{

student print_student(student a);

student read_student(student);

student modified_student;

:

:

static student a={ 1234, “MS”, “ ”, “Subhalakshmi”, “Music”, 45, 78, 98, ` 67, ‘A’};

printf(“|nEnrolment no :%d\nFirst name : %s\nMiddle name : %s\nLast name : %s\nCourse name : %s\nGrade : %c\n”,a.enrolment_no, a.stud_name.first_name, a.stud_name.middle_name, a.stud_name.last_name, a.course_name, a.grade);

:

:

a=read_student(a);/* the function read_student is called to read student information */

}

student read_student(student a)

{

scanf(“%d %s %s %s %s %c”,&a.enrolment_no, a.stud_name.first_name, a.stud_name.middle_name, a.stud_name.last_name, a.course_name, &a.grade);

return (a);

}

10.5 PASSING STRUCTURE TO A FUNCTION USING POINTERS

A structure can be transmitted to another function using a pointer which as we have seen earlier implements the call by reference scheme. The address of the structure transmitted by the calling function is received in a pointer to the same type of structure in the called one. The individual structure members are accessed by the pointer variable using the notation, ps->name or (*ps). name in the called function..

Example 10.7 :

/* This program illustrates the transmission of structures using pointers to another function */

# include

typedef struct {

float real;

float imag;

}complex;

complex add_complex(complex,complex);

void read_complex(complex *);

void write_complex(complex);

main()

{

complex a,b,c;

read_complex(&a);

read_complex(&b);

c=add_complex(a,b);

write_complex(c);

}

complex add_complex(complex x,complex y)

{

complex temp;

temp.real=x.real + y.real;

temp.imag=x.imag + y.imag;

return(temp);

}

void read_complex(complex *x)

{

scanf(“%f %f”,&(x->real),&(x->imag));

}

void write_complex(complex x)

{

char c[3]=“+j”;

if(x.imag <>

{

c[0]=‘-’;

x.imag=-x.imag;

}

printf(“%f%s%f”,x.real,c,x.imag);

}

5. For each of following C programs, describe the output that will be generated.

(a)

# include

typedef struct {

char *x;

char *y;

char *z;

} planets;

main( )

{

void f(planets sample);

static planets sample = {“earth”, “mars”, “jupiter”};

printf(“%s %s %s \n”, sample.x, sample.y, sample.z};

f(sample);

printf(“%s %s %s \n”, sample.x, sample.y, smaple.z);

}

void f(planets sample)

{

sample.x = “mercury”;

sample.y = “venus”;

sample.z = “saturn”;

printf(“%s %s %s \n”, sample.x, sample.y, sample.z);

return;

}

(b)

# include

typedef struct {

char *x;

char *y;

char *z;

} planets;

main( )

{

planets f(planets sample);

static planets sample = {“earth”, “mars”, “jupiter”};

printf(“%s %s %s \n”, sample.x, sample.y, sample.z};

sample = f(sample);

printf(“%s %s %s \n”, sample.x, sample.y, smaple.z);

}

planets f(planets sample)

{

sample.x = “mercury”;

sample.y = “venus”;

sample.z = “saturn”;

printf(“%s %s %s \n”, sample.x, sample.y, sample.z);

return(sample);

}

(c) # include

typedef union {

int i;

float f;

}sample;

main( )

{

sample u;

void f( sample u);

u.i = 200;

u.f = 1.6;

f(u);

printf(“%d %f\n”, u.i, u.f);

}

void f (sample x)

{

x.i = 500;

printf(“%d %f \n”, x.i, x.f);

return;

}

0 comments: