Vous êtes sur la page 1sur 42

Chapter 5

Functions for All Subtasks 1. Solutions to Selected Programming Projects Detailed solutions to the first 6 projects are presented here. The rest are essentially the same problems, except for what is being converted. Notes about the remaining problems are included. One of the more important things in programming is planning, even for the simplest program. If the planning is thorough, the coding will be easy, and the only errors likely to be encountered are syntax errors, usually caused by either typing errors, a boundary condition problem (frequently, an off by one error), or (we hope not) lack of knowledge of the language details. 1 Convert Time Task: Convert 24 hour time notation to 12 hour AM/PM notation. General comments: The student should note that: a) The convert function has boundary cases that require careful attention. b) ALL of this commentary and planning should be done PRIOR to beginning to write the program. Once this is done the program is almost written. The sooner coding begins, the longer the program will take to do correctly. c) When testing for equality, as in if (12 == hours) put the constant first. The compiler will catch errors such as if (12= hours) which are hard to see otherwise. I made many errors of this type while coding this problem.

1
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

//file: ch5prog1.cc //Task: Convert 24 hour time notation to 12 hour AM/PM //notation. //Input: 24 hour time //Output: corresponding 12 hour time, with AM/PM indication //Required: 3 functions: input, conversion, and output. // keep AM/PM information in a char variable // allow repeat at user's option //Notes: conversion function will have a char reference // parameter to return whether the time is AM/PM. Other // parameters are required. #include <iostream> using namespace std; void input( int& hours24, int& minutes); //Precondition: input( hours, minutes ) is called with //arguments capable of being assigned. //Postcondition: // user is prompted for time in 24 hour format: // HH:MM, where 0 <= HH < 24, 0 <= MM < 60. // hours is set to HH, minutes is set to MM. //KNOWN BUG: NO CHECKING IS DONE ON INPUT FORMAT. Omitting //the : (colon) from the input format eats one character //from the minutes data, and silently gives erroneous //results. void convert( int& hours, char& AMPM ); //Precondition: 0 <= hours < 24, //Postcondition:

2
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// // // // // // // // // // // //

if hours > 12, // Note: definitely in the afternoon hours is replaced by hours - 12, AMPM is set to 'P' else if 12 == hours // boundary afternoon hour AMPM is set to 'P', // hours is not changed. else if 0 == hours // boundary morning hour hours = hours + 12; AMPM = 'A'; else (hours < 12) AMPM is set to 'A'; hours is unchanged

void output( int hours, int minutes, char AMPM ); //Precondition: // 0 < hours <=12, 0 <= minutes < 60, // AMPM == 'P' or AMPM == 'A' //Postconditions: // time is written in the format // HH:MM AM or HH:MM PM int main() { int hours, minutes; char AMPM, ans; do { input( hours, minutes ); convert ( hours, AMPM ); output( hours, minutes, AMPM ); cout << "Enter Y or y to continue," << " anything else quits."

3
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

<< endl; cin >> ans; } while ( 'Y'== ans || 'y' == ans ); return 0; } void input( int& hours24, int& minutes) { char colon; cout << "Enter 24 hour time in the format HH:MM " << endl; cin >> hours24 >> colon >> minutes; } //Precondition: 0 <= hours < 24, //Postcondition: // if hours >= 12, // hours is replaced by hours - 12, // AMPM is set to 'P' // else // (hours < 12) // hours is unchanged and AMPM is set to 'A' void convert( int& hours, char& AMPM ) { if (hours > 12) // definitely in the afternoon { hours = hours - 12; AMPM = 'P'; } else if (12 == hours) // boundary afternoon hour AMPM = 'P'; // but hours is not changed. else if (0 == hours) // boundary morning hour {

4
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

hours = hours + 12; AMPM = 'A'; } else // (hours < 12) // definitely morning hour AMPM = 'A'; // hours is unchanged } void output( int hours, int minutes, char AMPM ) { cout << "Time in 12 hour format: " << endl << hours << ":" << minutes << " " << AMPM << 'M' << endl; } A typical run follows: 20:33:03:~/AW$ a.out Enter 24 hour time in the 0:30 Time in 12 hour format: 12:30 AM Enter Y or y to continue, y Enter 24 hour time in the 2:15 Time in 12 hour format: 2:15 AM Enter Y or y to continue, y Enter 24 hour time in the Enter 24 hour time in the 11:30 Time in 12 hour format:

format HH:MM

anything else quits. format HH:MM

anything else quits. format HH:MM format HH:MM

5
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

11:30 AM Enter Y or y to continue, y Enter 24 hour time in the 12:30 Time in 12 hour format: 12:30 PM Enter Y or y to continue, y Enter 24 hour time in the 23:59

anything else quits. format HH:MM

anything else quits. format HH:MM

Time in 12 hour format: 11:59 PM Enter Y or y to continue, anything else quits. n 20:33:59:~/AW$ 2. Time
// // // // // // // // // // // // // // // Waiting time Problem 2, Savitch, Programming and Problem Solving with C++ 5th file ch5.2.cpp Program input: current time and a waiting time each time is number of hours and a number of minutes. Program output is is the time the waiting period completes. Use 24 hour time. Allow user repeat. Notes: The 24 hour boundary, i.e., when the time wraps to the next day is important here. Known Bugs: If the completion time would be in a day later than the next day after the start, this program gives incorrect results.

#include <iostream> void input( int& hours24, int& minutes) {

6
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

using std::cout; using std::cin; using std::endl; char colon; cout << "Enter 24 hour time in the format HH:MM " << endl; cin >> hours24 >> colon >> minutes;

void output( int hours, int minutes) { using std::cout; using std::cin; using std::endl; cout << "Time in 24 hour format:\n" << hours << ":" << minutes << endl;

int main() { using std::cout; using std::cin; using std::endl; int timeHours, timeMinutes, waitHours, waitMinutes, finishHours, finishMinutes; cout << "Compute completion time from current time and waiting period\n"; char ans = 'y'; while ('y' == ans || 'Y' == ans) { cout << "Current time:\n"; input(timeHours, timeMinutes); cout << "Waiting time:\n"; input(waitHours, waitMinutes); finishHours = timeHours + waitHours; finishMinutes = timeMinutes + waitMinutes; finishHours += finishMinutes / 60; if(finishHours >= 24) { finishHours %= 24;

7
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

cout << "Completion time is in the day following the start time\n"; } finishMinutes%= 60; cout << "Completion "; output(finishHours, finishMinutes); cout << "\n\nEnter Y or y to continue, any other halts\n\n"; cin >> ans;

} }

return 0;

/* Typical run Compute completion Current time: Enter 24 hour time 12:30 Waiting time: Enter 24 hour time 15:40 Completion time is Completion Time in 4:10 time from current time and waiting period in the format HH:MM in the format HH:MM in the day following the start time 24 hour format:

Enter Y or y to continue, any other halts y Current time: Enter 24 hour time in the format HH:MM 8:30 Waiting time: Enter 24 hour time in the format HH:MM 15:10 Completion Time in 24 hour format: 23:40 Enter Y or y to continue, any other halts n Press any key to continue

*/

8
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

3. Project 3 Modify project 2 to use 12 hour time. We provide suggestions on how to proceed in solving this problem. This problem is different from #2 only in the details of managing 12 hour time. The wait time interval could be any number of hours and minutes, so the output should provide the number of days that elapse from the start time until completion. You may want an input routine that verifies that you have entered legitimate 12 hour time data, i.e. hours betwee 1 and 12, minutes between 0 and 59, and includes either an A for AM or a P for PM. Write code to convert the 12 hour start time to 24 hour time and use the code from #3 to computer the finish time. Decide on how to handle finish times that fall in some later day, then convert 24 hour time to 12 hour time and output that using code from #2. 4. Statistics Compute average and standard deviation of 4 entries. General remarks are in the code file which I present here: // file ch5prob4.cc #include <iostream> using namespace std; /* Task: Write a function that computes average (I will call this the arithmetic mean or simply the mean) and standard deviation of four scores. The average or mean, avg, is computed as avg = ( s1 + s2 + s3 + s4 ) / 4 The standard deviation is computed as

9
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

std_deviation =

( s1 a) + ( s 2 a ) + ( s3 a) 4

where a = avg. Note that some statisticians may wish to use 3 instead of 4. We will use 4. Input: scores s1 s2 s3 s4 Output: standard deviation and mean. Required: The function is to have 6 parameters. This function calls two others that compute the mean and the std deviation. A driver with a loop should be written to test the function at the user's option. */ //function declaration (or prototype) //When used, the math library must be linked to the //executable. #include <cmath> // for sqrt using namespace std; void average (double s1, double s2, double s3, double s4, double& avg) { avg = ( s1 + s2 + s3 + s4 ) / 4; }

// Preconditions: average function must have been called on //the data, and the value of the average passed into the //parameter a //Postconditions: Standard deviation is passed back in //the variable stdDev

10
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

void sD (double s1, double s2, double s3, double s4, double a, double& stdDev) { stdDev = sqrt( (s1 - a)*(s1 - a) + (s2 - a)*(s2 - a) + (s3 - a)*(s3 - a) + (s4 - a)*(s4 - a) )/4 ; } void statistics( double s1, double s2, double s3, double s4, double& avg, double& stdDev ); //Preconditions: this function is called with any set of //values. Very large or very small numbers are subject to //errors in the calculation. Analysis of this sort of error //is beyond the scope of this chapter. //PostConditions: avg is set to the mean of s1, s2, s3, s4 //and stdDev is set to the standard deviation of s1..s4 //function definition: void statistics( double s1, double s2, double s3, double s4, double& avg, double& stdDev ) { average ( s1, s2, s3, s4, avg ); sD ( s1, s2, s3, s4, avg, stdDev ); } int main() { double s1, s2, s3, s4, avg, stdDev; char ans; do { cout << "Enter 4 decimal numbers, " << "I will give you the mean "

11
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

<< endl << "and standard deviation of the data " << endl; cin >> s1 >> s2 >> s3 >> s4; statistics( s1, s2, s3, s4, avg, stdDev); cout << "mean of " << s1 << " " << s2 << " " << s3 << " " << s4 << " is " << avg << endl << "the standard deviation of " << "these numbers is " << stdDev << endl; cout << "y or Y continues, any other terminates" << endl; cin >> ans; } while ( 'Y' == ans || 'y' == ans ); return 0; } A typical run follows: 21:44:35:~/AW$ a.out Enter 4 decimal numbers, I will give you the mean and standard deviation of the data 12.3 13.4 10.5 9.0 mean of 12.3 13.4 10.5 9 is 11.3 the standard deviation of these numbers is 0.841873 y or Y continues, any other terminates y Enter 4 decimal numbers, I will give you the mean and standard deviation of the data 1 2 3 4 mean of 1 2 3 4 is 2.5 the standard deviation of these numbers is 0.559017 y or Y continues, any other terminates n 21:45:05:~/AW$

12
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

5. Change maker problem. Only notes on the solution are provided for this problem. In my discussion of this problem, I include a word or two on algorithm development, concluding (sometimes only the following). A greedy algorithm works for this problem. A greedy algorithm makes locally optimal choices at each point in the sequence of points in the solution, in the hope that the locally optimal choices will result in a globally optimal solution. This works surprisingly often, including this problem. It is interesting to me that the greedy algorithm fails for some national coinage. I suggest that the student write code to choose the largest number of coins of the largest denomination from the list of coin not yet used. Repeat this on the remaining amount of money for decreasing denominations until no more coins are left.

6. Conversion 1 Conversion of feet/inches to meters: //File: Ch4Prob6.cc //Task: Convert feet/inches to meters //Input:a length in feet and inches, with possible decimal //part of inches //Output: a length in meters, with 2 decimal places, which //are the 'centimeters' specified in the problem. //Required: functions for input, computation, and output. //Include a loop to repeat the calculation at the user's //option.Remarks: The computation is a simple conversion from //feet + inches to feet with a decimal part, then to meters. //Output is restricted to 2 decimal places. // //By 'meters and centimeters' the author means that the

13
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

//output is to be meters with two decimal places - which is //meters and centimeters. I mention this because my students //always stumble at this because of a lack of knowledge of //the metric system. #include <iostream> using namespace std; void input ( int& feet, double& inches ); //Precondition: function is called //Postcondition: //Prompt given to the user for input in the format FF II, //where FF is integer number of feet and II is a double //number of inches. feet and inches are returned as entered //by the user. void convert (int feet, double inches, double& meters ); //Preconditions: //REQUIRED CONSTANTS: INCHES_PER_FOOT, METERS_PER_FOOT //inches < 12, feet within range of values for int type //Postconditions: //meters assigned 0.3048 * (feet + inches/12) //observe that the centimeter requirement is met by //the value of the first two decimal places of the converted //feet, inches input. void output( int feet, double inches, double meters ); //input: the formal argument for meters fits into a double //output: //"the value of feet, inches" <feet, inches> //" converted to meters, centimeters is " <meters> //where meters is displayed as a number with two decimal //places

14
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

int main() { int feet; double inches, meters; char ans; do { input ( feet, inches ); convert ( feet, inches, meters ); output ( feet, inches, meters ); cout << "Y or y continues, any other character quits " << endl; cin >> ans; } while ( 'Y' == ans || 'y' == ans ); return 0; } void input ( int& feet, double& inches ) { cout << "Enter feet as an integer: " << flush; cin >> feet; cout << "Enter inches as a double: " << flush; cin >> inches; } const double METERS_PER_FOOT = 0.3048; const double INCHES_PER_FOOT = 12.0; void convert (int feet, double inches, double& meters )

15
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

{ meters = METERS_PER_FOOT * (feet + inches/INCHES_PER_FOOT); } void output( int feet, double inches, double meters ) { //inches, meters displayed as a number with two decimal //places cout.setf( ios::showpoint ); cout.setf( ios::fixed ); cout.precision(2); cout << "the value of feet, inches" << feet << "," << inches << endl << " converted to meters, centimeters is " << meters << endl; } /* A typical run follows: 06:59:16:~/AW$ a.out Enter feet as an integer: 5 Enter inches as a double: 7 the value of feet, inches5,7.00 converted to meters, centimeters is 1.70 Y or y continues, any other character quits y Enter feet as an integer: 245 Enter inches as a double: 0 the value of feet, inches245,0.00 converted to meters, centimeters is 74.68

16
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

Y or y continues, any other character quits q 06:59:49:~/AW$ */ 7. Conversion 2 Conversion of meters back to centimeters. //file: ch5prob7.cc //Task: Convert meters with centimeters (just the decimal //part of meters)to feet/inches // //Input: a length in feet and inches, with possible decimal //part of inches //Output: A length measured in feet with any decimal fraction //converted to inches by multiplying by 12. Fractions of an //inch are represented by 2 decimal places. // //Required: functions for input, computation, and output. //Include a loop to repeat the calculation at the user's //option. // //Remark: The computation is a simple conversion from meters //to feet, inches, where inches has a decimal part. //Output is restricted to 2 decimal places //Comment: Please see Problem 4 for discussion of 'meters and //centimeters' #include <iostream> using namespace std; void input ( double & meters ); //Precondition: function is called

17
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

//Postcondition: //Prompt given to the user for input of a number of meters as //a double. input of a double for meters has been accepted void convert (int& feet, double& inches, double meters ); //Preconditions: // REQUIRED CONSTANTS: INCHES_PER_FOOT, METERS_PER_FOOT //Postconditions: //feet is assigned the integer part of meters (after //conversion to feet units) inches is assigned the //fractional part of feet ( after conversion to inch units void output( int feet, double inches, double meters ); //input: the formal argument for meters fits into a double //output: //"the value of meters, centimeters is: " <meters> //" converted to English measure is " //<feet> "feet, " <inches> " inches " //where meters is displayed as a number with two decimal //places int main() { int feet; double inches, meters; char ans; do { input ( meters ); convert ( feet, inches, meters ); output ( feet, inches, meters ); cout << "Y or y continues, any other character quits "

18
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

<< endl; cin >> ans; } while ( 'Y' == ans || 'y' == ans ); return 0; } void input ( double& meters ) { cout << "Enter a number of meters as a double \n"; cin >> meters; } const double METERS_PER_FOOT = 0.3048; const double INCHES_PER_FOOT = 12.0; void convert (int &feet, double& inches, double meters ) { double dfeet; dfeet = meters / METERS_PER_FOOT; feet = int( dfeet ); inches = (dfeet - feet)*INCHES_PER_FOOT; } void output( int feet, double inches, double meters ) { //meters is displayed as a double with two decimal places //feet is displayed as int, inches as double with two //decimal places cout.setf( ios::showpoint ); cout.setf( ios::fixed ); cout.precision(2); cout << "The value of meters, centimeters " << endl

19
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

<< << << << }

meters << " meters" << endl "converted to English measure is " << endl feet << " feet, " << inches << " inches" endl;

/* A typical run follows: 07:56:28:~/AW$ a.out Enter a number of meters as a double 6.0 The value of meters, centimeters 6.00 meters converted to English measure is 19 feet, 8.22 inches Y or y continues, any other character quits y Enter a number of meters as a double 75 The value of meters, centimeters 75.00 meters converted to English measure is 246 feet, 0.76 inches Y or y continues, any other character quits q 07:56:40:~/AW$ */ 8. Conversion 3 This exercise combines the two previous exercises. Convert between feet/inches and meters. The direction is the user's option.

20
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// file: ch5prob8.cc //Task: Convert between meters and feet/inches at user's //option Within conversion, allow repeated calculation //after end of either conversion, allow choice of another //conversion. //Input: At program request, user selects direction of //conversion. Input is either feet/inches(with decimal //fraction for inches) OR meters with 2 place decimal //fraction that represents the centimeters. //Output: Depends on user selection: either meters or //feet and inches. //Method: Suggested by problem statement: use if-else //selection based on the user input to choose between //functions written for problems 4 and 5 above. //Required: functions for input, computation, and output. //Include a loop to repeat the calculation at the user's //option. #include <iostream> using namespace std; void inputM ( double& meters ); //Precondition: function is called //Postcondition: //Prompt given to the user for input of a number of meters //as a double void inputE ( int& feet, double& inches ); //Precondition: function is called

21
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

//Postcondition: //Prompt given to the user for input in the format FF II, //where FF is an int number of feet and II is a double number //of inches feet and inches are returned as entered by the //user. void convertEtoM (int feet, double inches, double& meters ); //Preconditions: //REQUIRED CONSTANTS: INCHES_PER_FOOT, METERS_PER_FOOT //inches < 12, feet within range of values for an int //Postconditions: //meters assigned 0.3048 * (feet + inches/12) //Observe that the requirement to produce centimeters is met //by the value of the first two decimal places of meters. void convertMtoE (int& feet, double& inches, double meters ); //Preconditions: // REQUIRED CONSTANTS: INCHES_PER_FOOT, METERS_PER_FOOT //Postconditions: //the variable feet is assigned the integer part of //meters/METERS_PER_FOOT //the variable inches is assigned the fractional part of //feet after conversion to inch units. void output( int feet, double inches, double meters ); //input: the formal argument for meters fits into a double //output: //"the value of feet, inches" <feet, inches> //" corresponds to meters, centimeters is " <meters> //where meters is displayed as a number with two decimal

22
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

//places void EnglishToMetric (); // requests English measure, converts to metric, outputs both void MetricToEnglish(); // request metric measure, converts to English, outputs both int main() { char ans; do { int which; cout << "Enter 1 for English to Metric or " << endl << "Enter 2 for Metric to English conversion" << endl; cin >> which; if ( 1 == which ) EnglishToMetric(); else MetricToEnglish(); cout << "Y or y allows another choice of conversion. " << "any other quits" << endl; cin >> ans; } while ( 'y' == ans || 'Y' == ans ); return 0; } void MetricToEnglish() {

23
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

int feet; double inches, meters; char ans; do { inputM ( meters ); convertMtoE ( feet, inches, meters ); output ( feet, inches, meters ); cout << "Y or y continues, any other character quits " << endl; cin >> ans; } while ( 'Y' == ans || 'y' == ans ); } void EnglishToMetric () { int feet; double inches, meters; char ans; do { inputE ( feet, inches ); convertEtoM ( feet, inches, meters ); output ( feet, inches, meters ); cout << "Y or y continues, any other character quits " << endl; cin >> ans; } while ( 'Y' == ans || 'y' == ans ); } void inputE ( int& feet, double& inches )

24
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

{ cout << "Enter feet as an integer: " << flush; cin >> feet; cout << "Enter inches as a double: " << flush; cin >> inches; } void inputM ( double& meters ) { cout << "Enter a number of meters as a double " << endl; cin >> meters; } const double METERS_PER_FOOT = 0.3048; const double INCHES_PER_FOOT = 12.0; // convert English measure to Metric void convertEtoM (int feet, double inches, double& meters ) { meters = METERS_PER_FOOT * (feet + inches/INCHES_PER_FOOT); } // convert Metric to English measure void convertMtoE (int &feet, double& inches, double meters ) { double dfeet; dfeet = meters / METERS_PER_FOOT; feet = int( dfeet ); inches = (dfeet - feet)*INCHES_PER_FOOT; }

25
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

void output( int feet, double inches, double meters ) { // meters is displayed as a double with two decimal // places // feet is displayed as int, inches as double with two //decimal places cout.setf( ios::showpoint ); cout.setf( ios::fixed ); cout.precision(2); cout << meters << " meters " << "corresponds to " << feet << " feet, " << inches << " inches" << endl; } /* A typical run follows 08:59:38:~/AW$ a.out Enter 1 for English to Metric or Enter 2 for Metric to English conversion 2 Enter a number of meters as a double 75 75.00 meters corresponds to 246 feet, 0.76 inches Y or y continues, any other character quits n Y or y allows another choice of conversion. any other quits y Enter 1 for English to Metric or Enter 2 for Metric to English conversion 1

26
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

Enter feet as an integer: 246 Enter inches as a double: 0.76 75.00 meters corresponds to 246 feet, 0.76 inches Y or y continues, any other character quits q Y or y allows another choice of conversion. any other quits q 09:00:08:~/AW$ */ 9-12. More ConversionsNo Solutions Provided. These problems differ from problems whose solutions have already been presented only in the names and specific factors used to carry out the conversions. 13. The Area of an Arbitrary Triangle I provide only notes for this problem. To determine the area of an arbitrary triangle can be computed using Heros formula for the area of a triangle1 the lengths of the edges of which are a, b, and c: s = (a + b + c)/2 area = sqrt(s(s - a)(s - b)(s - c)) It is necessary to test whether edges of lengths a, b and c actually form a triangle. The test for values of a, b and c to form a triangle is that each of the following inequalities be satisfied. a + b > c and

Hero, Heron, or Hron, was a mathematician conjectured to have lived between the 3rd and 2nd centuries BCE. He lived in Alexandria, but wrote in Greek. This formula is ascribed to him as is Heros engine, where steam recoil rotates a sphere or wheel.

27
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

b+ c > a and a+c > b A question to ask the student might be: Do two of these imply the third? The answer, (un?)fortunately, is no. All three conditions for legimate data must be checked. The student should be able to produce an example such as a = 1, b = 1, c = 2 that shows that the assertion, two of these conditions implies the third, isnt true for all a, b and c. The program should confirm that the entered values of a, b, and c satisfy these condtions. If the test shows a triangle is possible, then the area and perimeter are computed and reported. If the test fails, the program reports this fact and exits.

28
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

14. Wind Chill Index In cold weather, meteorologists report an index is called the windchill factor, that takes into account the wind sped and the temperature. This index provides a measure of the chilling effect of wind at a given air temperature. There is much information on the web, but the site http://www.kwarc.org/ksrwx_stn_info.html states that our formula gives an equivalent temperature in still air. In the following, we declare w, v, and t, and use these as follows: double w; // wind chill factor double v; // wind speed in meters/sec double t ; // temperature in degrees Celsius, t <= 10; Windchill may be approximate by the formula
0.16 0.16

w = 13.12 + 0.6215 * t 11.37 * v

+ 0.3965 * t * v

We enforced the temperature restriction and we looked up a windchill calculator in lieu of weather reports to compare to our results. See http://www.msc.ec.gc.ca/education/windchill/windchill_calcula tor_e.cfm // File: ch5.14.cpp // Windchill Index // Wind Chill #include <iostream> #include <cmath> #include <cstdlib> //using namespace std; //Pre: v wind speed in meters/sec // t in degrees Celsius. Required t <= 10 //Post: returned value is the windChill index

29
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

double windChill(double v, double t); int main() { using std::cout; using std::cin; //using std::pow; // quirk of MSVC++ using std::endl; double t, v; char ans; do { cout << "Enter the Celcius termperature (<= 10 degrees)\n"; cin >> t; cout << "Enter wind speed in meters/second: \n"; cin >> v; cout << "Wind chill factor is " << windChill(v, t) << endl; cout << "Y/y continues, other quits\n"; cin >> ans; } while(ans == 'y' || ans == 'Y'); return 0;

} double windChill(double v, double t) { using std::cout; double w; // wind chill factor if(t>10) { cout << "Quitting. windChill called with temperature > 10 " << "degrees\n"; exit(0); } w = 13.12 + 0.6215 * t - 11.37 * pow(v,0.16) + 0.3965 * t * pow(v,0.16); return w; } /* Typical run:

30
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

Enter the Celcius termperature (<= 0 Enter wind speed in meters/second: 5 Wind chill factor is -1.58942 Y/y continues, other quits y Enter the Celcius termperature (<= -1 Enter wind speed in meters/second: 5 Wind chill factor is -2.72388 Y/y continues, other quits y Enter the Celcius termperature (<= -10 Enter wind speed in meters/second: 5 Wind chill factor is -12.934 Y/y continues, other quits y Enter the Celcius termperature (<= -20 Enter wind speed in meters/second: 5 Wind chill factor is -24.2785 Y/y continues, other quits x

10 degrees)

10 degrees)

10 degrees)

10 degrees)

These results agree with Environment Canada Windchill calculator, accessible at the URL: http://www.msc.ec.gc.ca/education/windchill/windchill_calcula tor_e.cfm
*/

15.
// *********************************************************************** // Ch5Proj15abc.cpp // // This program simulates the duel between Aaron, Bob, and Charlie. // It answers parts a-c of project 15.

31
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// *********************************************************************** #include <iostream> #include <cstdlib> using namespace std; // Function prototypes void shoot(bool& targetAlive, double accuracy); int startDuel(); // Constants const double AARONACCURACY = 1.0/3; const double BOBACCURRACY = 0.5; const double CHARLIEACCURACY = 1.0; const int NUMDUELS = 1000; // ====================== // shoot: // Simulates shooting at a live target, // referenced by targetAlive, with a given accuracy. // ====================== void shoot(bool& targetAlive, double accuracy) { double r; // Only continue if the target is alive if (targetAlive == true) { r = rand() % 100; // Random number from 0-99 if (r < (accuracy * 100)) { // Hit target targetAlive = false; } } } // ====================== // startDuel: // Simulates a duel where Aaron shoots first and each // contestant shoots at the best shooter still alive. // // Returns 0 if Aaron wins, 1 if Bob wins, 2 if Charlie wins // ====================== int startDuel() { bool aaronAlive = true, bobAlive = true, charlieAlive = true; // Keep shooting as long as any two people are still alive while ((aaronAlive && bobAlive) || (aaronAlive && charlieAlive) || (bobAlive && charlieAlive)) { // Needed for random numbers

32
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// Aaron's turn if (aaronAlive) { if (charlieAlive) { shoot(charlieAlive, AARONACCURACY); } else if (bobAlive) { shoot(bobAlive, AARONACCURACY); } } // Bobs's turn if (bobAlive) { if (charlieAlive) { shoot(charlieAlive, BOBACCURRACY); } else if (aaronAlive) { shoot(aaronAlive, BOBACCURRACY); } } // Charlie's turn if (charlieAlive) { if (bobAlive) { shoot(bobAlive, CHARLIEACCURACY); } else if (aaronAlive) { shoot(aaronAlive, CHARLIEACCURACY); } }

} if (aaronAlive) return 0; else if (bobAlive) return 1; else if (charlieAlive) return 2;

// ==================== // main function // ==================== int main() { int i; int winner; double aaronWins=0, bobWins=0, charlieWins=0;

33
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// Simulate 1000 duels for (i=0; i < NUMDUELS; i++) { winner = startDuel(); if (winner == 0) { aaronWins++; } else if (winner == 1) { bobWins++; } else if (winner == 2) { charlieWins++; } } cout endl; cout cout cout } << "Using the strategy of shooting at the best shooter alive:" << << "Aaron win %: " << (aaronWins/NUMDUELS) << endl; << "Bob win %: " << (bobWins/NUMDUELS) << endl; << "Charlie win %: " << (charlieWins/NUMDUELS) << endl;

return 0;

// *********************************************************************** // Ch5Proj15d.cpp // // This program simulates the duel between Aaron, Bob, and Charlie. // It answers part d of project 15, where Aaron intentionally misses his // first shot. // *********************************************************************** #include <iostream> #include <cstdlib> using namespace std; // Function prototypes void shoot(bool& targetAlive, double accuracy); int startDuel(); // Constants const double AARONACCURACY = 1.0/3; const double BOBACCURRACY = 0.5; const double CHARLIEACCURACY = 1.0; const int NUMDUELS = 1000; // ====================== // shoot: // Needed for random numbers

34
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

// Simulates shooting at a live target, // referenced by targetAlive, with a given accuracy. // ====================== void shoot(bool& targetAlive, double accuracy) { double r; // Only continue if the target is alive if (targetAlive == true) { r = rand() % 100; // Random number from 0-99 if (r < (accuracy * 100)) { // Hit target targetAlive = false; } } } // ====================== // startDuel: // Simulates a duel where Aaron shoots first and each // contestant shoots at the best shooter still alive. // To simulate Aaron missing on his first shot, Aaron is moved // to the end of the cycle (i.e. Bob shoots first, which is equivalent // to Aaron missing first). // // Returns 0 if Aaron wins, 1 if Bob wins, 2 if Charlie wins // ====================== int startDuel() { bool aaronAlive = true, bobAlive = true, charlieAlive = true; // Keep shooting as long as any two people are still alive while ((aaronAlive && bobAlive) || (aaronAlive && charlieAlive) || (bobAlive && charlieAlive)) { // Bobs's turn first to simulate Aaron missing the first shot if (bobAlive) { if (charlieAlive) { shoot(charlieAlive, BOBACCURRACY); } else if (aaronAlive) { shoot(aaronAlive, BOBACCURRACY); } } // Charlie's turn if (charlieAlive) { if (bobAlive)

35
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

shoot(bobAlive, CHARLIEACCURACY); } else if (aaronAlive) { shoot(aaronAlive, CHARLIEACCURACY); }

} if (aaronAlive) return 0; else if (bobAlive) return 1; else if (charlieAlive) return 2;

// Aaron's turn now LAST to simulate Aaron missing first shot if (aaronAlive) { if (charlieAlive) { shoot(charlieAlive, AARONACCURACY); } else if (bobAlive) { shoot(bobAlive, AARONACCURACY); } }

// ==================== // main function // ==================== int main() { int i; int winner; double aaronWins=0, bobWins=0, charlieWins=0; // Simulate 1000 duels for (i=0; i < NUMDUELS; i++) { winner = startDuel(); if (winner == 0) { aaronWins++; } else if (winner == 1) { bobWins++; } else if (winner == 2) { charlieWins++; } }

36
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

cout << "Using the strategy of shooting at the best shooter alive, but Aaron intentionally misses on the first shot:" << endl; cout << "Aaron win %: " << (aaronWins/NUMDUELS) << endl; cout << "Bob win %: " << (bobWins/NUMDUELS) << endl; cout << "Charlie win %: " << (charlieWins/NUMDUELS) << endl; } return 0;

2. Outline of Topics 5.1 void-Functions Definitions of void Functions return Statements in void Functions 5.2 Call-by-Reference Parameters A First View of Call-by-Reference Call-by-Reference in Detail Mixed Parameter Lists 5.3 Using Procedural Abstraction Functions Calling Functions Preconditions and Postconditions 5.4 Testing and Debugging Functions Stubs and Drivers 3. General Remarks on the Chapter Section 5.1 void-Functions From the outset it is important that the students understand several points about voidfunctions. A void-function does not return a value. While a return; statement is allowed, a return; statement is not necessary, and no expression can follow a return; statement in void-functions. The call to a void-function is an executable statement. The result of a call to a void-function may not be assigned to a variable.

37
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

(Technically, a void-function's value at execution is not an r-value.) Execution of a return; statement terminates the function, with control being returned to the caller. Finally, any code after a return statement is not executed. A call to a function with no arguments must have the parentheses following the function name, in contrast to Pascal, where the function name is sufficient. Read the sections 7.2 and 7.4 of Ellis and Stroustrup, The Annotated C++ Reference Manual, Addison Wesley, 1991, reprinted with corrections 1994, ISBN 0-201-5149-1, and sections 11.3.1-11.3.3 in Stroustrup, The design and Evolution of C++ Addison Wesley, 1994 reprinted with corrections, May 1994, or Stroustrup, The C++ Programming Language, 3rd edition Addison Wesley Longman, 1997. for details. 5.2 Call-by-Reference Parameters Recall that value parameters have the value of the argument 'plugged in' for the formal parameter. The text, in Chapter 4, points out that the behavior is exactly that of a local variable that has its initial value provided by the value of the actual argument. Here we are interested in a different mechanism. With call-by-reference, the formal parameter itself automagically2 becomes the actual parameter. The mechanism is that the types are checked, then the address of the actual parameter is copied into the places where the formal parameters (i.e. parameters) would need to be assigned or have their values fetched. When a value needs to be fetched, the value that stored at the address of the caller's actual parameter (i.e. argument) is fetched. When an assignment needs to be made, the value to be assigned is stored into the memory at the address of the caller's actual parameter. (See the discussion in the text in the section Call-by-Reference in Detail of this chapter.) I find that even with fairly weak students a discussion as the summary presented here along with the text's discussion results in a good understanding of these concepts.

automagically is a neologism which means automatically, as if by magic.

38
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

Notice that the syntactic distinction between call-by-reference and call-by-value is the ampersand sign, &, which is between the type-name and the parameter namein the parameter list. This distinction allows us to mix value and reference parameter passing mechanisms. There is no C++ reason for placing the ampersand adjacent to the type, but this is typically C++ programming style, found in most C++ texts and treatises. It is important to note that the ampersand for a reference parameter must be put both into the declaration (prototype) and into the definition of a function using pass-by-reference. One further warning: overloading based on a distinction between a reference parameter and a value parameter was not supported in many early compilers. This has been corrected in more recent compilers. GNU g++ complains about the following code. //file: test1.cc //to check overloading based on distinction between //value parameter and reference parameter of same type. #include <iostream> using namespace std; void f( int &i, int j) { cout << "f(int&, int)" << endl; } void f( int i, int& j){ cout << "f(int, int&)" << endl; } int main() { int i = 1, j = 2; f(i, 1); f(1, j); f(1, 1); f(i, j); return 0; } The error messages are:

39
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

test1.cc: In function `int main()': test1.cc:15: call of overloaded `f (int, int)' test1.cc:7: candidates are: void f(int &, int) test1.cc:8: void f(int, int &) test1.cc:16: call of overloaded `f (int &, int ambiguous test1.cc:7: candidates are: void f(int &, int) test1.cc:8: void f(int, int &) The ISO Standard says this should be an error.

is ambiguous <near match> <near match> &)' is

It should be reiterated that omission of an ampersand & for a variable that should be a reference-parameter is a an error that can be quite difficult to find. 5.3 Using Procedural Abstraction My students do not want to supply pre and post conditions for functions they write. I iterate that without specifications, it is impossible to determine whether the code is correct in any sense other than that it compiles without error and runs without error for some data. No notion of correctness of a solution to a problem is possible without knowing a function's specifications which are expressed in the preconditions and postconditions. Without preconditions, the user cannot determine that the input data is correct. Without postconditions, the user cannot determine whether the output is correct for any data, regardless of whether the data is correct. Correctness may be defined as: 1) having no abnormal termination of the program for data that meets the preconditions on the input, that is, the program should run to a normal successful completion for correct data, and 2) for correct input, the program should generate correct output - output that meets the post conditions for that input data. 3) desirable behavior in response to incorrect data is that the program should behave in a reasonable way. This may mean summary termination in the face of error, or detecting

40
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

errors and giving the user another chance, or behaving in some other fail-safe way (an elevator control, perhaps?) The pre- and post- conditions should be machine testable. Accomplishing this can be difficult in some instances. This is a goal to be sought in writing pre- and post- conditions. Failure to meet this goal means increased difficulty in demonstrating that the program is correct. 5.4 Testing and Debugging Functions Testing is essential to the process of writing correct code. There are two ways to test code. One follows the top-down design technique, where the first step is to divide the problem into subproblems. The condition on the subproblems is that if each is solved, the original problem is solved. Note that it is desirable to test before doing a lot of programming. How? The main program can be written, then tested independently of the subprograms by writing 'stub' subprograms - small subprograms that do little more than return fictitious data that the calling function needs to be able to continue, and (at least in my programming) emits a message that lets the tester know that the subprogram has been encountered. These stub subprograms should simple enough that correctness is not a problem. This technique allows part of a program to be tested before the rest of it has been tested, or perhaps before the subprograms have been written. The other technique is bottom up: test the functions independently of the calling program. How? Write a driver - a main program or calling program substitute - that exercises the subprogram with data that a correct calling program might present to the subprogram during execution. In fact, incorrect data should also be used to test the robustness of the subprogram. Proper selection of data is essential to the success of this testing technique.

41
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Savitch Problem Solving w/ C++, 6e

Instructors Resource Guide Chapter 5

These testing techniques are useful to the extent that the client program author and the subprogram program author use procedural abstraction. This means that the specifications of the subprogram is all that is known to the client, and, beyond the specifications, any use to which the subprogram in put is not known to the subprogram author. Dividing a program into separate pieces, which are tested apart from each other, is a useful technique independently of pre and post- conditions. However, the testing is limited if exact conditions are not known. Clearly, a specification of input, output and action for all functions is essential to the ability to full use of this testing technique.

42
Copyright 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley

Vous aimerez peut-être aussi