Case Study: GradeBook Using a Rectangular Array

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 362 - 368)

2. When the app executes, another compiler (known as the just-in-time compiler

8.11 Case Study: GradeBook Using a Rectangular Array

arrayreturns the size of the first dimension of the array (the number of rows), and the call

GetLength(1)returns the size of the second dimension (the number of columns).

MethodOutputArrayfor Jagged Arrays

Line 23 invokes methodOutputArraywith argumentjagged, so the version ofOutput-

Arrayat lines 43–56 is called. The nestedforeachstatement (lines 48–55) outputs the rows of a jagged array. The innerforeachstatement (lines 51–52) iterates through each element in the current row of the array. This allows the loop to determine the exact num- ber of columns in each row. Since the jagged array is created as an array of arrays, we can use nestedforeachstatements to output the elements in the console window. The outer loop iterates through the elements ofarray, which are references to one-dimensional ar- rays ofintvalues that represent each row. The inner loop iterates through the elements of the current row. Aforeachstatement can also iterate through all the elements in a rectan- gular array. In this case,foreachiterates through all the rows and columns starting from row0, as if the elements were in a one-dimensional array.

Common Multidimensional-Array Manipulations Performed withforStatements Many common array manipulations useforstatements. As an example, the followingfor statement sets all the elements in row 2 of rectangular arrayain Fig. 8.17 to0:

We specified row2; therefore, we know that the first index is always2(0is the first row, and1is the second row). Thisforloop varies only the second index (i.e., thecolumn in- dex). The precedingforstatement is equivalent to the assignment statements

The following nestedforstatement totals the values of all the elements in arraya:

These nestedforstatements total the array elements one row at a time. The outer for statement begins by setting therowindex to0so that row 0’s elements can be totaled by the innerforstatement. The outerforthen incrementsrowto1so that row 1’s elements can be totaled. Then the outerforincrementsrowto 2so that row 2’s elements can be totaled. The variabletotalcan be displayed when the outerforstatement terminates. In the next example, we show how to process a rectangular array in a more concise manner usingforeachstatements.

8.11 Case Study: GradeBook Using a Rectangular Array

In Section 8.9, we presented classGradeBook(Fig. 8.15), which used a one-dimensional array to store student grades on a single exam. In most courses, students take several exams.

for ( int column = 0; column < a.GetLength( 1 ); ++column ) a[ 2, column ] = 0;

a[ 2, 0 ] = 0;

a[ 2, 1 ] = 0;

a[ 2, 2 ] = 0;

a[ 2, 3 ] = 0;

int total = 0;

for ( int row = 0; row < a.GetLength( 0 ); ++row ) {

for ( int column = 0; column < a.GetLength( 1 ); ++column ) total += a[ row, column ];

} // end outer for

Instructors are likely to want to analyze grades across the entire course, both for a single student and for the class as a whole.

Storing Student Grades in a Rectangular Array in ClassGradeBook

Figure 8.20 contains a version of classGradeBookthat uses a rectangular arraygradesto store the grades of a number of students on multiple exams. Each row of the array represents a single student’s grades for the entire course, and each column represents the grades for the whole class on one of the exams the students took during the course. An app such asGrade-

BookTest(Fig. 8.21) passes the array as an argument to theGradeBookconstructor. In this example, we use a 10-by-3 array containing 10 students’ grades on three exams. Five meth- ods perform array manipulations to process the grades. Each method is similar to its coun- terpart in the earlier one-dimensional-array version of classGradeBook(Fig. 8.15). Method

GetMinimum(lines 44–58 in Fig. 8.20) determines the lowest grade of any student for the se- mester. MethodGetMaximum(lines 61–75) determines the highest grade of any student for the semester. MethodGetAverage(lines 78–90) determines a particular student’s semester average. MethodOutputBarChart(lines 93–122) outputs a bar chart of the distribution of all student grades for the semester. MethodOutputGrades(lines 125–149) outputs the two- dimensional array in tabular format, along with each student’s semester average.

1 // Fig. 8.20: GradeBook.cs

2 // Grade book using a rectangular array to store grades.

3 using System;

4

5 public class GradeBook 6 {

7 8

9 // auto-implemented property CourseName 10 public string CourseName { get; set; } 11

12 // two-parameter constructor initializes

13 // auto-implemented property CourseName and grades array 14 public GradeBook( string name, int[ , ] gradesArray )

15 {

16 CourseName = name; // set CourseName to name 17

18 } // end two-parameter GradeBook constructor 19

20 // display a welcome message to the GradeBook user 21 public void DisplayMessage()

22 {

23 // auto-implemented property CourseName gets the name of course 24 Console.WriteLine( "Welcome to the grade book for\n{0}!\n",

25 CourseName );

26 } // end method DisplayMessage 27

28 // perform various operations on the data 29 public void ProcessGrades()

30 {

Fig. 8.20 | Grade book using a rectangular array to store grades. (Part 1 of 4.)

private int[ , ] grades; // rectangular array of student grades

grades = gradesArray; // initialize grades array

8.11 Case Study:GradeBookUsing a Rectangular Array 323

31 // output grades array 32 OutputGrades();

33

34 // call methods GetMinimum and GetMaximum 35 Console.WriteLine( "\n{0} {1}\n{2} {3}\n",

36 "Lowest grade in the grade book is", GetMinimum(), 37 "Highest grade in the grade book is", GetMaximum() );

38

39 // output grade distribution chart of all grades on all tests 40 OutputBarChart();

41 } // end method ProcessGrades 42

43 // find minimum grade 44 public int GetMinimum()

45 {

46 // assume first element of grades array is smallest 47 int lowGrade = grades[ 0, 0 ];

48 49 50 51 52 53 54 55 56

57 return lowGrade; // return lowest grade 58 } // end method GetMinimum

59

60 // find maximum grade 61 public int GetMaximum()

62 {

63 // assume first element of grades array is largest 64 int highGrade = grades[ 0, 0 ];

65

66 // loop through elements of rectangular grades array 67 foreach ( int grade in grades )

68 {

69 // if grade greater than highGrade, assign it to highGrade 70 if ( grade > highGrade )

71 highGrade = grade;

72 } // end foreach 73

74 return highGrade; // return highest grade 75 } // end method GetMaximum

76 77 78 79 80 81 82 83

Fig. 8.20 | Grade book using a rectangular array to store grades. (Part 2 of 4.)

// loop through elements of rectangular grades array foreach ( int grade in grades )

{

// if grade less than lowGrade, assign it to lowGrade if ( grade < lowGrade )

lowGrade = grade;

} // end foreach

// determine average grade for particular student public double GetAverage( int student )

{

// get the number of grades per student int amount = grades.GetLength( 1 );

int total = 0; // initialize total

84 85 86 87 88 89 90 91

92 // output bar chart displaying overall grade distribution 93 public void OutputBarChart()

94 {

95 Console.WriteLine( "Overall grade distribution:" );

96

97 // stores frequency of grades in each range of 10 grades 98 int[] frequency = new int[ 11 ];

99 100 101 102 103 104 105

106 // for each grade frequency, display bar in chart 107 for ( int count = 0; count < frequency.Length; ++count )

108 {

109 // output bar label ( "00-09: ", ..., "90-99: ", "100: " ) 110 if ( count == 10 )

111 Console.Write( " 100: " );

112 else

113 Console.Write( "{0:D2}-{1:D2}: ", 114 count * 10, count * 10 + 9 );

115

116 // display bar of asterisks

117 for ( int stars = 0; stars < frequency[ count ]; ++stars ) 118 Console.Write( "*" );

119

120 Console.WriteLine(); // start a new line of output 121 } // end outer for

122 } // end method OutputBarChart 123

124 // output the contents of the grades array 125 public void OutputGrades()

126 {

127 Console.WriteLine( "The grades are:\n" );

128 Console.Write( " " ); // align column heads 129

130 // create a column heading for each of the tests

131 for ( int test = 0; test < grades.GetLength( 1 ); ++test ) 132 Console.Write( "Test {0} ", test + 1 );

133

134 Console.WriteLine( "Average" ); // student average column heading 135

Fig. 8.20 | Grade book using a rectangular array to store grades. (Part 3 of 4.)

// sum grades for one student

for ( int exam = 0; exam < amount; ++exam ) total += grades[ student, exam ];

// return average of grades return ( double ) total / amount;

} // end method GetAverage

// for each grade in GradeBook, increment the appropriate frequency foreach ( int grade in grades )

{

++frequency[ grade / 10 ];

} // end foreach

8.11 Case Study:GradeBookUsing a Rectangular Array 325

Processing a Two-Dimensional Array with aforeachStatement

MethodsGetMinimum,GetMaximumandOutputBarCharteach loop through array grades using theforeachstatement—for example, theforeachstatement from methodGetMin-

imum (lines 50–55). To find the lowest overall grade, this foreach statement iterates through rectangular arraygradesand compares each element to variablelowGrade. If a grade is less thanlowGrade,lowGradeis set to that grade.

When theforeachstatement traverses the elements of arraygrades, it looks at each element of the first row in order by index, then each element of the second row in order by index and so on. Theforeachstatement in lines 50–55 traverses the elements ofgrade in the same order as the following equivalent code, expressed with nestedforstatements:

When theforeachstatement completes,lowGradecontains the lowest grade in the rect- angular array. MethodGetMaximumworks similarly to methodGetMinimum.

MethodOutputBarChart

MethodOutputBarChart(lines 93–122) displays the grade distribution as a bar chart. The syntax of theforeachstatement (lines 101–104) is identical for one-dimensional and two- dimensional arrays.

MethodOutputGrades

MethodOutputGrades(lines 125–149) uses nestedforstatements to output values of the arraygrades, in addition to each student’s semester average. The output in Fig. 8.21 shows the result, which resembles the tabular format of an instructor’s physical grade book. Lines 131–132 (in Fig. 8.20) display the column headings for each test. We use theforstatement rather than theforeachstatement here so that we can identify each test with a number.

Similarly, theforstatement in lines 137–148 first outputs a row label using a counter vari- 136 // create rows/columns of text representing array grades

137 for ( int student = 0; student < grades.GetLength( 0 ); ++student )

138 {

139 Console.Write( "Student {0,2}", student + 1 );

140

141 // output student's grades

142 for ( int grade = 0; grade < grades.GetLength( 1 ); ++grade ) 143 Console.Write( "{0,8}", grades[ student, grade ] );

144

145 // call method GetAverage to calculate student's average grade;

146 // pass row number as the argument to GetAverage 147 Console.WriteLine( "{0,9:F}", );

148 } // end outer for

149 } // end method OutputGrades 150 } // end class GradeBook

for ( int row = 0; row < grades.GetLength( 0 ); ++row )

for ( int column = 0; column < grades.GetLength( 1 ); ++column ) {

if ( grades[ row, column ] < lowGrade ) lowGrade = grades[ row, column ];

}

Fig. 8.20 | Grade book using a rectangular array to store grades. (Part 4 of 4.)

GetAverage( student )

able to identify each student (line 139). Although array indices start at 0, lines 132 and 139 outputtest + 1andstudent + 1, respectively, to produce test and student numbers start- ing at1(see Fig. 8.21). The innerforstatement in lines 142–143 uses the outerforstate- ment’s counter variablestudentto loop through a specific row of arraygradesand output each student’s test grade. Finally, line 147 obtains each student’s semester average by pass- ing the row index ofgrades(i.e.,student) to methodGetAverage.

MethodGetAverage

MethodGetAverage(lines 78–90) takes one argument—the row index for a particular student. When line 147 callsGetAverage, the argument isintvaluestudent, which spec- ifies the particular row of rectangular arraygrades. Method GetAverage calculates the sum of the array elements on this row, divides the total by the number of test results and returns the floating-point result as adoublevalue (line 89).

ClassGradeBookTestThat Demonstrates ClassGradeBook

The app in Fig. 8.21 creates an object of classGradeBook(Fig. 8.20) using the two-dimen- sional array ofints thatgradesArrayreferences (Fig. 8.21, lines 9–18). Lines 20–21 pass a course name andgradesArrayto theGradeBookconstructor. Lines 22–23 then invoke

myGradeBook’sDisplayMessageandProcessGradesmethods to display a welcome mes- sage and obtain a report summarizing the students’ grades for the semester, respectively.

1 // Fig. 8.21: GradeBookTest.cs

2 // Create a GradeBook object using a rectangular array of grades.

3 public class GradeBookTest 4 {

5 // Main method begins app execution 6 public static void Main( string[] args )

7 {

8 9 10 11 12 13 14 15 16 17 18 19

20 GradeBook myGradeBook = new GradeBook(

21 "CS101 Introduction to C# Programming", gradesArray );

22 myGradeBook.DisplayMessage();

23 myGradeBook.ProcessGrades();

24 } // end Main

25 } // end class GradeBookTest Welcome to the grade book for

CS101 Introduction to C# Programming!

Fig. 8.21 | Create aGradeBookobject using a rectangular array of grades. (Part 1 of 2.)

// rectangular array of student grades int[ , ] gradesArray = { { 87, 96, 70 },

{ 68, 87, 90 }, { 94, 100, 90 }, { 100, 81, 82 }, { 83, 65, 85 }, { 78, 87, 65 }, { 85, 75, 83 }, { 91, 94, 100 }, { 76, 72, 84 }, { 87, 93, 73 } };

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 362 - 368)

Tải bản đầy đủ (PDF)

(1.020 trang)