Controlling Function Behavior Sequence, Selection and Repetition Review We’ve seen that we can write a simple function that encodes a formula: double EllipseArea(double length, double width); { double halfLength = length/2.0, halfWidth = width/2.0; return PI * halfLength * halfWidth; } The statements in such a function are executed in sequence (one after another), which is called sequential execution. Difficulty There are other operations that are difficult to implement, using just sequential execution. Example: Let’s write a program to read in a sequence of test scores, and display their average and a corresponding pass/fail grade. Behavior Our program should prompt for, read, and average a sequence of test scores. It should then display the average. It should then compute the pass-fail letter grade (P or F) corresponding to that average. Finally, it should display that letter grade. Objects Description Type sequence of ??? test scores average double P/F grade char Kind ??? varying varying Name ??? average grade Operations Description prompt for, read and average a sequence of doubles display a double compute grade display char Predefined? Library? no yes no yes -- iostream -iostream Name -- << -<< Algorithm 0. Display via cout the purpose of the program. 1. Compute average by prompting for, reading and averaging a sequence of test scores. 2. Display average. 3. Compute P/F letter grade corresponding to average. 4. Display grade. Discussion We have predefined operations for steps 0, 2 and 4 of our algorithm, but no predefined operations for steps 1 or 3... Solution: Build functions to perform those operations. Function 1 Behavior Our function should read, sum, and count the sequence of scores using the input-loop pattern. If the number of scores was positive, it should return sum/numScores. Otherwise (numScores is not positive) it should display an error message and terminate the program. Function 1 Objects Description Type Kind Name number of scores sum of scores a prompt a score error msg int varying numScores double string double string varying constant varying constant sum -score -- Function 1 Operations Description Predefined? Library? display a string read a double test for sentinel add score to sum increment count repeat above steps divide doubles return a double select steps terminate program yes yes yes yes yes yes yes yes yes yes iostream iostream built-in iostream iostream built-in built-in built-in built-in cstdlib Name << >> < += ++ for / return if exit() Function 1 Algorithm 0. Initialize sum to 0, count to 0. 1. Loop: a. Read score. b. If score < 0: terminate repetition. c. Increment count. d. Add score to sum. End loop. 2. If count > 0 Return sum / count. Else Display an error message and terminate the program. Function 1 Coding #include <cstdlib> // exit() double ReadAndAverage() { double score, sum = 0.0; int count = 0; for (;;) { cout << “Enter a test score (-1 to quit): “; cin >> score; if (score < 0) break; // test for sentinel count++; sum += score; } } if (count > 0) return sum / count; else { cerr << “\n* no scores to average!\n” << endl; exit(1); } Function 2 Behavior Our function should receive from its caller an average. If that average is less than 60, it should return a failing grade; otherwise, it should return a passing grade. Function 2 Objects Description Type average failing grade passing grade double char char Kind varying constant constant Name avg ‘F’ ‘A’ Function 2 Operations Description Predefined? Library? receive double yes return a char yes select from among yes different returns built-in built-in built-in Name -return if Function 2 Algorithm 0. Receive avg from caller. 1. If avg < 60: Return ‘F’. Else Return ‘P’. Function 2 Coding char PassFailGrade(double avg) { if (avg < 60) return ‘F’; else return ‘P’; } Discussion ReadAndAverage() and PassFailGrade() are sufficiently useful that it is probably worth storing them in a library (e.g., grading). Once we have functions for each operation that is not predefined, we can encode the algorithm that solves our problem. Coding #include <iostream> #include “grading.h” // ReadAndAverage(), PassFailGrade() int main() { cout << “\nThis program reads a sequence of test scores” << “\n and computes their pass-fail grade.\n”; double average = ReadAndAverage(); char grade = PassFailGrade(average); cout << “\nThe average is “ << average << “\n and the grade is “ << grade << endl; } Testing This program reads a sequence of test scores and computes their pass-fail grade. Enter Enter Enter Enter a a a a score: score: score: score: 65 55 75 -1 The average is 65 and the grade is P . . . Summary (i) The C++ for loop lets you repeat a block of statements a specified number of times. Patterns: for (int count = Start; count <= Stop; count++) Statements for (;;) { StatementList1 if (Condition) break; StatementList2 } These permit repetitive execution of statements. Summary (ii) The C++ if statement lets you select from among two statements. Pattern: if (BooleanExpression) Statement1 [else Statement2] This permits selective execution of statements.