<Previous Lesson

Introduction to Programming

Next Lesson>

Lesson#20

Lesson 20

Summary


1) Structures
- Declaration of a Structure
- Initializing Structures
- Functions and structures
- Arrays of structures
- sizeof operator
2) Sample Program 1
3) Sample Program 2
4) Unions

Structures


Today, we will discuss the concepts of structures and unions which are very interesting
part of C language. These are also in C++. After dilating upon structures, we will move to
the concept of classes, quite similar to ‘structures’.
What a structure is?
We can understand ‘structure’ with the example of students of
a class discussed in some of the earlier lectures. Suppose we have data about students of a
class i.e. name, addresses, date of birth, GPA and courses of study. This information is
related to only a single entity i.e. student. To understand the matter further, we can think
of a car with its specifications like model, manufacturer company, number of seats and so
on. But there is always a requirement in most of our data processing applications that the
relevant data should be grouped and handled as a group. This is what the concept of
structure is. In structure, we introduce a new data type. In the previous lectures, we had
been dealing with int, float, double and char in our programs. You are fully familiar with
Page 240
the term ’strings’ but there is no data type called strings. We have used ‘array of char’ as
strings. While dealing with numbers, there is no built-in mechanism to handle the
complex numbers. This means that there is no data type like complex. The FORTRAN
language (Formula Translation) written for scientific application, has a complex data
type. Therefore, in FORTRAN, we can say complex x; now x is a variable of type
complex and has a real part and an imaginary part. There is no complex data type in C
and C++. While trying to solve the quadratic equation on the similar grounds, we may
have a complex number as answer i.e. if we have to calculate the square root of -1, an
iota (ί) will be used. So the combination of real and imaginary parts is called complex
number. In C, C++ we deal with such situations with structures. So a structure is not
simply a grouping of real world data like students, car etc, it also has mathematical usage
like complex number. The definition of structure is as under:
“A structure is a collection of variables under a single name. These variables can be of
different types, and each has a name that is used to select it from the structure”

Declaration of a Structure:


Structures are syntactically defined with the word struct. So struct is another keyword
that cannot be used as variable name. Followed by the name of the structure. The data,
contained in the structure, is defined in the curly braces. All the variables that we have
been using can be part of structure. For example:
struct student{
char name[60];
char address[100];
float GPA;
};
Here we have a declared a structure, ‘student’ containing different elements. The name of
the student is declared as char array. For the address, we have declared an array of
hundred characters. To store the GPA, we defined it as float variable type. The variables
which are part of structure are called data members i.e. name, address and GPA are data
members of student. Now this is a new data type which can be written as:
student std1, std2;
Here std1 and std2 are variables of type student like int x, y; x and y in this case are
variables of int data type. This shows the power of C and C++ language and their
extensibility. Moreover, it means that we can create new data types depending upon the
requirements. Structures may also be defined at the time of declaration in the following
manner:
struct student{
char name[60];
char address[100];
Page 241
float GPA;
}std1, std2;
We can give the variable names after the closing curly brace of structure declaration.
These variables are in a comma-separated list.
Structures can also contain pointers which also fall under the category of data type. So we
can have a pointer to something as a part of a structure. We can’t have the same structure
within itself but can have other structures. Let’s say we have a structure of an address. It
contains streetAddress like 34 muslim town, city like sukhar, rawalpindi, etc and country
like Pakistan. It can be written in C language as:
struct address{
char streetAddress[100];
char city[50];
char country[50];
}
Now the structure address can be a part of student structure. We can rewrite student
structure as under:
struct student{
char name[60];
address stdAdd;
float GPA;
};
Here stdAdd is a variable of type Address and a part of student structure. So we can have
pointers and other structures in a structure. We can also have pointers to a structure in a
structure. We know that pointer hold the memory address of the variable. If we have a
pointer to an array, it will contain the memory address of the first element of the array.
Similarly, the pointer to the structure points to the starting point where the data of the
structure is stored.
We have used the card-shuffling example before. What will be the structure of card? Its
one attribute may be the suit i.e. spades, clubs, diamonds or hearts. The second attribute
is the value of the card like ace, deuce, 3 up to king. The structure of card contains a char
pointer to suit and a char pointer to value i.e.
struct card {
char *suit;
char *value;
};
card card1, card2;
Page 242
We have defined card1 and card2 of type card. We can also define more cards. There are
also arrays of structure. The syntax is same as with the normal data type. So a set of cards
or an array of hundred students can be defined as under:
card fullSet[52];
student s[100];
The pointers to structure can be defined in the following manner i.e.
student *sptr;
Here sptr is a pointer to a data type of structure student. Briefly speaking, we have
defined a new data type. Using structures we can declare:
Simple variables of new structure
Pointers to structure
Arrays of structure
There are also limitation with structures as we can not say card1 + card2; As the
operator plus (+) does not know how to add two structures. We will learn to overcome
these limitations at the advanced stage. On the other hand, assignment of structures
works. Therefore if s1 and s2 are of type student structure, we can say that s1 = s2. The
assignment works because the structure is identical. So the name will be copied to the
name
, address to address and so on. If we want to display the structure with cout, it will
also work. The cout is a very intelligent function as it interprets the structure besides
showing the output.

Initializing Structures


We have so far learnt how to define a structure and declare its variables. Let’s see how
can we put the values in its data members. The following example can help us understand
the phenomenon further.
struct student{
char name[64];
char course[128];
int age;
int year;
};
student s1, s2, s3;
Once the structure is defined, the variables of that structure type can be declared.
Initialization may take place at the time of declaration i.e.
student s1 = {“Ali”, “CS201”, 19, 2002 };
Page 243
In the above statement, we have declared a variable s1 of data type student structure and
initialize its data member. The values of data members of s1 are comma separated in
curly braces. “Ali” will be assigned to name, “CS201” will be assigned to the course, 19
to age and 2002 to year. So far we have not touched these data members directly.
To access the data members of structure, dot operator (.) is used. Therefore while
manipulating name of s1, we will say s1.name. This is a way of referring to a data
member of a structure. This may be written as:
s1.age = 20;
s1.year = 2002;
The above statement will assign the value 20 to the age data member of structure s1. Can
we assign a string to the name of s1? Write programs to see how to do this? You may
need string copy function to do this. Also, initialize the pointers to structure and see what
is the difference.
Similarly, to get the output of data members on the screen, we use dot operator. To
display the name of s1 we can write it as:
cout << “The name of s1 = “ << s1.name;
Other data members can be displayed on the screen in the same fashion.
Here is a simple example showing the initialization and displaying the structure.
/* Simple program showing the initialization of structure.*/
#include <iostream.h>
main()
{
// Declaring student structure
struct student{
char name[64];
char course[128];
int age;
int year;
};
// Initializing the structure
student s1 = {"Ali", "CS201- Introduction to programming", 22, 2002};
cout << "Displaying the structure data members" << endl;
cout << "The name is " << s1.name << endl;
cout << "The course is " << s1.course << endl;
cout << "The age is " << s1.age << endl;
cout << "The year is " << s1.year << endl;
}
Page 244
The output of the above program is:
Displaying the structure data members
The name is Ali
The course is CS201- Introduction to programming
The age is 22
The year is 2002
Here, s1 is a unit. The data members have been grouped together. If we have s1 and s2 as
two variables of student type and want to copy the data of s1 to s2, it can be written as:
s2 = s1;

Functions and structures


We can pass structures to functions. Structures are passed into functions as per the C/C++
calling conventions by value. In other words, a copy of entire structure is put on the
stack. The function is called which removes it from the stack and uses the structure. We
can also pass the structures by reference to function. This can be performed in the same
way we do with the normal variables i.e. pass the address of the structure to the function.
This is call by reference.
When we pass an array to a function, the reference of the array is passed to the function.
Any change in the array elements changes the original array. Suppose we have a structure
containing an array. What will happen to the array if the structures are passed as value? Is
the array passed as value or reference? As the array is a part of structure, it will be passed
as value. The advantage of ‘pass by value’ process is that if the function makes some
changes to the array elements, it does not affect the original array. However, it may be
disadvantageous as the complete array is copied on the stack and we can run out of
memory space. So be careful while passing the structures to functions. We know that
functions return value, int, char etc. Similarly functions can also return structures. In a
way, the behavior of structure is same as ordinary data type.
Suppose we have a pointer to structure as student *sptr; here sptr is a pointer to student.
Now s1 is a variable of type student and sptr = &s1 and sptr is pointing to s1. How can
we access the data with sptr? We cannot say *sptr.name. The precedence of dot operator
(.) is higher than * operator. So dot operator is evaluated first and then * operator. The
compiler will give error on the above statement. To get the results, we have to evaluate *
operator first i.e. (*sptr).name will give the desired result. There is another easy and short
way to access the structure’s data member i.e. using the arrow (->) in place of dot
operator. We normally use the arrow (-> i.e. minus sign and then the greater than sign) to
manipulate the structure’s data with pointers. So to access the name with sptr we will
write:
sptr->name;
Page 245
Remember the difference between the access mechanism of structure while using the
simple variable and pointer.
While accessing through a simple variable, use dot operator i.e. s1.name
While accessing through the pointer to structure, use arrow operator i.e. sptr-
>name;
Following is the example, depicting the access mechanism of structure’s data member
using the pointer to structure.
The code of the sample example is:
/* This program shows the access of structure data members with pointer to structure */
#include <iostream.h>
main()
{
// Declaration of student structure
struct student{
char name[64];
char course[128];
int age;
int year;
};
// Initializing the s1
student s1 = {"Ali", "CS201- Introduction to programming", 22, 2002};
student *sptr;
// Assigning a structure to pointer
sptr = &s1;
cout << "Displaying the structure data members using pointers" << endl;
cout << "Using the * operator" << endl;
cout << endl;
cout << "The name is " << (*sptr).name << endl;
cout << "The course is " << (*sptr).course << endl;
cout << "The age is " << (*sptr).age << endl;
cout << "The year is " << (*sptr).year << endl;
cout << endl;
cout << "Using the -> operator" << endl;
cout << endl;
cout << "The name is " << sptr->name << endl;
cout << "The course is " << sptr->course << endl;
cout << "The age is " << sptr->age << endl;
cout << "The year is " << sptr->year << endl;
}
Page 246
The output of the program is:
Displaying the structure data members using pointers
Using the * operator
The name is Ali
The course is CS201- Introduction to programming
The age is 22
The year is 2002
Using the -> operator
The name is Ali
The course is CS201- Introduction to programming
The age is 22
The year is 2002

Arrays of structures


Let’s discuss the arrays of structure. The declaration is similar as used to deal with the
simple variables. The declaration of array of hundred students is as follows:
student s[100];
In the above statement, s is an array of type student structure. The size of the array is
hundred and the index will be from 0 to 99. If we have to access the name of first student,
the first element of the array will be as under:
s[0].name;
Here s is the array so the index belongs to s. Therefore the first student is s[0], the 2nd
student is s[1] and so on. To access the data members of the structure, the dot operator is
used. Remember that the array index is used with the array name and not with the data
member of the structure.

Sizeof operator


As discussed earlier, the sizeof operator is used to determine the size of data type. The
sizeof operator can also be used with the structure. Structure contains different data types.
How can we determine its size in the memory? Consider the student structure that
contains two char arrays and two int data types. We can simply use the sizeof operator to
determine its size. It will tell us how many bytes the structure is occupying.
sizeof(s1);
We don’t need to add the size of all the data members of the structure. This operator is
very useful while using the write() function to write the structure in the file.
Page 247
Here is a small example which shows the number of bytes a structure occupies in
memory.
/* this program shows the memory size of a structure*/
#include <iostream.h>
main()
{
// Declaring student structure
struct student{
char name[64];
char course[128];
int age;
int year;
};
student s1 = {"Ali", "CS201- Introduction to programming", 22, 2002};
// using sizeof operator to determine the size
cout << "The structure s1 occupies " << sizeof(s1) << " bytes in the memory";
}
The output of the above program is:
The structure s1 occupies 200 bytes in the memory
Let’s summarize what we can do with structures:
We can define the structure
We can declare variables of that type of structure
We can declare pointers to structure
We can declare arrays of structure
We can take the size of structure
We can do simple assignment of two variables of the same structure type

Sample Program 1
Problem:

Suppose we have ten students in a class. The attributes of student are name, course, age
and GPA. Get the data input from the user to populate the array. Calculate the average
age, average GPA of the class. Find out the grade of the class and student with max GPA.

Solution:


The problem is very simple. We will declare a structure of student with name, course, age
and GPA as data members. In a loop, we will get the data from the user to populate the
Page 248
array. Then in a loop, we will calculate the totalAge and totalGPA of the class besides
determining the max GPA in that loop. Finally calculate the average age and average
GPA by dividing the totalAge and totalGPA by the number of students i.e. 10. The grade
of the class can be determined by the average GPA.
The complete code of the program is:
/* This program calculates the average age and average GPA of a class. Also determine
the grade of the class and the student with max GPA. We will use a student structure and
manipulate it to get the desired result. */
#include <iostream.h>
main()
{
// Declaration of student structure
struct student
{
char name[30];
char course[15];
int age;
float GPA;
};
const int noOfStudents = 10; // total no of students
student students[noOfStudents]; // array of student structure
int totalAge, index, averageAge;
float totalGPA, maxGPA, averageGPA;
// initializing the structure, getting the input from user
for ( int i = 0; i < noOfStudents; i++ )
{
cout << endl;
cout << "Enter data for Student # : " << i + 1 << endl;
cout << "Enter the Student's Name : " ;
cin >> students[i].name ;
cout << "Enter the Student's Course : " ;
cin >> students[i].course ;
cout << "Enter the Student's Age : " ;
cin >> students[i].age ;
cout << "Enter the Student's GPA : " ;
cin >> students[i].GPA ;
}
maxGPA = 0;
// Calculating the total age, total GPA and max GPA
for ( int j = 0; j < noOfStudents; j++ )
Page 249
{
totalAge = totalAge + students[j].age ;
totalGPA = totalGPA + students[j].GPA ;
// Determining the max GPA and storing its index
if ( students[j].GPA > maxGPA )
{
maxGPA = students[j].GPA;
index = j;
}
}
// Calculating the average age
averageAge = totalAge / noOfStudents ;
cout << "\n The average age is : " << averageAge << endl;
// Calculating the average GPA
averageGPA = totalGPA / noOfStudents ;
cout << "\n The average GPA is : " << averageGPA << endl;
cout << "\n Student with max GPA is : " << students[index].name << endl ;
// Determining the Grade of the class
if (averageGPA > 4)
{
cout << "\n Wrong grades have been enter" << endl ;
}
else if ( averageGPA == 4)
{
cout << "\n The average Grade of the class is : A" << endl;
}
else if ( averageGPA >= 3)
{
cout << "\n The average Grade of the class is : B" << endl;
}
else if ( averageGPA >= 2)
{
cout << "\n The average Grade of the class is : C" << endl;
}
else
{
cout << "\n The average Grade of the class is : F" << endl;
}
}
The output of the program with three students i.e. when noOfStudents = 3
Page 250
Enter data for Student # : 1
Enter the Student's Name : Ali
Enter the Student's Course : CS201
Enter the Student's Age : 24
Enter the Student's GPA : 3.5
Enter data for Student # : 2
Enter the Student's Name : Faisal
Enter the Student's Course : CS201
Enter the Student's Age : 22
Enter the Student's GPA : 3.6
Enter data for Student # : 3
Enter the Student's Name : Jamil
Enter the Student's Course : CS201
Enter the Student's Age : 25
Enter the Student's GPA : 3.3
The average age is : 24
The average GPA is : 3.46667
Student with max GPA is : Faisal
The average Grade of the class is : B

Sample Program 2
Problem:

Read the student data from a file, populate the structure and write the structure in another
file.

Solution:


We have to read from a file. We will write a function which will read from a file and
return a structure to the calling program. The prototype of function is:
returnType functionName (argument list)
As the function is returning a student structure so the return type will be ‘student’. We
can name the function as getData() as it is reading from a file a returning the data (i.e.
student structure). In the arguments, we can give it the handle of the file from which the
data is to be read. For the simplicity, we keep the argument list empty. Therefore, the
prototype of our function is as under:
student getData();
Page 251
This function is going to read from a file. The handle of the file has to be global so that
function can access that file handle. We will define the handle of the file before main
function to make it global. We will open the file in the main function before calling the
getData
function. The getData function returns a student structure .We will assign this to
some variable of type student like:
s1 = getData();
Where s1 is a variable of type student. It means that the structure, returned by the getData
function is assigned to s1. The getData function can read the data from the file using
extraction operators (i.e. >>). As this function is returning a student structure, we declare
tmpStd
of type student. Data read from the file will be assigned to the tmpStd. In the end
of the getData function, we will return the tmpStd using the return keyword (i.e. return
tmpStd).
Let’s have a look what is happening in the memory. When we entered into the getData
function from main, it creates locally a tmpStd of type student structure. tmpStd is created
somewhere in the memory. It starts reading data from the file assigning it at that memory
location. On its return, the function copies this tmpStd on to the stack. Stack is the way
the function communicates with the main function or calling program. When the function
returns, it will destroy the tmpStd as it is local variable of getData function. It does not
exist anymore. It just came into being while you were inside the getData function. It
disappears once getData finishes. However, before it disappears, the getData copies
tmpStd
in the memory so the main function pick up those value use it to assign to s1.
Similarly we write the writeData function to write the data into a file. We will pass this
function a student type structure to write it on the file. The prototype of writeData is as:
void writeData(student s1);
The sample input file:
nasir
CS201
23
3
Jamil
CS201
31
4
Faisal
CS201
25
3.5
Here is the complete code of the program:
/* this program reads from a file, populate the structure, and write the structure in a file */
Page 252
#include <stdlib.h>
#include <fstream.h>
// Global variables for input and output files
ifstream inFile;
ofstream outFile;
//student structure
struct student
{
char name[30];
char course[15];
int age;
float GPA;
};
// function declarations
void openFile(); // open the input and output files
student getData(); // Read the data from the file
void writeData(student); // write the structure into a file
void main()
{
const int noOfStudents = 3; // Total no of students
openFile(); // opening input and output files
student students[noOfStudents]; // array of students
// Reading the data from the file and populating the array
for(int i = 0; i < noOfStudents; i++)
{
if (!inFile.eof())
{
students[i] = getData();
}
else
{
break ;
}
}
// Writing the structures to the file
for(int i = 0; i < noOfStudents; i++)
{
writeData(students[i]);
}
Page 253
// Closing the input and output files
inFile.close ( ) ;
outFile.close ( ) ;
}
/* This function opens the input file and output file */
void openFile()
{
inFile.open("SAMPLE.TXT", ios::in);
inFile.seekg(0L, ios::beg);
outFile.open("SAMPLEOUT.TXT", ios::out | ios::app);
outFile.seekp(0L, ios::end);
if(!inFile || !outFile)
{
cout << "Error in opening the file" << endl;
exit(1);
}
}
/* This function reads from the file */
student getData()
{
student tempStudent;
// temp variables for reading the data from file
char tempAge[2];
char tempGPA[5];
// Reading a line from the file and assigning to the variables
inFile.getline(tempStudent.name, '\n');
inFile.getline(tempStudent.course, '\n');
inFile.getline(tempAge, '\n');
tempStudent.age = atoi(tempAge);
inFile.getline(tempGPA, '\n');
tempStudent.GPA = atof(tempGPA);
// Returning the tempStudent structure
return tempStudent;
}
/* This function writes into the file the student structure*/
void writeData(student writeStudent)
{
outFile << writeStudent.name << endl;
outFile << writeStudent.course << endl;
outFile << writeStudent.age << endl;
Page 254
outFile << writeStudent.GPA << endl;
}
The contents of output file is:
nasir
CS201
23
3
Jamil
CS201
31
4
Faisal
CS201
25
3.5

Unions


We have another construct named union. The concept of union in C/C++ is: if we have
something in the memory, is there only one way to access that memory location or there
are other ways to access it. We have been using int and char interchangeably in our
programs. We have already developed a program that prints the ACSII codes. In this
program, we have stored a char inside an integer. Is it possible to have a memory location
and use it as int or char interchangeably? For such purposes, the construct union is used.
The syntax of union is:
union intOrChar{
int i,
char c;
};
The syntax is similar as that of structure. In structures, we have different data members
and all of these have their own memory space. In union, the memory location is same
while the first data member is one name for that memory location. However, the 2nd data
member is another name for the same location and so on. Consider the above union (i.e.
intOrChar) that contains an integer and a character as data members. What will be the
size of this union? The answer is the very simple. The union will be allocated the
memory equal to that of the largest size data member. If the int occupies four bytes on
our system and char occupies one byte, the union intOrChar will occupy four bytes.
Consider another example:
union intOrDouble{
int ival;
Page 255
double dval;
};
The above union has two data members i.e. ival of type int and dval of type double. We
know that double occupies more memory space than integer. Therefore, the union will
occupy the memory space equivalent to double. The data members of unions are accessed
in a similar way as we use with structures i.e. using the dot operator. For example:
intOrDouble uval;
uval.ival = 10;
To get the output of the data members, cout can be used as:
cout << “ The value in ival = “ << uval.ival;
It will print “The value in ival = 10”. Now what will be output of the following
statement?
cout << “ The value in dval = “ << uval.dval;
We don’t know. The reason is that in the eight bytes of double, integer is written
somewhere. When we use integer, it is printed fine. When we printed the double, the
value of int will not be displayed. Rather something else will be printed. Similarly in the
following statement i.e.
uval.dval = 100.0;
cout << “ The value in dval = “ << uval.dval;
It will print the right value of dval. The value of this double is written in such a way that
it will not be interpreted by the integer. If we try to print out ival, it will not display 100.
Unions are little bit safer for integer and characters. But we have to think in terms that
where to store the value in memory.
Suppose, we have some integer value 123 and want to append 456 to it so that it becomes
123456. How can we do that? To obtain this result, we have to shift the integer three
decimal places i.e. we can multiply the integer 123 by 1000 (i.e. 123000) and then add
456 to it (i.e. 123456). Consider a union containing four characters and an integer. Now
the size of the char is one and integer is four so the size of the union will be four. We
assign the character ‘a’ to the integer, and display the chars and integer value. If we want
to shift the value of first byte into the second byte, the integer will be multiplied by
256(i.e. A byte contains 8 bits and 2 to power 8 is 256), then add character ‘b’ to it. We
see that the char variables of union contains ‘a’ and ‘b’.
Here is the code of the program;
/* This program uses a union of int and char and display the memory usage by both */
#include <iostream.h>
Page 256
main()
{
// Declaration of union
union intOrChar{
char c[4];
int x;
}u1;
u1.x = 'a'; // Assigning ‘a’ to x
// Displaying the char array and integer value
cout << "The value of c = " << u1.c[0] << "," << u1.c[1]
<< "," << u1.c[2] << "," << u1.c[3]<< endl;
cout << "The value of x = " << u1.x << endl;
// Shifting the values one byte and adding ‘b’ to the int
u1.x *= 256;
u1.x += 'b';
// Displaying the char array and integer value
cout << "The value of c = " << u1.c[0] << "," << u1.c[1]
<< "," << u1.c[2] << "," << u1.c[3]<< endl;
cout << "The value of x = " << u1.x << endl;
// Shifting the values one byte and adding ‘b’ to the int
u1.x *= 256;
u1.x += 'c';
// Displaying the char array and integer value
cout << "The value of c = " << u1.c[0] << "," << u1.c[1]
<< "," << u1.c[2] << "," << u1.c[3]<< endl;
cout << "The value of x = " << u1.x << endl;
// Shifting the values one byte and adding ‘b’ to the int
u1.x *= 256;
u1.x += 'd';
// Displaying the char array and integer value
cout << "The value of c = " << u1.c[0] << "," << u1.c[1]
<< "," << u1.c[2] << "," << u1.c[3]<< endl;
cout << "The value of x = " << u1.x << endl;
}
The output of the program is;
The value of c = a, , ,
Page 257
The value of x = 97
The value of c = b,a, ,
The value of x = 24930
The value of c = c,b,a,
The value of x = 6382179
The value of c = d,c,b,a
The value of x = 1633837924
Unions are very rarely used. They become very important when we want to do some
super efficient programming. Experiment with the unions and structures.
We have learnt how to use structures and unions. These are relatively less used parts of
C/C++ language. But structures at least are very useful. They allow us a convenient way
of grouping data about a single entity. We have used student entity in our example. You
can think of a car or any other object and find out its properties before grouping them in a
structure. We don’t need to manipulate its properties individually as grouping them into a
unit is a better option. Try to write different programs using structures.

<Previous Lesson

Introduction to Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Copyright © 2008-2013 zainbooks All Rights Reserved
Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top