CS 1440 Lab 7

Pre-Lab

### Background

In Chapter 2, you learned that variables are names of memory locations.  You also have been told that you should use meaningful variable names.  So, if you are required to write a grading program that asks for test grades and computes the average of the grades, you may use variables like the ones named below:

int  count;
double  test, total, average;

Now, suppose that in addition to the average, your program must preserve the values of each test grade.  You can't "reuse" the test variable each time, because a double variable can remember only one number.  You could have a group of test variables, perhaps named: test1, test2, test3, etc.

Now suppose that you need to do this for 10 students where each student has 3 test grades.  You need to preserve the test grades, average them together, preserve the students names, and their final letter grades.  You might end up with many variables (6 per student) like these:

string name_1, grade_1;      /** student 1 **/
double test_1_1, test_1_2, test_1_3, average_1;

string name_2, grade_2;           /** student 2 **/
double test_2_1, test_2_2, test_2_3, average_2;
.  .  .
.  .  .
string name_10, grade_10;         /** student 10 **/
double test_10_1, test_10_2, test_10_3, average_10;

What is really going on here?  What you have is a bunch of variables to maintain information about a student: name, grade, tests, average.  With some clever variable naming you can keep track of many students,  but C++ gives us more powerful ways than a clever naming scheme to group memory locations than just a clever naming scheme.

Just as C++ lets us define our own functions, C++ also lets us define our own data types.  For the above example, we need a type that groups information about a student.  C++ lets us define either a struct or a class to do this.  In this lab we'll briefly discuss structs and then spend most of our time on classes.

STRUCTS

To "group" the student information together into a new struct data type, we say in C++:

struct  Student
{
double  test1, test2, test3;
double  average;
};

This code does not create a variable, it just defines a data type.  Use this new data type in a variable declaration just like you've been doing with the base C++ types (like int or double).  So you can have 10 student variables by declaring:

Student  student1, student2, . . . , student10;

Of course, you can't ues the ellipsis -- C++ insists that you type all ten names. Now your program really only has 10 variables (compared with 60 above), but each of these variables is a collection of memory locations as defined by the Student struct data type.  Each variable of this data type collects 6 named memory locations, name, grade, test1, test2, test3, and average, as members.

So how do you print out student3's name?  By using a member selector statement to select the name member of student3:

cout  <<  student3.name  <<  endl;

The dot is the member selection operator. It is used to access the data members in input statements, output statements, and other expressions you have used.  It usually does not make sense to use the entire collection in an expression.  Note that the following don't make sense:

student1 = "Jane";  // student1's name?
student1 = 100;     // student1's test1 grade?

However, it does make sense to refer to the entire struct when you want to pass the entire collection to a function, as in:

print_information(student1);  /* prints name, average,

The members of a struct can have any type, so you can arrange them "hierarchically".  For example, suppose that you want to group the grade information for a whole section of a course. You can do that by defining a struct with a member for each student. The member for a student should record all the information for that student, so the appropriate data type for it is the Student struct data type. You might write the following defintition:

struct  Course
{
string  name;
int  section;
Student  student1, student2, . . ., student10;
};

Course  cs1440, cs3460, cs4667;

Notice that  cs1440.name  and  cs1440.student1.name  are different data members (memory locations) even though the "last" member names are the same.  Also notice how you select "nested" data members using multiple dots.

CLASSES

Classes are another way C++ lets us group distinct but related memory locations.  Classes are more powerful and versatile than structs, which is why we will focus on them rather than on structs.  Classes are more powerful because in addition to combining related data, they also contain functions that are appropriate for manipulating the data.

Remember when you used file streams (fstreams)?  You declared a stream variable, then opened the fstream, which connected the Unix file with that variable. You wrote something like:

ifstream  fin;
fin.open("myfile.txt");

ifstream is a "class" data type.  In addition to some data members, the class defines some function members like open, close, fail, eof, and others too!