Case Study: Class GradeBook Using an Array to Store Grades

Case Study Class GradeBook Using an Array to Store Grades

This section further evolves class GradeBook, introduced in Chapter 3 and expanded in Chapters 46. Recall that this class represents a grade book used by a professor to store and analyze a set of student grades. Previous versions of the class process a set of grades entered by the user, but do not maintain the individual grade values in data members of the class. Thus, repeat calculations require the user to reenter the same grades. One way to solve this problem would be to store each grade entered in an individual data member of the class. For example, we could create data members grade1, grade2, ..., grade10 in class GradeBook to store 10 student grades. However, the code to total the grades and determine the class average would be cumbersome. In this section, we solve this problem by storing grades in an array.

Storing Student Grades in an Array in Class GradeBook

The version of class GradeBook (Figs. 7.167.17) presented here uses an array of integers to store the grades of several students on a single exam. This eliminates the need to repeatedly input the same set of grades. Array grades is declared as a data member in line 29 of Fig. 7.16therefore, each GradeBook object maintains its own set of grades.

Figure 7.16. Definition of class GradeBook using an array to store test grades.

(This item is displayed on pages 351 - 352 in the print version)

 1 // Fig. 7.16: GradeBook.h
 2 // Definition of class GradeBook that uses an array to store test grades.
 3 // Member functions are defined in GradeBook.cpp
 4
 5 #include  // program uses C++ Standard Library string class
 6 using std::string;
 7
 8 // GradeBook class definition
 9 class GradeBook
10 {
11 public:
12 // constant -- number of students who took the test
13 const static int students = 10; // note public data
14
15 // constructor initializes course name and array of grades
16 GradeBook( string, const int [] );
17
18 void setCourseName( string ); // function to set the course name
19 string getCourseName(); // function to retrieve the course name
20 void displayMessage(); // display a welcome message
21 void processGrades(); // perform various operations on the grade data
22 int getMinimum(); // find the minimum grade for the test
23 int getMaximum(); // find the maximum grade for the test
24 double getAverage(); // determine the average grade for the test
25 void outputBarChart(); // output bar chart of grade distribution
26 void outputGrades(); // output the contents of the grades array
27 private:
28 string courseName; // course name for this grade book
29 int grades[ students ]; // array of student grades
30 }; // end class GradeBook

Note that the size of the array in line 29 of Fig. 7.16 is specified by public const static data member students (declared in line 13). This data member is public so that it is accessible to the clients of the class. We will soon see an example of a client program using this constant. Declaring students with the const qualifier indicates that this data member is constantits value cannot be changed after being initialized. Keyword static in this variable declaration indicates that the data member is shared by all objects of the classall GradeBook objects store grades for the same number of students. Recall from Section 3.6 that when each object of a class maintains its own copy of an attribute, the variable that represents the attribute is also known as a data membereach object (instance) of the class has a separate copy of the variable in memory. There are variables for which each object of a class does not have a separate copy. That is the case with static data members, which are also known as class variables. When objects of a class containing static data members are created, all the objects of that class share one copy of the class's static data members. A static data member can be accessed within the class definition and the member-function definitions just like any other data member. As you will soon see, a public static data member can also be accessed outside of the class, even when no objects of the class exist, using the class name followed by the binary scope resolution operator (::) and the name of the data member. You will learn more about static data members in Chapter 10.

The class's constructor (declared in line 16 of Fig. 7.16 and defined in lines 1724 of Fig. 7.17) has two parametersthe name of the course and an array of grades. When a program creates a GradeBook object (e.g., line 13 of fig07_18.cpp), the program passes an existing int array to the constructor, which copies the values in the passed array to the data member grades (lines 2223 of Fig. 7.17). The grade values in the passed array could have been input from a user or read from a file on disk (as discussed in Chapter 17, File Processing). In our test program, we simply initialize an array with a set of grade values (Fig. 7.18, lines 1011). Once the grades are stored in data member grades of class GradeBook, all the class's member functions can access the grades array as needed to perform various calculations.

Figure 7.17. GradeBook class member functions manipulating an array of grades.

(This item is displayed on pages 352 - 355 in the print version)

 1 // Fig. 7.17: GradeBook.cpp
 2 // Member-function definitions for class GradeBook that
 3 // uses an array to store test grades.
 4 #include 
 5 using std::cout;
 6 using std::cin;
 7 using std::endl;
 8 using std::fixed;
 9
10 #include 
11 using std::setprecision;
12 using std::setw;
13
14 #include "GradeBook.h" // GradeBook class definition
15
16 // constructor initializes courseName and grades array
17 GradeBook::GradeBook( string name, const int gradesArray[] )
18 {
19 setCourseName( name ); // initialize courseName
20
21 // copy grades from gradeArray to grades data member
22 for ( int grade = 0; grade < students; grade++ ) 
23  grades[ grade ] = gradesArray[ grade ]; 
24 } // end GradeBook constructor
25
26 // function to set the course name
27 void GradeBook::setCourseName( string name )
28 {
29 courseName = name; // store the course name
30 } // end function setCourseName
31
32 // function to retrieve the course name
33 string GradeBook::getCourseName()
34 {
35 return courseName;
36 } // end function getCourseName
37
38 // display a welcome message to the GradeBook user
39 void GradeBook::displayMessage()
40 {
41 // this statement calls getCourseName to get the
42 // name of the course this GradeBook represents
43 cout << "Welcome to the grade book for
" << getCourseName() << "!"
44 << endl;
45 } // end function displayMessage
46
47 // perform various operations on the data
48 void GradeBook::processGrades()
49 {
50 // output grades array
51 outputGrades();
52
53 // call function getAverage to calculate the average grade
54 cout << "
Class average is " << setprecision( 2 ) << fixed <<
55 getAverage() << endl;
56
57 // call functions getMinimum and getMaximum
58 cout << "Lowest grade is " << getMinimum() << "
Highest grade is "
59 << getMaximum() << endl;
60
61 // call function outputBarChart to print grade distribution chart
62 outputBarChart();
63 } // end function processGrades
64
65 // find minimum grade
66 int GradeBook::getMinimum()
67 {
68 int lowGrade = 100; // assume lowest grade is 100
69
70 // loop through grades array
71 for ( int grade = 0; grade < students; grade++ )
72 {
73 // if current grade lower than lowGrade, assign it to lowGrade
74 if ( grades[ grade ] < lowGrade ) 
75  lowGrade = grades[ grade ]; // new lowest grade 
76 } // end for
77
78 return lowGrade; // return lowest grade
79 } // end function getMinimum
80
81 // find maximum grade
82 int GradeBook::getMaximum()
83 {
84 int highGrade = 0; // assume highest grade is 0
85
86 // loop through grades array
87 for ( int grade = 0; grade < students; grade++ )
88 {
89 // if current grade higher than highGrade, assign it to highGrade
90 if ( grades[ grade ] > highGrade ) 
91  highGrade = grades[ grade ]; // new highest grade 
92 } // end for
93
94 return highGrade; // return highest grade
95 } // end function getMaximum
96
97 // determine average grade for test
98 double GradeBook::getAverage()
99 {
100 int total = 0; // initialize total
101
102 // sum grades in array
103 for ( int grade = 0; grade < students; grade++ )
104 total += grades[ grade ];
105
106 // return average of grades
107 return static_cast< double >( total ) / students;
108 } // end function getAverage
109
110 // output bar chart displaying grade distribution
111 void GradeBook::outputBarChart()
112 {
113 cout << "
Grade distribution:" << endl;
114
115 // stores frequency of grades in each range of 10 grades
116 const int frequencySize = 11;
117 int frequency[ frequencySize ] = { 0 };
118
119 // for each grade, increment the appropriate frequency
120 for ( int grade = 0; grade < students; grade++ )
121 frequency[ grades[ grade ] / 10 ]++;
122
123 // for each grade frequency, print bar in chart
124 for ( int count = 0; count < frequencySize; count++ )
125 {
126 // output bar labels ("0-9:", ..., "90-99:", "100:" )
127 if ( count == 0 )
128 cout << " 0-9: ";
129 else if ( count == 10 )
130 cout << " 100: ";
131 else
132 cout << count * 10 << "-" << ( count * 10 ) + 9 << ": ";
133
134 // print bar of asterisks
135 for ( int stars = 0; stars < frequency[ count ]; stars++ )
136 cout << '*';
137
138 cout << endl; // start a new line of output
139 } // end outer for
140 } // end function outputBarChart
141
142 // output the contents of the grades array
143 void GradeBook::outputGrades()
144 {
145 cout << "
The grades are:

";
146
147 // output each student's grade
148 for ( int student = 0; student < students; student++ )
149 cout << "Student " << setw( 2 ) << student + 1 << ": " << setw( 3 )
150 << grades[ student ] << endl;
151 } // end function outputGrades

Figure 7.18. Creates a GradeBook object using an array of grades, then invokes member function processGrades to analyze them.

 1 // Fig. 7.18: fig07_18.cpp
 2 // Creates GradeBook object using an array of grades.
 3
 4 #include "GradeBook.h" // GradeBook class definition
 5
 6 // function main begins program execution
 7 int main()
 8 {
 9 // array of student grades
10 int gradesArray[ GradeBook::students ] =
11 { 87, 68, 94, 100, 83, 78, 85, 91, 76, 87 };
12
13 GradeBook myGradeBook(
14 "CS101 Introduction to C++ Programming", gradesArray );
15 myGradeBook.displayMessage();
16 myGradeBook.processGrades();
17 return 0;
18 } // end main
 
 Welcome to the grade book for
 CS101 Introduction to C++ Programming!

 The grades are:

 Student 1: 87
 Student 2: 68
 Student 3: 94
 Student 4: 100
 Student 5: 83
 Student 6: 78
 Student 7: 85
 Student 8: 91
 Student 9: 76
 Student 10: 87

 Class average is 84.90
 Lowest grade is 68
 Highest grade is 100

 Grade distribution:
 0-9:
 10-19:
 20-29:
 30-39:
 40-49:
 50-59:
 60-69: *
 70-79: **
 80-89: ****
 90-99: **
 100: *
 

Member function processGrades (declared in line 21 of Fig. 7.16 and defined in lines 4863 of Fig. 7.17) contains a series of member function calls that output a report summarizing the grades. Line 51 calls member function outputGrades to print the contents of the array grades. Lines 148150 in member function outputGrades use a for statement to output each student's grade. Although array indices start at 0, a professor would typically number students starting at 1. Thus, lines 149150 output student + 1 as the student number to produce grade labels "Student 1:", "Student 2:", and so on.

Member function processGrades next calls member function getAverage (lines 5455) to obtain the average of the grades in the array. Member function getAverage (declared in line 24 of Fig. 7.16 and defined in lines 98108) uses a for statement to total the values in array grades before calculating the average. Note that the averaging calculation in line 107 uses const static data member students to determine the number of grades being averaged.

Lines 5859 in member function processGrades call member functions getMinimum and getMaximum to determine the lowest and highest grades of any student on the exam, respectively. Let us examine how member function getMinimum finds the lowest grade. Because the highest grade allowed is 100, we begin by assuming that 100 is the lowest grade (line 68). Then, we compare each of the elements in the array to the lowest grade, looking for smaller values. Lines 7176 in member function getMinimum loop through the array, and lines 7475 compare each grade to lowGrade. If a grade is less than lowGrade, lowGrade is set to that grade. When line 78 executes, lowGrade contains the lowest grade in the array. Member function getMaximum (lines 8295) works similarly to member function getMinimum.

Finally, line 62 in member function processGrades calls member function outputBarChart to print a distribution chart of the grade data using a technique similar to that in Fig. 7.9. In that example, we manually calculated the number of grades in each category (i.e., 09, 1019, ..., 9099 and 100) by simply looking at a set of grades. In this example, lines 120121 use a technique similar to that in Fig. 7.10 and Fig. 7.11 to calculate the frequency of grades in each category. Line 117 declares and creates array frequency of 11 ints to store the frequency of grades in each grade category. For each grade in array grades, lines 120121 increment the appropriate element of the frequency array. To determine which element to increment, line 121 divides the current grade by 10 using integer division. For example, if grade is 85, line 121 increments frequency[ 8 ] to update the count of grades in the range 8089. Lines 124139 next print the bar chart (see Fig. 7.18) based on the values in array frequency. Like lines 2930 of Fig. 7.9, lines 135136 of Fig. 7.17 use a value in array frequency to determine the number of asterisks to display in each bar.

Testing Class GradeBook

The program of Fig. 7.18 creates an object of class GradeBook (Figs. 7.167.17) using the int array gradesArray (declared and initialized in lines 1011). Note that we use the binary scope resolution operator (::) in the expression "GradeBook::students" (line 10) to access class GradeBook's static constant students. We use this constant here to create an array that is the same size as array grades stored as a data member in class GradeBook. Lines 1314 pass a course name and gradesArray to the GradeBook constructor. Line 15 displays a welcome message, and line 16 invokes the GradeBook object's processGrades member function. The output reveals the summary of the 10 grades in myGradeBook.


Introduction to Computers, the Internet and World Wide Web

Introduction to C++ Programming

Introduction to Classes and Objects

Control Statements: Part 1

Control Statements: Part 2

Functions and an Introduction to Recursion

Arrays and Vectors

Pointers and Pointer-Based Strings

Classes: A Deeper Look, Part 1

Classes: A Deeper Look, Part 2

Operator Overloading; String and Array Objects

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

Templates

Stream Input/Output

Exception Handling

File Processing

Class string and String Stream Processing

Web Programming

Searching and Sorting

Data Structures

Bits, Characters, C-Strings and structs

Standard Template Library (STL)

Other Topics

Appendix A. Operator Precedence and Associativity Chart

Appendix B. ASCII Character Set

Appendix C. Fundamental Types

Appendix D. Number Systems

Appendix E. C Legacy Code Topics

Appendix F. Preprocessor

Appendix G. ATM Case Study Code

Appendix H. UML 2: Additional Diagram Types

Appendix I. C++ Internet and Web Resources

Appendix J. Introduction to XHTML

Appendix K. XHTML Special Characters

Appendix L. Using the Visual Studio .NET Debugger

Appendix M. Using the GNU C++ Debugger

Bibliography



C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net