2. When the app executes, another compiler (known as the just-in-time compiler
5.8 Formulating Algorithms: Counter-Controlled
To illustrate how algorithms are developed, we modify theGradeBookclass of Chapter 4 to solve two variations of a problem that averages student grades. Consider the following problem statement:
A class of 10 students took a quiz. The grades (integers in the range 0 to 100) for this quiz are available to you. Determine the class average on the quiz.
The class average is equal to the sum of the grades divided by the number of students. The algorithm for solving this problem on a computer must input each grade, keep track of the total of all grades input, perform the averaging calculation and display the result.
Pseudocode Algorithm with Counter-Controlled Repetition
Let’s use pseudocode to list the actions to execute and specify the order in which they should execute. We usecounter-controlled repetitionto input the grades one at a time.
This technique uses a variable called acounter(orcontrol variable) to control the number of times a set of statements will execute. Counter-controlled repetition is often calleddefi- nite repetition, because the number of repetitions is knownbeforethe loop begins execut- ing. In this example, repetition terminates when the counter exceeds 10. This section presents a fully developed pseudocode algorithm (Fig. 5.5) and a version of classGradeBook
(Fig. 5.6) that implements the algorithm in a C# method. The section then presents an app (Fig. 5.7) that demonstrates the algorithm in action. In Section 5.9, we demonstrate how to use pseudocode to develop such an algorithm from scratch.
Note the references in the algorithm of Fig. 5.5 to a total and a counter. Atotalis a variable used to accumulate the sum of several values. A counter is a variable used to count—in this case, the grade counter indicates which of the 10 grades is about to be
Software Engineering Observation 5.1
Experience has shown that the most difficult part of solving a problem on a computer is developing the algorithm for the solution. Once a correct algorithm has been specified, the process of producing a working C# app from it is normally straightforward.
1 set total to zero 2 set grade counter to one 3
4 while grade counter is less than or equal to 10 5 prompt the user to enter the next grade 6 input the next grade
7 add the grade into the total 8 add one to the grade counter 9
10 set the class average to the total divided by 10 11 display the class average
Fig. 5.5 | Pseudocode algorithm that uses counter-controlled repetition to solve the class- average problem.
5.8 Formulating Algorithms: Counter-Controlled Repetition 155
entered by the user. Variables used to store totals are normally initialized to zero before being used in an app.
Implementing Counter-Controlled Repetition in ClassGradeBook
ClassGradeBook(Fig. 5.6) contains a constructor (lines 12–15) that assigns a value to the instance variable created by auto-implemented propertyCourseNamein line 9. Lines 18–23 declare methodDisplayMessage. Lines 26–52 declare methodDetermineClassAverage, which implements the class-averaging algorithm described by the pseudocode in Fig. 5.5.
1 // Fig. 5.6: GradeBook.cs
2 // GradeBook class that solves the class-average problem using 3 // counter-controlled repetition.
4 using System;
5
6 public class GradeBook 7 {
8 // auto-implemented property CourseName 9 public string CourseName { get; set; } 10
11 // constructor initializes CourseName property 12 public GradeBook( string name )
13 {
14 CourseName = name; // set CourseName to name 15 } // end constructor
16
17 // display a welcome message to the GradeBook user 18 public void DisplayMessage()
19 {
20 // property CourseName gets the name of the course
21 Console.WriteLine( "Welcome to the grade book for\n{0}!\n",
22 CourseName );
23 } // end method DisplayMessage 24
25 // determine class average based on 10 grades entered by user 26
27 {
28 int total; // sum of the grades entered by user 29
30 int grade; // grade value entered by the user 31 int average; // average of the grades
32
33 // initialization phase
34 total = 0; // initialize the total 35
36
37 // processing phase
38 while ( ) // loop 10 times
39 {
40 Console.Write( "Enter grade: " ); // prompt the user
41 grade = Convert.ToInt32( Console.ReadLine() ); // read grade
Fig. 5.6 | GradeBookclass that solves the class-average problem using counter-controlled repetition. (Part 1 of 2.)
public void DetermineClassAverage()
int gradeCounter; // number of the grade to be entered next
gradeCounter = 1; // initialize the loop counter
gradeCounter <= 10
MethodDetermineClassAverage
Lines 28–31 declare local variablestotal,gradeCounter,gradeandaverageto be of type
int. In this example, variabletotalaccumulates the sum of the grades entered andgrade-
Countercounts the number of grades entered. Variablegradestores the most recent grade value entered (line 41). Variableaveragestores the average grade.
The declarations (in lines 28–31) appear in methodDetermineClassAverage’s body.
Variables declared in a method body arelocalvariables and can be used only from the line of their declaration to the closing right brace of the block in which they’re declared. A local variable’s declarationmustappear before the variable is used in that method. A local vari- able cannot be accessedoutsidethe block in which it’s declared.
In the versions of classGradeBookin this chapter, we simply read and process a set of grades. The averaging calculation is performed in methodDetermineClassAverageusing local variables—we do not preserve any information about student grades in instance vari- ables of the class. In later versions of the class (in Chapter 8), we store the grades using an instance variable that refers to a data structure known as an array. This will allow aGrade- Bookobject to perform various calculations on the same set of grades without requiring the user to enter the grades multiple times.
We say that a variable isdefinitely assignedwhen it’s guaranteed to be assigned a value before the variable is used. Notice that each local variable declared in lines 28–31 is defi- nitely assigned before it’s used in calculations. The assignments (in lines 34–35) initialize
totalto0andgradeCounterto1. Variablesgradeandaverage(for the user input and calculated average, respectively) need not be initialized here—their values are assigned as they’re input or calculated later in the method.
42 total = total + grade; // add the grade to total 43
44 } // end while 45
46 // termination phase 47
48
49 // display total and average of grades
50 Console.WriteLine( "\nTotal of all 10 grades is {0}", total );
51 Console.WriteLine( "Class average is {0}", average );
52 } // end method DetermineClassAverage 53 } // end class GradeBook
Good Programming Practice 5.5
Separate declarations from other statements in methods with a blank line for readability.
Common Programming Error 5.3
Using the value of a local variable before it’s definitely assigned results in a compilation error.
All local variables must be definitely assigned before their values are used in expressions.
Fig. 5.6 | GradeBookclass that solves the class-average problem using counter-controlled repetition. (Part 2 of 2.)
gradeCounter = gradeCounter + 1; // increment the counter by 1
average = total / 10; // integer division yields integer result
5.8 Formulating Algorithms: Counter-Controlled Repetition 157
Line 38 indicates that thewhilestatement should continue looping (also callediter- ating) as long as the value ofgradeCounteris less than or equal to10. While this condition remains true, thewhilestatement repeatedly executes the statements between the braces that delimit its body (lines 39–44).
Line 40 displays the prompt"Enter grade: "in the console window. Line 41 reads the grade entered by the user and assigns it to variablegrade. Then line 42 adds the new
gradeentered by the user to thetotaland assigns the result tototal, which replaces its previous value.
Line 43 adds1togradeCounterto indicate that the app has processed a grade and is ready to input the next grade from the user. IncrementinggradeCountereventually causes
gradeCounterto exceed10. At that point thewhileloop terminates, because its condition (line 38) becomes false.
When the loop terminates, line 47 performs the averaging calculation and assigns its result to the variableaverage. Line 50 usesConsole’sWriteLinemethod to display the text"Total of all 10 grades is "followed by variabletotal’s value. Line 51 then dis- plays the text"Class average is "followed by variableaverage’s value. MethodDeter- mineClassAveragereturns control to the calling method (i.e.,MaininGradeBookTestof Fig. 5.7) after reaching line 52.
ClassGradeBookTest
ClassGradeBookTest(Fig. 5.7) creates an object of classGradeBook(Fig. 5.6) and demon- strates its capabilities. Lines 9–10 of Fig. 5.7 create a newGradeBookobject and assign it to variablemyGradeBook. Thestringin line 10 is passed to theGradeBookconstructor (lines 12–15 of Fig. 5.6). Line 12 (Fig. 5.7) callsmyGradeBook’sDisplayMessagemethod to dis- play a welcome message to the user. Line 13 then callsmyGradeBook’sDetermineClassAv- eragemethod to allow the user to enter 10 grades, for which the method then calculates and displays the average—the method performs the algorithm shown in Fig. 5.5.
Error-Prevention Tip 5.1
Initialize each counter and total, either in its declaration or in an assignment statement.
Totals are normally initialized to 0. Counters are normally initialized to 0 or 1, depend- ing on how they’re used (we’ll show examples of each).
1 // Fig. 5.7: GradeBookTest.cs
2 // Create GradeBook object and invoke its DetermineClassAverage method.
3 public class GradeBookTest 4 {
5 public static void Main( string[] args )
6 {
7 // create GradeBook object myGradeBook and 8 // pass course name to constructor
9 GradeBook myGradeBook = new GradeBook(
10 "CS101 Introduction to C# Programming" );
11
12 myGradeBook.DisplayMessage(); // display welcome message
Fig. 5.7 | CreateGradeBookobject and invoke itsDetermineClassAveragemethod. (Part 1 of 2.)
Notes on Integer Division and Truncation
The averaging calculation performed by methodDetermineClassAveragein response to the method call at line 13 in Fig. 5.7 produces an integer result. The app’s output indicates that the sum of the grade values in the sample execution is 848, which, when divided by 10, should yield the floating-point number 84.8. However, the result of the calculation
total / 10(line 47 of Fig. 5.6) is the integer84, becausetotaland10arebothintegers.
Dividing two integers results ininteger division—any fractional part of the calculation is lost (i.e.,truncated, not rounded). We’ll see how to obtain a floating-point result from the averaging calculation in the next section.