Pages

Friday, February 12, 2010

Nested structure

What is a nested structure ?


A nested structure is a structure defined inside another structure. We have already learnt about nested if’s and nested loops. In case you have skipped it let’s do a quick revision. A nested if is “an if inside another if” and a nested loop is “a loop inside another loop”. for example a nested if will look like this

if(condition 1)


{


                     if(condition 2)


                    {


                   }


                 else


               {


              }


}


else

And this is a nested for loop

for(i=0;i<10;i++)


{


for(j=0;j<4;j++)


{


}


}

As you can see in both the codes above one if (or for) is purely inside the other that’s why it is called nested. We can also create nested structures in the same way where one structure will be written completely inside the other.

Why are they used ?

The simplest answer of this question is REUSABILITY. A nested structure helps us to reuse the properties of an existing structure from other structrure. The main benefit that we will get is that we won’t have to re declare all those variables again which cut the memory needs of the program not to mention saving of time and effort. Let’s see how it works

A school wants to maintain data of its teachers and students. Following is the information that we want to maintain.

Teachers : name,address,teleno,qualification, salary and date of joining.


Students : name,father’s name, address,teleno, and class.

As you can see some properties of both the persons (name,address and teleno) are same while some of them are different. if we create structures of the above entities we will have to write the code twice, once each for students and teachers. This will demand not only more resources but also time and effort of the programmer. Let’s see the incorrect version first and then we will jump to the correct one.

Example 1 : creating 2 different structures from scratch.

struct students


{


char name[20];


char fname[20];


char address[30];


long teleno;


int clas;


};


struct teachers


{


char name[20];


char address[30];


long teleno;


int salary;


char doj[12];


};



Going by the above structures is quite clear that we have 3 variables declared in both the structures. Imagine what would happen if there are many more variables that are common like (height, weight, blood group etc.). it can also happen that we want to store data of non teaching staff separately what will happen then ? we will have to create dozens of variables for each teachers,students, and non teachers. This is definitely going to create chaos since managing so many variables is not easy. Declaring same variables again and again will also create inconsistency in all the structures. for example somewhere we have created the address variable with a size of 30 and at some other place we can give the size as 20. This will cause problems later on if we try to copy the strings and do some processing that involve different size strings. Let’s recreate the structures now using the nest concept to see if it helps.

Step 1 : Create a structure that will contain the common variables.

struct person


{


char name[20];


char address[30];


long teleno;


};

Step 2 : Create another structures that will use the above structure.

struct students


{


person stud_data; //using person as a datatype


char fname[20];


int clas;


}

Step 3 : Create an object of the second structure and intiailsize the properties.

students mystudents; // creating an object


printf(“\nEnter name : “);


scanf(“%s”,&mystudents.stud_data.name);


printf(“\nEnter address : “);


scanf(“%s”,&mystudents.stud_data.address);


printf(“\nEnter teleno : “);


scanf(“%ld”,&mystudents.stud_data.teleno);


printf(“\nEnter father’s name : “);


scanf(“%s”,&mystudents.stud_data.fname);


printf(“\nEnter class : “);


scanf(“%d”,&mystudents.stud_data.clas);



The complete code

struct person


{


char name[20];


char address[30];


long teleno;


};


struct students


{


person stud_data; //using person as a datatype


char fname[20];


int clas;


}


struct teachers


{


person tdetails;


char quail[10];


int salary;


char doj[12];


};


void main()


{


students mystudents; // creating an object of students


teachers myteachers; // creating an object of teachers






printf(“\nENTER STUDENT’s DATA”);


printf(“\nEnter name : “);


scanf(“%s”,&mystudents.stud_data.name);


printf(“\nEnter address : “);


scanf(“%s”,&mystudents.stud_data.address);


printf(“\nEnter teleno : “);


scanf(“%ld”,&mystudents.stud_data.teleno);


printf(“\nEnter father’s name : “);


scanf(“%s”,&mystudents.fname);


printf(“\nEnter class : “);


scanf(“%d”,&mystudents.clas);






printf(“\nENTER TEACHER’s DATA”);


printf(“\nEnter name : “);


scanf(“%s”,&myteachers.tdetails.name);


printf(“\nEnter address : “);


scanf(“%s”,&myteachers.tdetails.address);


printf(“\nEnter teleno : “);


scanf(“%ld”,&myteachers.tdetails.teleno);


printf(“\nEnter qualification : “);


scanf(“%s”,&myteachers.quali);


printf(“\nEnter date of joining : “);


scanf(“%s”,&myteachers.doj);






printf(“\n DATA ENTRY COMPLETE. NOW PRINTING DATA…”);

printf(“\nPRINTING STUDENTS DATA”);


printf(“\n-+-+--+-+--+-+--+-+--+-+--+-+--+-+-“);// just a separator, can be skipped


printf(“\nName : %s”,mystudents.stud_data.name);


printf(“\nAddress : %s”,mystudents.stud_data.address);


printf(“\nTeleno : %ld”,mystudents.stud_data.teleno);


printf(“\nFather’s name : %s”,mystudents.fname);


printf(“\nClass : %d”,mystudents.clas);






printf(“\nPRINTING TEACHERS DATA”);


printf(“\n-+-+--+-+--+-+--+-+--+-+--+-+--+-+-“);


printf(“\nName : %s”,myteachers.tdetails.name);


printf(“\nAddress : %s”, myteachers.tdetails.address);


printf(“\nTeleno : %ld”, myteachers.tdetails.teleno);


printf(“\nQualification : %s”, myteachers.quali);


printf(“\nDate of joining : %s”, myteachers.doj);


}

Description

In the above code firstly we have created a structure named “person” which houses the common properties of both students and teachers. The second structure named “students” then uses the “person“ structure as a datatype (don’t forget structures are user defined datatypes). The statement “person stud_data” denotes that the variable “stud_data” has its datatype as “person”. This allows the “students” structure to access the properties of the person structure using a special syntax which is “objectname.variablename.parentvariablename”. the student structure has just three member variables of its “own” – stud_data, fname and clas but since it has a reference of the person structure inside, it can also access person’s variables also.

Creating multiple objects

Once we have created a structure we can declare as many objects as we want based on the structure. How many objects will be created solely depends how many records do you want to store. for example to maintain records/data of 20 doctors you can create 20 objects.

Method 1 : Creating individual objects

Example 2 : Storing multiple records

struct doctors
{
char name[20],qualification[10];
int exp,surgeries;
}
void main()
{
doctors doc1,doc2,doc3; // to store data of 3 doctors
printf(“\nEnter Details Of The First doctor “);
printf(“\nName : “);
gets(doc1.name); // to let the user enter spaces
printf(“\nQualification : “);
scanf(“%s”,&doc1.qualification);
printf(“\nExperience in years : “);
scanf(“%d”,&doc1.exp);
printf(“\nEnter surgeries performed : “);
scanf(“\n%d”,&doc1.surgeries);
printf(“\nEnter Details Of The Second doctor “);
printf(“\nName : “);
gets(doc2.name);
printf(“\nQualification : “);
scanf(“%s”,&doc2.qualification);
printf(“\nExperience in years : “);
scanf(“%d”,&doc2.exp);
printf(“\nEnter surgeries performed : “);
scanf(“\n%d”,&doc2.surgeries);
printf(“\nEnter Details Of The Third doctor “);
printf(“\nName : “);
gets(doc3.name);
printf(“\nQualification : “);
scanf(“%s”,&doc3.qualification);
printf(“\nExperience in years : “);
scanf(“%d”,&doc3.exp);
printf(“\nEnter surgeries performed : “);
scanf(“\n%d”,&doc3.surgeries);

printf(“\nList of doctors entered “);
printf(“\nDOCTOR 1”);
printf(“\nName of the doctor : %s”,doc1.name);
printf(“\nQualification : %s”,doc1.qualification);
printf(“\nExperience in years : %d”,doc1.exp);
printf(“\nSurgeries performed : %d”,doc1.surgeries);
printf(“\nDOCTOR 2”);
printf(“\nName of the doctor : %s”,doc2.name);
printf(“\nQualification : %s”,doc2.qualification);
printf(“\nExperience in years : %d”,doc2.exp);
printf(“\nSurgeries performed : %d”,doc2.surgeries);
printf(“\nDOCTOR 3”);
printf(“\nName of the doctor : %s”,doc3.name);
printf(“\nQualification : %s”,doc3.qualification);
printf(“\nExperience in years : %d”,doc3.exp);
printf(“\nSurgeries performed : %d”,doc3.surgeries);
}


 
Description
In the above code we have created three objects namely doc1,doc2 and doc3 to store data of 3 doctors. Each doctor has a name, qualification, experience and surgeries as their properties. To accept the data we have used multiple printf,scanf statements so that the records can be stored. When we use individual objects like doc1,doc2 etc. we will have to write many printf/scanf statements to input and output data. Of course, the program will work fine but won’t this method make it too lengthy if data of more doctors needed to be added.



Method 2 : Creating array object

Example 3 : Storing multiple records using an array object

struct doctors
{
char name[20],qualification[10];
int exp,surgeries;
}
void main()
{
doctors doc[5]; // an array of 5 doctors.
int I;
//Getting the input
for (i=0;i<5;i++) { printf(“\nEnter Name “); scanf(“%s”,&doc[i].name); printf(“\nEnter Qualification “); scanf(“%s”,&doc[i].qualification); printf(“\nEnter Experience “); scanf(“%d”,&doc[i].exp); printf(“\nEnter surgeries performed : “); scanf(“%d”,&doc[i].surgieries); } //Printing the output for(i=0;i<5;i++) { printf(“\nName : %s”,doc[i].name); printf(“\nQualification : %s”,doc[i].qualification); printf(“\nExperience : %d”,doc[i].experience); printf(“\nSurgeries : %d”,doc[i].surgeries); printf(“\n==========================”);// will act as a separator between 2 records. }


Description :The above code instead of creating individual objects creates an array of 5 objects. As far as memory is concerened creating an array of 5 objects will require the same amount of memory as 5 individual objects but the main benefit in creating the array is that the effort required in writing in printf/scanf statements has be largely reduced. The use of loop has made the program easier to write and not to mention has made it shorter.
When the statement “doc[5]” is compiled it creates an array of type “doctors”. Remember that a structure is a user defined data type therefore the array is capable of storing “name,qualification,expereicne and surgeries of doctor per index/element. It can be said that the array has a name,qualificaition, experience and surgeries variables in each of the 5 indexes. So the name of the first doctor is stored in index no [0], second doctor’s name is stored in index no[1] and so on. The loop stores the first set of data in the index no [0] and the last record is stored in index [4].
It is not necessary that all the records are printed. if we want to print a particular record it is fairly easy to do so. Consider the following code snippet which can be appended to the above example.


int no;
printf(“\nEnter record number to be displayed : “);
scanf(“%d”,&no);
if(no<1>5)
printf(“\nInvalid record no. Enter a value between 1 and 5 “);
else
{
printf(“\nName : %S”,doc[no-1].name);
printf(“\nQualification : %s”,doc[no-1].qualifcation);
printf(“\nExperience : %d”,doc[no-1].exp);
printf(“\nSurgeries : %d”,doc[no-1].surgeries);
}


Description
The values are stored in the array from index no. 0 to index no. 4 but the user is not aware that the values start from 0. for the end user the data is stored from record number 1 to 5 therefore when asked to enter the desired record number he/she will enter a value from 1 to 5 and not 0 to 4 since he/she is not familiar with the concept of programming or arrays. if a number less than 1 or more than 5 is entered the program will display an error message reading “Invalid record no. Enter a value between 1 and 5”, but if the value falls between the range(1-5) the code given in the else part will display the data of that particular doctor by subtracting 1 from the entered value. for example if the user enters 3 to view the data of the third doctor, the third record is stored in the index no. 2 (since array start from 0) therefore subtracting 1 from the user value will take us to index no 2 which is the desired record.

Example 3 : Performing calculations in a structure.


All the program created till now were examples of basic input/output. The data that was being entered by the user was shown back without much of processing. The example given below is slightly different. It will ask the user to enter some data and will calculate the remaining values based on those values.



struct products


{


int prodno,price,qty,discount,total,net;


}


void main()


{


products prod[10];


int I;


for(i=0;i<10;i++)


{


printf(“\nEnter Product No. “);


scanf(“%d”,&prod[i].prodno);


printf(“\nEnter maximum retail price :”);


scanf(“%d”,&prod[i].price);


printf(“\nEnter Quantity Purchased : “);


scanf(“%d”,&prod[i].qty);


prod[i].total=prod[i].price*prod[i].qty;


prod[i].discount=prod[i].total*3/100;


prod[i].net=prod[i].total-prod[i].discount;


}


printf(“\n NOW PRINTING DATA “);


for(i=0;i<5;i++)


{


printf(“\nProduct No. %d”,prod[i].prodno);


printf(“\nPrice %d”,prod[i].price);


printf(“\nQuantity %d”,prod[i].qty);


printf(“\nTotal %d”,prod[i].total);


printf(“\nDiscount %d”,prod[i].dis);


printf(“\nNet Payable %d”,prod[i].net);


}


}



Description

The user is prompted to enter product no,price and quantity only. The rest of the values are then calculated using basic formulas like total is price *qty, discount is calculated at 3% of total and net amount is total – discount. It is evident from the code that it is not necessary that all the values must be entered by the user only. Some values are entered by the user and remaining are determined by applying simple calculations.

Each product has six properties namely , product no (prodno), price (price), quantity(qty),total(total),discount(dis) and net payable (net). There are five products which are stored in the form of an array from 0 till 4. Each index of the array has all the six properties mentioned above. Which means that the “prodno” of the first product will be called “prod[0].prodno” where “prod” is name of the array, [0] is the index no, and prodno is the name of the structure variable. Similarly the second “prodno” will be called prod[1].prodno and so on. The easiest way to access all these values is by using a loop from 0 to 4 which will ask the user to enter the values to the array. Values like prodno and price are entered directly by the user whereas the other ones are calculated by the program itself.