Download as pdf or txt
Download as pdf or txt
You are on page 1of 154

DalePhatANS_complete 8/18/04 10:30 AM Page 1049

Answers to
Selected Exercises
Chapter 1 Exam Preparation Exercises
1. a. v, b. i, c. viii, d. iii, e. iv, f. vii, g. vi, h. ii.
2. Analysis and specification, general solution (algorithm), verify.
3. Concrete solution (program), test.
4. The analysis and specification step within the problem-solving phase.
5. The steps never end. Changing the last step to say, “Repeat from first step until gradua-
tion,” converts the sequence into an algorithm that eventually ends, assuming the person
will graduate from school some day. We can make sure that this loop ends by specifying
a condition that will definitely occur. For example, “Repeat from first step until last day
of classes.”
6. a. vi, b. ii, c. v, d. i, e. vii, f. iv.
7. The program can be compiled on different computer systems without modification.
8. The control unit directs the actions of the other components in the computer to execute
program instruction in the proper order.
9. False. The editor is software rather than hardware.
10. False. Peripheral devices are external to the CPU and its main memory.
11. Yes. If the software license restricts use to a single computer or a single user, then this is
a case of piracy, even though you split the cost.
12. a. ii, b. v, c. iii, d. vii, e. i, f. vi, g. iv.

Chapter 1 Programming Warm-Up Exercises


1. Branches: Steps n1, n2, and n3. There are two loops: steps p, q, and r; and steps t and u.
Steps a, c, and e are references to subalgorithms defined elsewhere.
DalePhatANS_complete 8/18/04 10:30 AM Page 1050

1050 | Answers to Selected Exercises

2. follow separate algorithm for filling glass with water and placing on counter
If right-handed,
pick up toothpaste tube in left hand and unscrew cap by turning counter-clockwise
place toothpaste cap on counter
transfer toothpaste tube to right hand and pick up toothbrush in left hand, holding it by its
handle
place open end of toothpaste tube against tips of brush bristles and squeeze toothpaste tube
just enough to create a 0.5-inch-long extrusion of toothpaste on brush
pull toothpaste tube away from brush and place tube on counter
transfer toothbrush to right hand, holding it by its handle
open mouth and insert brush, placing toothpaste-covered bristles against one tooth
scrub tooth with brush by moving brush up and down 10 times
reposition brush to an unscrubbed tooth
repeat previous two steps until all teeth have been brushed
spit toothpaste into sink
put toothbrush in sink
pick up glass in right hand
fill mouth with water from glass
swish water in mouth for five seconds
spit water from mouth into sink
repeat previous three steps three times
Otherwise (if left-handed)
pick up toothpaste tube in right hand and unscrew cap by turning counter-clockwise
place toothpaste cap on counter
transfer toothpaste tube to left hand and pick up toothbrush in right hand, holding it by its
handle
place open end of toothpaste tube against tips of brush bristles and squeeze toothpaste tube
just enough to create a 0.5-inch-long extrusion of toothpaste on brush
pull toothpaste tube away from brush and place tube on counter
transfer toothbrush to left hand, holding it by its handle
open mouth and insert brush, placing toothpaste-covered bristles against one tooth
scrub tooth with brush by moving brush up and down 10 times
reposition brush to an unscrubbed tooth
repeat previous two steps until all teeth have been brushed
spit toothpaste into sink
put toothbrush in sink
pick up glass in left hand
fill mouth with water from glass
swish water in mouth for five seconds
spit water from mouth into sink
repeat previous three steps three times
Place glass on counter
Follow separate algorithm for cleaning up after brushing teeth
DalePhatANS_complete 8/18/04 10:30 AM Page 1051

Answers to Selected Exercises | 1051

3. The test for right- or left-handedness is a branch. Each branch contains two loops, one
that iterates until all teeth are brushed and another that iterates rinsing four times. The
first and last steps refer to separately defined subalgorithms.
4. Change step u to:
u. Repeat step t nine times.

Chapter 1 Case Study Follow-Up Exercises


1. a. 1900 No
b. 2000 Yes
c. 1996 Yes
d. 1998 No
2. a. 1900 Line = 6
b. 1945 Line = 2
c. 1600 Line = 7
d. 1492 Line = 4
e. 1776 Line = 4
3. Divide by 1000 and see if the remainder is 0.
4. I was not, but your answer may be different.
5. Keep adding 1 to the year and test it until you find the next leap year. Another algo-
rithm would be to use the following:
nextYear = year + (year % 4)
divide the nextYear by 100 and if the remainder isn’t 0,
Write that nextYear is the next leap year
Otherwise, divide the nextYear by 400 and if the remainder isn’t 0
Write that (nextYear + 4) is the next leap year
Otherwise nextYear is the next leap year
6. Line Number
{
__1___ if (year % 4 != 0)
__2___ return false;
__3___ else if (year % 100 != 0)
__4___ return true;
__5___ else if (year % 400 != 0)
__6___ return false;
__7___ else return true;
}

Chapter 2 Exam Preparation Exercises


1. a. valid, b. invalid (hyphens not allowed), c. invalid (reserved words not allowed), d. valid,
e. valid, f. valid, g. invalid (must begin with a letter), h. invalid (# is not allowed).
2. a. vi, b. ix, c. iv, d. v, e. vii, f. ii, g. i, h. x, i. iii, j. viii.
3. False.
DalePhatANS_complete 8/18/04 10:30 AM Page 1052

1052 | Answers to Selected Exercises

4. The template allows an identifier to begin with a digit. Identifiers can begin with a letter
or an underscore, and digits may appear only in the second character position and
beyond.
5. False.
6. True.
7. True.
8. Note that the second line concatenates two words without a separating space.
Four score and
seven years agoour fathers
brought forth on this
continent a new nation...

9. ”Bjarne Stroustrup named his new programming language C++ because it is a successor
to the C programming language.”
10. By preceding it with a backslash character (\”).
11. If we forget the */ at the end of a comment, then any number of lines of program code
can be inadvertently included in the comment. The // form avoids this by automatically
terminating at the end of the line.
12. The // form of comment cannot span more than one line. It also cannot be inserted into
the middle of a line of code because everything to the right of // becomes a comment.
13. << is the stream insertion operator, and is pronounced “put to” or “is sent,” as in “cout is
sent string4.”
14. No. The endl identifier is a manipulator, and is not a string value.
15. It tells the C++ preprocessor to insert the contents of a specified file at that point in the
code.
16. std::cout << "Hello everybody!" << std::endl;
17. A block.
18. By splitting it into pieces that fit on a line, and joining them with the concatenation
operator.
19. #include <iostream>
#include <string>

using namespace std;

const string TITLE = "Dr.";


int main()
{
cout << "Hello " + TITLE + " Stroustrup!";
}

Chapter 2 Programming Warm-Up Exercises


1. Substitute the actual data in the following:
cout << "July 4, 2004" << endl;
DalePhatANS_complete 8/18/04 10:30 AM Page 1053

Answers to Selected Exercises | 1053

2. Note that the \" escape sequence is needed in six places here:
cout << "He said, \"How is that possible?\"" << endl
<< "She replied, \"Using manipulators.\"" << endl
<< "\"Of course,\" he exclaimed!" << endl;
3. a. const string ANSWER = "True";
b. char middleInitial;
c. string courseTitle;
d. const char PERCENT = '%'
4. const string FIRST = "Your first name inserted here";
const string LAST = "Your last name inserted here";
// Insert your middle initial in place of A:
const char MIDDLE = 'A';

5. cout << PART1 << PART2 << PART1 << PART3;


6. PART1 + PART2 + PART1 + PART3
7. cout << "Yet the web of thought has no such creases"
<< endl;
cout << "And is more like a weaver's masterpieces;"
<< endl;
cout << "One step a thousand threads arise," << endl;
cout << "Hither and thither shoots each shuttle," << endl;
cout << "The threads flow on unseen and subtle," << endl;
cout << "Each blow effects a thousand ties." << endl;

8. #include <iostream>
#include <string>

using namespace std;

const string TITLE = "Rev.";


const char FIRST = 'H';
const char MID 'G';
const char DOT = '.';

int main()
{
cout << TITLE << FIRST << DOT << MID << DOT
<< " Jones";
}

9. The solution to this problem is for the student to show that he or she has run the pro-
gram correctly. It should output:
***********************************
* *
* Welcome to C++ Programming! *
* *
***********************************
DalePhatANS_complete 8/18/04 10:30 AM Page 1054

1054 | Answers to Selected Exercises

Chapter 2 Case Study Follow-Up


1. const string BLACK = "%%%%%%%%"; // Define a line of a black square
2. const string WHITE = "........"; // Define a line of a white square
3. Move the first five output statements to the end of the program.
4.
const string BLACK = "**********"; // Define a line of a black square
const string WHITE = " "; // Define a line of a white square

5.
//******************************************************************
// Chessboard program
// This program prints a chessboard pattern that is built up from
// basic strings of white and black characters.
//******************************************************************

#include <iostream>
#include <string>

using namespace std;

const string BLACK = "********"; // Define a line of a black square


const string WHITE = " "; // Define a line of a white square
const string BLACK_BLANK = "** **"; // Define a constant of embedded
// blanks
int main ()
{
string whiteRow; // A row beginning with a white square
string blackRow; // A row beginning with a black square
string blackBlankRow; // A black first row with mixed squares
string whiteBlankRow; // A white first row with mixed squares

// Create a white-black row by concatenating the basic strings

whiteRow = WHITE + BLACK + WHITE + BLACK +


WHITE + BLACK + WHITE + BLACK;

// Create a white-black row with interior blanks in the blacks

whiteBlankRow = WHITE + BLACK_BLANK + WHITE + BLACK_BLANK +


WHITE + BLACK_BLANK + WHITE + BLACK_BLANK;

// Create a black-white row with interior blanks in the blacks


blackBlankRow = BLACK_BLANK + WHITE + BLACK_BLANK + WHITE +
BLACK_BLANK + WHITE + BLACK_BLANK + WHITE;
DalePhatANS_complete 8/18/04 10:30 AM Page 1055

Answers to Selected Exercises | 1055

// Create a black-white row by concatenating the basic strings

blackRow = BLACK + WHITE + BLACK + WHITE +


BLACK + WHITE + BLACK + WHITE;

// Print five white-black rows

cout << whiteRow << endl;


cout << whiteRow << endl;
cout << whiteBlankRow << endl;
cout << whiteBlankRow << endl;
cout << whiteRow << endl;

// Print five black-white rows

cout << blackRow << endl;


cout << blackRow << endl;
cout << blackBlankRow << endl;
cout << blackBlankRow << endl;
cout << blackRow << endl;

// Print five white-black rows

cout << whiteRow << endl;


cout << whiteRow << endl;
cout << whiteBlankRow << endl;
cout << whiteBlankRow << endl;
cout << whiteRow << endl;

// Print five black-white rows

cout << blackRow << endl;


cout << blackRow << endl;
cout << blackBlankRow << endl;
cout << blackBlankRow << endl;
cout << blackRow << endl;

// Print five white-black rows

cout << whiteRow << endl;


cout << whiteRow << endl;
cout << whiteBlankRow << endl;
cout << whiteBlankRow << endl;
cout << whiteRow << endl;
DalePhatANS_complete 8/18/04 10:30 AM Page 1056

1056 | Answers to Selected Exercises

// Print five black-white rows

cout << blackRow << endl;


cout << blackRow << endl;
cout << blackBlankRow << endl;
cout << blackBlankRow << endl;
cout << blackRow << endl;

// Print five white-black rows

cout << whiteRow << endl;


cout << whiteRow << endl;
cout << whiteBlankRow << endl;
cout << whiteBlankRow << endl;
cout << whiteRow << endl;

// Print five black-white rows

cout << blackRow << endl;


cout << blackRow << endl;
cout << blackBlankRow << endl;
cout << blackBlankRow << endl;
cout << blackRow << endl;

return 0;
}

6. There are 64 characters per line, except for the results of Exercise 4, which would have
80 characters per line.

Chapter 3 Exam Preparation Exercises


1. They are simple data types.
2. char, short, int, long.
3. Integer overflow.
4. E signifies an exponent in scientific notation. The digits to the left of the E are multiplied
by 10 raised to the power given by the digits to the right of the E.
DalePhatANS_complete 8/18/04 10:30 AM Page 1057

Answers to Selected Exercises | 1057

5.
integer / constant /
floating variable
a. const int TRACKS_ON_DISK = 17; integer constant
b. float timeOfTrack; floating variable
c. const float MAX_TIME_ON_DISK = 74.0; floating constant
d. short tracksLeft; integer variable
e. float timeLeft; floating variable
f. long samplesInTrack; integer variable
g. const double SAMPLE_RATE = 262144.5; floating constant
6. Integer division with an integer result, and floating division with a floating result.
7. a. 21, b. 21.6, c. 13.0, d. 18, e. 20, f. 22, g. 18.0.
8. () unary - [ * / % ] [ + - ]
9. True.
10. a. vi, b. ii, c. vii, d. iv, e. i, f. v, g. iii.
11. The ++ operator.
12. You write the name of a data type, followed by an expression enclosed in parentheses.
13. main returns an int value.
14. 215.00
15. False. When used alone they are equivalent, but used within a larger expression, they can
give different results (this is explained more in Chapter 10).
16. string::size_type
17. a. 29
b. 1
c. "ought to start with logic"
d. 0
e. "log"
f. 1
g. string::npos
18. It tells the stream to print floating-point numbers without using scientific notation.

Chapter 3 Programming Warm-Up Exercises


1. (hours * 60 + minutes) * 60 + seconds
2. a. days / 7
b. days % 7
3. dollars * 100 + quarters * 25 + dimes *10 + nickels * 5 + pennies
4. float(dollars * 100 + quarters * 25 + dimes *10 +
nickels * 5 + pennies) / 100.0
5. count = count + 3;
6. a. 3 * X + Y
b. A * A + 2 * B + C
c. ((A + B)/(C – D)) * (X / Y)
d. ((A * A + 2 * B + C)/D) / (X * Y)
DalePhatANS_complete 8/18/04 10:30 AM Page 1058

1058 | Answers to Selected Exercises

e. sqrt(fabs(A – B))
f. pow(X, -cos(Y))
7. string temp;
temp = sentence;
first = temp.find("and"); // Get first location

// Remove first section of string

temp = temp.substr(first + 3, temp.length() – (first + 3));

// Find second location of "and" in shortened string

second = temp.find("and");

// Remove next section of string

temp = temp.substr(second + 3, temp.length() – (second + 3));

// Adjust second to account for deleting first part of string

second = second + first + 3;

// Locate third "and" and adjust for prior deletions

third = temp.find("and") + second + 3;


8. startOfMiddle = name.find(' ') + 1;
9. cout << "$" << fixed << setprecision(2) << setw(8) << money;
10. cout << setprecision(5) << setw(15) << distance;
11. #include <climits>
cout << "INT_MAX = " << INT_MAX << " INT_MIN = " << INT_MIN;

12. //**********************************************
// Celsius program
// This program outputs the Celsius temperature
// corresponding to a given Fahrenheit temperature
//**********************************************

#include <iostream>

using namespace std;

int main()
{
const float FAHRENHEIT = 72.0;
DalePhatANS_complete 8/18/04 10:30 AM Page 1059

Answers to Selected Exercises | 1059

float celsius;

celsius = 5/9 * (FAHRENHEIT – 32);


cout << fixed << "Celsius equivalent of Fahrenheit "
<< FAHRENHEIT << " is " << celsius << " degrees.";
return 0;
}

Chapter 3 Case Study Follow-Up


1. cout << fixed << setprecision(2) << "For a loan amount of "
<< LOAN_AMOUNT << " with an interest rate of "
<< setprecision(4) << YEARLY_INTEREST << " and a "
<< NUMBER_OF_YEARS << " year mortgage, " << endl;
cout << "your monthly payments are $" << setprecision(2)
<< payment << "." << endl;

2. Change the NUMBER_OF_YEARS to NUMBER_OF_MONTHS with the value 84. Remove num-
berOfPayments and substitute NUMBER_OF_MONTHS where numberOfPayments
occurs. Change
...
const float LOAN_AMOUNT = 50000.00; // Amount of the loan
const float YEARLY_INTEREST = 0.0524; // Yearly interest rate
const int NUMBER_OF_MONTHS = 84; // Total number of payments

int main()
{
// local variables

float monthlyInterest; // Monthly interest rate


float payment; // Monthly payment

// Calculate values

monthlyInterest = YEARLY_INTEREST / 12;


payment = (LOAN_AMOUNT * pow(monthlyInterest + 1,
NUMBER_OF_MONTHS)
* monthlyInterest)/(pow(monthlyInterest + 1, NUMBER_OF_MONTHS)
- 1 );

// Output results

cout << fixed << setprecision(2) << "For a loan amount of "
<< LOAN_AMOUNT << " with an interest rate of "
<< setprecision(4) << YEARLY_INTEREST << " and a "
DalePhatANS_complete 8/18/04 10:30 AM Page 1060

1060 | Answers to Selected Exercises

<< NUMBER_OF_MONTHS << " month mortgage, " << endl;


cout << "your monthly payments are $" << setprecision(2)
<< payment << "." << endl;
...
}

3. ...
const float LOAN_AMOUNT = 50000.00; // Amount of the loan
const float YEARLY_INTEREST = 5.24; // Yearly interest rate
const int NUMBER_OF_MONTHS = 84; // Total number of payments

int main()
{
// local variables
float monthlyInterest; // Monthly interest rate
float payment; // Monthly payment

// Calculate values
monthlyInterest = YEARLY_INTEREST * 0.01 / 12;
payment = (LOAN_AMOUNT * pow(monthlyInterest + 1,
NUMBER_OF_MONTHS)
* monthlyInterest)/(pow(monthlyInterest + 1, NUMBER_OF_MONTHS)
- 1 );

// Output results
cout << fixed << setprecision(2) << "For a loan amount of "
<< LOAN_AMOUNT << " with an interest rate of "
<< YEARLY_INTEREST << " and a "
<< NUMBER_OF_MONTHS << " month mortgage, " << endl;
cout << "your monthly payments are $" << payment << "."
<< endl;
...
}

4. ...
float onePlus; // Monthly interest plus 1

// Calculate values

monthlyInterest = YEARLY_INTEREST * 0.01 / 12;

onePlus = monthlyInterest + 1;
payment = (LOAN_AMOUNT * pow(onePlus, NUMBER_OF_MONTHS) *
monthlyInterest/(pow(onePlus, NUMBER_OF_MONTHS) - 1;

...
DalePhatANS_complete 8/18/04 10:30 AM Page 1061

Answers to Selected Exercises | 1061

If an expression is duplicated more than twice, it probably should be calculated and


saved. If an expression is used only twice but is a complex expression, it probably
should be calculated and saved. The duplicate expression in this program is simple and
is used only twice; it probably isn’t worth the extra storage.

Chapter 4 Exam Preparation Exercises


1. False. The two statements input the values in reverse order with respect to the single
statement’s inputs.
2. a. The insertion operator cannot be used with cin.
b. The extraction operator cannot be used with cout.
c. The right operand of the extraction operator must be a variable.
d. The arguments are in reverse order.
e. The function name should not have a capital L, and the arguments are reversed.
3. a = 70, b = 80, c = 30, d = 40, e = 50, f = 60.
4. a = 70, b = 80, c = 30, d = 0, e = 20, f = 30.
5. a. string1 = "January", string2 = "25,"
b. The reading marker is on the space following the comma.
6. a. string1 = "January 25, 2005"
b. The reading marker is at the start of the next line.
7. a. string1 = "January", int1 = 25, char1 = ',',
string2 = "2005"

b. The reading marker is on the newline character at the end of the line.
8. It returns \n.
9. The first argument is a maximum number of characters to skip over. The second argu-
ment specifies a character that the function searches for. If it finds the character before
skipping the maximum number of characters, then it stops with the reading marker on
the following character.
10. Some variation in the answer is acceptable, as long as it is clear that the prompt for the
inexperienced user is much more detailed.
a. cout << "Enter a date in the format of mm/dd/yyyy."
<< " For example, for October 18, 1989, enter 10/18/1989.";
b. cout << "Enter date, format mm/dd/yyyy.";
11. Include the header file fstream. Declare the file stream. Prepare the file with open.
Specify the name of the file stream in each I/O statement.
12. ifstream and ofstream.
13. The first statement declares inFile to be an input file stream. The second statement
opens inFile, associating it with a file called datafile.dat by the operating system.
14. The correction is to convert the name into a C string.
ifstream inData;
string name;

cout << "Enter the name of the file: ");


cin >> name;
infile.open(name.c_str());
DalePhatANS_complete 8/18/04 10:30 AM Page 1062

1062 | Answers to Selected Exercises

15. The input operation is ignored.


16. False. The file immediately enters the fail state, and I/O operations on it are simply
ignored.
17. False. If the file doesn’t exist, it can open in the fail state.
18. The answer can vary, but should at least include vehicle, customer, and agency. A little
more thought might add garage, repair shop, contract, and so on.
19. The class.
20. a. A step for which the implementation details are fully specified.
b. A step for which some implementation details remain to be specified.
c. A self-contained series of steps that solves a given problem or subproblem.
d. A module that performs the same operation as the abstract step it defines.
e. A property of a module in which the concrete steps are all directed to solving just one
problem, and any significant subproblems are written as abstract steps.
21. The function.
22. a. no, b. yes, c. yes, d. no, e. no.
23. True.

Chapter 4 Programming Warm-Up Exercises


1. cin >> int1 >> int2 >> int3;
2. cout << "Enter a name in the format: first middle last:";
cin >> first >> middle >> last;

3. cout << "Enter a name in the format: first middle last:";


getline(cin, name);

4. float number1;
float number2;
float number3;
float average;

cout << "Enter the first number and press return: ";
cin >> number1;
cout << "Enter the second number and press return: ";
cin >> number2;
cout << "Enter the third number and press return: ";
cin >> number3;
average = (number1 + number2 + number3) / 3.0;
cout << "The average is: " << average << endl;

5. float number1;
float number2;
float number3;
float average;

cout << "Enter the three numbers separated by spaces: ";


cin >> number1 >> number2 >> number3;
DalePhatANS_complete 8/18/04 10:30 AM Page 1063

Answers to Selected Exercises | 1063

average = (number1 + number2 + number3) / 3.0;


cout << "The average is: " << average << endl;

6. The names of the variables may differ from those shown here. Instead of using the ignore
function to skip a single character, reading into a dummy char variable may also be
used.
a. int int1;
char char1;
float float1;

cin >> int1 >> char1 >> float1;

b. string string1;
string string2;
int int1;
int int2;

cin >> string1 >> int1 >> string2 >> int2;

c. int int1;
int int2;
float float1;

cin >> int1;


cin.ignore(1, ',');
cin >> int2;
cin.ignore(1, ',');
cin >> float1;

d. char char1;
char char2;
char char3;
char char4;

cin >> char1;


cin.ignore(1, ' ');
cin >> char2;
cin.ignore(1, ' ');
cin >> char3;
cin.ignore(1, ' ');
cin >> char4;
cin.ignore(1, ' ');

e. float float1;

cin.ignore(1, '$');
cin >> float1;
DalePhatANS_complete 8/18/04 10:30 AM Page 1064

1064 | Answers to Selected Exercises

7. In this solution the comma is included as part of the city name.


cin >> streetNum >> street1 >> street2 >> town >> state >> zip;

8. #include <fstream>
fstream temps;
temps.open("temperatures.dat");

9. An alternative approach is to declare one temp variable that is reused for each of six
input statements, and keep a running total of the input values.
float temp1;
float temp2;
float temp3;
float temp4;
float temp5;
float temp6;
float average;

temps >> temp1 >> temp2 >> temp3 >> temp4 >> temp15 >> temp6;
average = (temp1 + temp2 + temp3 + temp4 + temp5 + temp6) / 6.0;
cout << "The average temperature is: " << average;

10. #include <iostream>


#include <fstream>

using namespace std;

fstream inData;
fstream outData;
const float PI = 3.14159265;
float radius;
float circumference;
float area;

int main()
{
inData.open("indata.dat");
outData.open("outdata.dat");
inData >> radius;
circumference = radius * 2 * PI;
area = radius * radius * PI;
cout << "For the first circle, the circumference is "
<< circumference << " and the area is " << area << endl;
outData << radius << " " << circumference << " " << area << endl;
inData >> radius;
DalePhatANS_complete 8/18/04 10:30 AM Page 1065

Answers to Selected Exercises | 1065

circumference = radius * 2 * PI;


area = radius * radius * PI;
cout << "For the second circle, the circumference is "
<< circumference << " and the area is " << area << endl;
outData << radius << " " << circumference << " " << area << endl;
}

11. Changed lines are underlined.


#include <iostream>
#include <fstream>

using namespace std;

fstream inData;
fstream outData;
const float PI = 3.14159265;
float radius;
float circumference;
float area;
string filename;

int main()
{
inData.open("indata.dat");
cout << "Enter the name of the file to open: ";

cin >> filename;

outData.open(filename.c_str());

// The remainder of the program is unchanged

12. inFile >> int1 >> int2 >> int3;


13. cout << "Enter the name of the file to open: ";
cin >> filename;
userFile.open(filename.c_str());

14.
Top level:

Write letter
Mail letter
DalePhatANS_complete 8/18/04 10:30 AM Page 1066

1066 | Answers to Selected Exercises

Level 2
Write letter

Write return address and date


Write company address
Write salutation
Write body of letter
Write closing
Sign letter

Mail letter

Address envelope
Write return address
Attach stamp to envelope
Fold letter in thirds
Insert letter in envelope
Seal envelope
Place envelope in mail box

15. Letter and envelope are the main objects. Other objects include: return address, company
address, salutation, letter body, closing, signature, stamp, and mail box.

Chapter 4 Case Study Follow-Up


1. The answer will vary with each student.
2. // Output information in required formats
outData << socialNum << endl;
outData << " " << firstName << ' ' << middleName << ' '
<< lastName << ' ' << endl;
outData << " " << lastName << ", " << firstName << ' '
<< middleName << ' ' << endl;
outData << " " << lastName << ", " << firstName << ' '
<< initial << ' ' << endl;
outData << " " << firstName << ' ' << initial << ' '
<< lastName;

3. #include <iostream> // Access cin and cout


#include <fstream> // Access open
...
// Declare and open files

ifstream inData;
ofstream outData;
string fileName;
cout << "Enter the name of the input file: ";
DalePhatANS_complete 8/18/04 10:30 AM Page 1067

Answers to Selected Exercises | 1067

cin >> fileName;


inData.open(fileName.c_str());
outData.open("name.out");
...

4. #include <iostream> // Access cin and cout


#include <fstream> // Access open
...
// Declare and open files
ifstream inData;
ofstream outData;
string fileName;
cout << "Enter the name of the input file: ";
cin >> fileName;
inData.open(fileName.c_str());
cout << "Enter the name of the output file: ";
cin >> fileName;
outData.open(fileName.c_str());
...

5. //******************************************************************
// Mortgage Payment Calculator program
// This program determines the monthly payments on a mortgage given
// the loan amount, the yearly interest, and the number of years.
//******************************************************************

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main()
{
// Input variables

float loanAmount;
float yearlyInterest;
int numberOfYears;

// local variables

float monthlyInterest;
int numberOfPayments;
float payment;
DalePhatANS_complete 8/18/04 10:30 AM Page 1068

1068 | Answers to Selected Exercises

// Prompt for and read input values

cout << "Input the total loan amount (ex: 50000.00)" << endl;
cin >> loanAmount;
cout << "Input the interest rate (ex: 6.25)" << endl;
cin >> yearlyInterest;
cout << "Enter the number of years for the loan (ex: 15)"
<< endl;
cin >> numberOfYears;

// Calculate values

monthlyInterest = yearlyInterest * 0.01/ 12.0;


numberOfPayments = numberOfYears * 12;
payment = (loanAmount *
pow(1 + monthlyInterest, numberOfPayments)
* monthlyInterest)/
( pow(1 + monthlyInterest, numberOfPayments) - 1 );

// Output results

cout << fixed << setprecision(2) << "For a loan amount of "
<< loanAmount
<< " with an interest rate of " << yearlyInterest
<< " and a "
<< numberOfYears << " year mortgage, " << endl;
cout << fixed << setprecision(2)
<< "your monthly payments are $"
<< payment << "." << endl;
return 0;
}

Chapter 5 Exam Preparation Exercises


1. The order in which the computer executes statements in a program.
2. False. They are predefined constants.
3. False. It is >=.
4. Because, in the collating sequence of the character set, the uppercase letters all come
before the lowercase letters.
5. a. true
b. true
c. true
d. false
e. false
DalePhatANS_complete 8/18/04 10:31 AM Page 1069

Answers to Selected Exercises | 1069

f. true
g. true
6. a. true
b. true
c. true
d. true
e. true
f. false
g. false
7. Because conditional or short-circuit evaluation prevents the second part of the expres-
sion from being evaluated when someInt is 0.
8. True.
9. False. The parentheses are required.
10. It outputs “The data doesn't make sense."
11. It outputs The word may be "The"
12. Nothing.
13. Because the test is written with = instead of ==, so the expression is always false.
14. It outputs Very good
15. Very goodExcellent
16. Add braces to enclose the If-Then statement.
17. !inData
18. There is no limit, although a human reader finds it difficult to follow too many levels.

Chapter 5 Programming Warm-Up Exercises


1. moon == "blue" || moon == "Blue"
2. !inFile1 && !inFile2
3. if (inFile)
cin >> someString;

4. if (year1 < year2 && month1 < month2 && day1 < day2)
cout << month1 << "/" << day1 << "/" year1
<< " comes before "
<< month2 << "/' << day2 << "/" << year2;
else
cout << month1 << "/" << day1 << "/" year1
<< " does not come before "
<< month2 << "/' << day2 << "/" << year2;

5. if (year1 < year2 && month1 < month2 && day1 < day2)
cout << month1 << "/" << day1 << "/" year 1
<< " comes before "
<< month2 << "/' << day2 << "/" << year2;
else
{
cout << month1 << "/" << day1 << "/" year1
<< " does not come before "
DalePhatANS_complete 8/18/04 10:31 AM Page 1070

1070 | Answers to Selected Exercises

<< month2 << "/' << day2 << "/" << year2;
month1 = month2;
day1 = day2;
year1 = year2;
}

6. bool1 || bool2 && !(bool1 && bool2)


7. if (score < 0 || score > 100)
cout << "Score is out of range";

8. if (score < 0 || score > 100)


cout << "Score is out of range";
else
{
scoreTotal = scoreTotal + score;
scoreCount++;
}

9. infile1 >> value1;


infile2 >> value2;
if (!infile1 && !infile2)
cout << "File error.";
else if (!infile1 || !infile2)
if (infile1)
outfile << value1;
else
outfile << value2;
else
if (value1 < value2);
{
outfile << value1;
infile1 >> value1;
}
else
{
outfile << value2;
infile2 >> value2;
}

10. if (score > 100)


cout << "Duffer.";
else if (score > 80)
cout << "Weekend regular.";
else if (score > 72)
cout << "Competitive player.";
else if (score > 68)
cout << "Turn pro!";
else
DalePhatANS_complete 8/18/04 10:31 AM Page 1071

Answers to Selected Exercises | 1071

cout << "Time to go on tour!";

11. if (count1 <= count2 && count1 <= count3)


{
cout << count1;
if (count1 == count2)
cout << count2;
if (count1 == count3)
cout << count3;
}
else if (count2 <= count3)
{
cout << count2;
if (count2 == count3)
cout << count3;
}
else
cout << count3;

12. The conditional tests are using = instead of ==. Both branches have the error, but the sec-
ond one doesn’t output the message because the result of the assignment expression is 0,
which is treated as false by the branch.
maximum = 75;
minimum = 25;
if (maximum == 100)
cout << "Error in maximum: " << maximum << endl;
if (minimum == 0)
cout << "Error in minimum: " << minimum << endl;

13. if (area < 0)


{
area = -area;
root = sqrt(area);
}
else
root = sqrt(area);

14. Values of temp that should be tried are: 213, 212, 211, 33, 32, 31.
15. Combinations of values for month, day, and year that should be tested are as follows:

Month Day Year


1 27 2003 Tests first condition of first branch not taken
1 29 2003 Tests second condition of first branch not taken
2 29 2003 Tests first branch taken, second branch taken
2 29 2004 Tests first branch taken, second not taken
2 30 2004 Tests first branch taken, second not taken, third taken
DalePhatANS_complete 8/18/04 10:31 AM Page 1072

1072 | Answers to Selected Exercises

Chapter 5 Case Study Follow-Up


1. You could plug the BMI cut-off value and a value for weight into the formula and solve
it for the height; however, the body mass index is calculated using real arithmetic. The
number of decimal places must be very accurate to get the exact BMI value for which
you are looking. A better choice is to round the BMI value so that you are testing two
integers.
2. There is no unique answer, but the following values will work.
120, 64
140, 62
150, 59
160, 59
3. //******************************************************************
// BMI Program
// This program calculates the body mass index (BMI) given a weight
// in pounds and a height in inches and prints a health message
// based on the BMI. Input in metric measures.
//******************************************************************

#include <iostream>

using namespace std;

int main()
{

float weight; // Weight in kilograms


float height; // Height in meters
float bodyMassIndex; // Appropriate BMI
bool dataAreOK; // True if data non-negative

// Prompt for and input weight and height

cout << "Enter your weight in kilograms. " << endl;


cin >> weight;
cout << "Enter your height in meters. " << endl;
cin >> height;

// Test Data

if (weight < 0 || height < 0)


dataAreOK = false;
else
dataAreOK = true;
DalePhatANS_complete 8/18/04 10:31 AM Page 1073

Answers to Selected Exercises | 1073

if (dataAreOK)
{
// Calculate body mass index

bodyMassIndex = weight / (height * height);

// Print message indicating status

cout << "Your body mass index is " << bodyMassIndex << ". "
<< endl;
cout << "Interpretation and instructions. " << endl;
if (bodyMassIndex < 18.5)
cout << "Underweight: Have a milkshake." << endl;
else if (bodyMassIndex < 25.0)
cout << "Normal: Have a glass of milk." << endl;
else if (bodyMassIndex < 30.0)
cout << "Overweight: Have a glass of iced tea." << endl;
else
cout << "Obese: See your doctor." << endl;
}
else
cout << "Invalid data; weight and height must be positive."
<< endl;
return 0;
}

4. //******************************************************************
// BMI Program
// This program calculates the body mass index (BMI) given a weight
// in pounds and a height in feet and inches and prints a health
// based message on the BMI. Input in English measures.
//******************************************************************

#include <iostream>

using namespace std;

int main()
{
const int BMI_CONSTANT = 703; // Constant in nonmetric formula
float weight; // Weight in pounds
float inches; // Remainder of height in inches
float feet; // Height in feet
float height; // Complete height in inches
float bodyMassIndex; // Appropriate BMI
bool dataAreOK; // True if data non-negative
DalePhatANS_complete 8/18/04 10:31 AM Page 1074

1074 | Answers to Selected Exercises

// Prompt for and input weight and height

cout << "Enter your weight in pounds: " ;


cin >> weight;
cout << "Enter your height in feet and inches. " << endl;
cout << "Feet: " ;
cin >> feet;
cout << "Inches: " ;
cin >> inches;
height = feet * 12 + inches;

// Test Data

if (weight < 0 || height < 0)


dataAreOK = false;
else
dataAreOK = true;

if (dataAreOK)
{
// Calculate body mass index

bodyMassIndex = weight * BMI_CONSTANT /


(height * height);

// Print message indicating status

cout << "Your body mass index is " << bodyMassIndex


<< ". " << endl;
cout << "Interpretation and instructions. " << endl;
if (bodyMassIndex < 18.5)
cout << "Underweight: Have a milkshake." << endl;
else if (bodyMassIndex < 25.0)
cout << "Normal: Have a glass of milk." << endl;
else if (bodyMassIndex < 30.0)
cout << "Overweight: Have a glass of iced tea."
<< endl;
else
cout << "Obese: See your doctor." << endl;
}
else
cout << "Invalid data; weight and height "
<< "must be positive." << endl;
return 0;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1075

Answers to Selected Exercises | 1075

5. The weight and height are checked to be sure they are not negative before the BMI is cal-
culated in this program. There are several other things that could be done. For example,
if the weight is less than the height, then there is an error. In fact, if the weight is less
than one and a half times the height, there is a good chance that there is an error. This
condition produces very low BMIs. What about weights that are six or seven times the
height? These produce very high BMIs. Another approach would be to put a check on
the BMI itself. If it is below 10 or greater than 60, there is a good chance of input errors.

Chapter 6 Exam Preparation Exercises


1. False.
2. False.
3. True.
4. a. ii, b. ix, c. iv, d. viii, e. vi, f. i, g. v, h. vii, i. iii.
5. Twelve times.
1
2
3
4
5
6
7
8
9
10
11
12

6. Twelve times.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,

7. Twelve times.
$1.00
$2.00
$3.00
$4.00
$5.00
$6.00
$7.00
$8.00
$9.00
$10.00
$11.00
$12.00
DalePhatANS_complete 8/18/04 10:31 AM Page 1076

1076 | Answers to Selected Exercises

8. The output is:


@
@@
@@@
@@@@
@@@@@
@@@@@@
@@@@@@@
@@@@@@@@
@@@@@@@@@
@@@@@@@@@@
@@@@@@@@@@@

9. The output is:


1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100

10. The code fails to process the first value on the file. The corrected code is:
sum = 0;
indata >> number;
while (indata)
{
sum = sum + number;
indata >> number;
}

11. You could choose anything that’s not a name. A blank line would be one possibility. If
the program must read the name in three parts, then a series of nonalphabetic characters,
separated appropriately, would work. For example: 999 888 777.
12. The output is:
3 5 7 9 11 13 15 17 19

The corrected code is:


number = 0;
while (number < 10)
DalePhatANS_complete 8/18/04 10:31 AM Page 1077

Answers to Selected Exercises | 1077

{
cout << number * 2 – 1 << " ";
number++;
}

13. False.
14. What is the condition that ends the loop? How should the condition be initialized? How
should the condition be updated? What is the process being repeated? How should the
process be initialized? How should the process by updated? What is the state of the pro-
gram on exiting the loop?
15. The sum is not reinitialized at the start of each inner loop, so it simply keeps accumulat-
ing the input values. The count isn’t updated, so the flow of control doesn’t leave the
inner loop until the end-of-file condition is encountered. Here is the corrected code.
while (indata)
{
count = 1;
sum = 0;
while (count <= 5 && indata)
{
cin >> number;
sum = sum + number;
count++;
}
cout << sum / count << endl;
}

Chapter 6 Programming Warm-Up Exercises


1. count = -10;
while (count <= 10)
{
cout << count << endl;
count++;
}

2. count = 1;
sum = 0;
while (sum <= 10000)
{
sum = sum + count;
count++;
}
cout << count – 1;
DalePhatANS_complete 8/18/04 10:31 AM Page 1078

1078 | Answers to Selected Exercises

3. count = 0;
sum = 0;
indata >> score;
while (indata && count < 20)
{
sum = sum + score;
count++;
indata >> score;
}
if (count == 0)
cout << "No data on file.";
else
cout << "Average is " << sum / count << endl;

4. count = 0;
getline(chapter6, line);
while (chapter6)
{
if (line.find("code segment") < string::npos)
count++;
getline(chapter6, line);
}
cout << "The string was found " << count << " times."

5. cin >> response;


while (!(response == "Yes" || response == "yes" ||
response == "No" || response == "no"))
{
cout << "Invalid response. Please enter \"Yes\" or \"No\".";
cin >> response;
}
yes = response == "Yes" || response == "yes";

6. cout << "Sun Mon Tue Wed Thu Fri Sat" << endl;
count = 1;
while (count <= startDay) //Print blanks in first week
{
cout << " ";
count++;
}
dayNumber = 1;
while (dayNumber <= days) //Print day numbers for month
{
while (count <= 7) //Print for one week in month
{
if (dayNumber <= days)
DalePhatANS_complete 8/18/04 10:31 AM Page 1079

Answers to Selected Exercises | 1079

cout << setw(3) << dayNumber << " ";


count++;
dayNumber++;
}
cout << endl;
count = 1;
}

7. a. startDay = (startDay + days) % 7;


b. We would need the number of days in each successive month.
8. char oneChar;
int eCount;
int charCount;
eCount = 0;
textData >> oneChar;
charCount = 0;
while (textData)
{
charCount++;
if (oneChar == 'z')
eCount++;
textData >> oneChar;
}
cout << "Percentage of letter 'z': "
<< float(eCount) / charCount * 100;

9. char oneChar;
int eCount;
int charCount;
eCount = 0;
textData >> oneChar;
charCount = 0;
while (textData && charCount < 10000)
{
charCount++;
if (oneChar == 'z')
eCount++;
textData >> oneChar;
}
cout << "Percentage of letter 'z': "

<< float(eCount) / charCount * 100;


10. first = 1;
second = 1;
cout << first << endl << second << endl;
while (second < 30000)
DalePhatANS_complete 8/18/04 10:31 AM Page 1080

1080 | Answers to Selected Exercises

{
next = first + second;
first = second;
second = next;
cout << second << endl;
}

11. first = 1;
second = 1;
cout << setw(5) << 1 << setw(8) << first << endl
<< setw(5) << 1 << setw(8) << second << endl;
position = 2;
while (second < 30000)
{
next = first + second;
first = second;
second = next;
position++;
cout << setw(5) << position << setw(8) << second << endl;
}

12. cout << "Enter number of stars: ";


cin >> number;
count = 1;
while (count <= number)
{
cout << '*';
count++;
)
cout << endl;

13. The loop ends when the specified number of stars has been printed. The condition is ini-
tialized by getting the number of stars, and setting the loop iteration counter to 1. The
condition is updated by incrementing the iteration counter at the end of each iteration.
The process being repeated is the printing of a single star. The process does not require
any initialization or update. Upon exiting the loop, the specified number of stars has
been printed, and the iteration counter is equal to the number plus one.
14. indata >> number;
while (indata)
{
count = 1;
while (count <= number)
{
cout << '*';
count++;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1081

Answers to Selected Exercises | 1081

cout << endl;


indata >> number;
}

15. The code should be tested with an empty file, a file that contains one value, and a file
that contains multiple values. The values should include a negative integer, zero, and
positive integers.

Chapter 6 Case Study Follow-Up


1. if (current >= high) // Check for new high
2. if (preceding <= low)
3. Yes; a priming read is used because the first value read is special and needs to be
processed outside the loop. Normally, a priming read is not used with a count-controlled
loop.
4. Count-controlled.
5. Changing the input to come from the keyboard is easy: cout replaces all references to
the file name in output statements and all other references to the file are removed. How-
ever, because the output is also going to the screen, it will be intermingled with the
prompts and the input. If you are careful, you can make the screen readable, but if the
input is from the keyboard, it is better for the output to go to a file.
6. Often the amount of data determines whether it should be entered into a file rather than
entered at the keyboard. Another factor is where the data is coming from. In this case,
values are being recorded by a machine, so it is logical to have them go directly to a file.
7. We should try data sets that present the highest value and lowest dip in different places
and in different orders. For example, we should try one set with the highest reading as
the first value and another set with it as the last. We should try test data with no dips (all
the readings equal), with multiple dips, and with the lowest dip before, after, and between
other dips. Finally, we should try the program on some typical sets of readings and check
the output with results we’ve determined by hand.

Chapter 7 Exam Preparation Exercises


1. It uses the keyword void instead of int, the function is not called main, and it does not
contain a return statement.
2. False. The parameter name is optional.
3. Control returns after the last statement has executed, and returns to the statement imme-
diately following the call.
4. a. v, b. iii, c. vi, d. i, e. iv, f. viii, g. ii, h. vii.
5. name and salary are reference parameters. age and level are value parameters.
6. The call must have six arguments, unless default parameters are used (we do not cover
their use in this book, but they are mentioned).
7. The value parameter stores the new value but the argument is unaffected. The reference
parameter stores the new value directly into the argument.
8. The type must come before the name of each parameter instead of after it. The & should
be appended to the type instead of to the parameter name. The prototype should end with
a semicolon.
DalePhatANS_complete 8/18/04 10:31 AM Page 1082

1082 | Answers to Selected Exercises

9. False. Arguments must appear in the same order as the corresponding parameters.
10. Hiding a module implementation in a separate block with a formally specified interface.
11. Flow out, or in and out.
12. It should not contain a return statement.
13. The result is not passed back to the caller—it should be a reference parameter instead of a
local variable.
14. The result is not passed back to the caller—result should be a reference parameter
instead of a value parameter.
15. The x and y parameters should be value parameters—their data flow is inward only. In the
case of the y parameter, the value of the argument will be set to zero when the function
returns.
16. False. Like any other variable declaration, it can be accessed only by statements within
the block that follows its declaration.
17. True.
18. That the file contains valid data (only integers), and that it has at least one value (the
mean is undefined for an empty data set).

Chapter 7 Programming Warm-Up Exercises


1. void Max (/* in */ int num1,
/* in */ int num2,
/* out */ int& greatest)

2. void Max (int, int, int&);


3. void Max (/* in */ int num1,
/* in */ int num2,
/* out */ int& greatest)
{
if (num1 > num2)
greatest = num1;
else
greatest = num2;
}

4. void GetLeast (/* inout */ ifstream& infile,


/* out */ int& lowest)

5. void GetLeast (ifstream&, int&);


6. void GetLeast (/* inout */ ifstream& infile,
/* out */ int& lowest)
{
int number;
infile >> number; // Get a number
lowest = INT_MAX; // Initially use greatest int
while (infile)
{
if (number < lowest)
DalePhatANS_complete 8/18/04 10:31 AM Page 1083

Answers to Selected Exercises | 1083

lowest = number; // Remember lower number


infile >> number; // Get next number
}
}

7. // Precondition:
// File infile has been opened AND
// header file climits has been included
// Postcondition:
// File infile is at end-of-file AND
// if the file is empty, lowest contains INT_MAX;
// else smallest number on file infile is in lowest

8. void Reverse ( /* in */ string original,


/* out */ string& lanigiro )

9. void Reverse ( string, string& );


10. void Reverse ( /* in */ string original,
/* out */ string& lanigiro )
{
int count;
count = 1;
lanigiro = "";
while (count <= original.length())
{
lanigiro = lanigiro +
original.substr(original.length() - count, 1);
count++;
}
)

11. // Precondition:
// Original must have a value
// Postcondition:
// lanigiro contains the reverse of the string in original

12. void LowerCount ( /* out */ int& count)


{
char inChar;
count = 0;
cin >> inChar;
while (cin && inChar != '\n')
{
if (islower(inChar))
count++;
cin >> inChar;
}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1084

1084 | Answers to Selected Exercises

13. // Precondition:
// The program has included the header cctype
// Postcondition:
// A line has been read from cin AND
// the number of lowercase letters on the line is in count

14. void GetNonemptyLine ( /* inout */ ifstream& infile,


/* out */ string& line)
{
getline(infile, line);
while (infile && line == "")
getline(infile, line);
}

15. void SkipToEmptyLine ( /* inout */ ifstream& infile,


/* out */ int& skipped)
{
skipped = 0;
getline(infile, line);
while (infile && line != "")
{
skipped++;
getline(infile, line);
}
}

16. void TimeAdd ( /* inout */ int& days,


/* inout */ int& hours,
/* inout */ int& minutes,
/* in */ int addDays,
/* in */ int addHours,
/* in */ int addMinutes)
{
int extraHour;
int extraDay;
minutes = (minutes + addMinutes) % 60;
extraHour = (minutes + addMinutes) / 60;
hours = (hours + addHours + extraHour) % 24;
extraDay = (hours + addHours + extraHour) / 24;
days = days + addDays + extraDay;
}

17. void TimeAdd ( /* inout */ int& days,


/* inout */ int& hours,
/* inout */ int& minutes,
/* inout */ int& seconds,
DalePhatANS_complete 8/18/04 10:31 AM Page 1085

Answers to Selected Exercises | 1085

/* in */ int addDays,
/* in */ int addHours,
/* in */ int addMinutes,
/* in */ int addSeconds)
{
int extraMinute;
int extraHour;
int extraDay;
seconds = (seconds + addSeconds) % 60;
extraMinute = (seconds + addSeconds) / 60;
minutes = (minutes + addMinutes + extraMinute) % 60;
extraHour = (minutes + addMinutes + extraMinute) / 60;
hours = (hours + addHours + extraHour) % 24;
extraDay = (hours + addHours + extraHour) / 24;
days = days + addDays + extraDay;
}

18. void SeasonPrint (/* in */ int month,


/* in */ int day);
{
if (month == 12 && day >= 21)
cout << "Winter";
else if ((month == 9 and day >= 21) || month > 9)
cout << "Fall";
else if ((month == 6 and day >= 21) || month > 6)
cout << "Summer";
else if ((month == 3 and day >= 21) || month > 3)
cout << "Spring";
else
cout << "Winter";
}

Chapter 7 Case Study Follow-Up Exercises


1. //*****************************************************************
// Mortgage Payment Tables program
// This program prints a table showing loan amount, interest rate,
// length of loan, monthly payments, and total cost of a mortgage.
//******************************************************************

#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>
using namespace std;
DalePhatANS_complete 8/18/04 10:31 AM Page 1086

1086 | Answers to Selected Exercises

// Function prototypes
void PrintHeading(ofstream&);
void GetLoanAmount(float&);
void GetRestOfData(float&, int&);
void DeterminePayment(float, int, float, float&);
void PrintResults(ofstream&, float, int, float, float);

int main()
{
// Input variables
float loanAmount;
float yearlyRate;
int numberOfYears;
float payment;
ofstream dataOut;
dataOut.open("mortgage.out");

PrintHeading(dataOut);

// Prompt for and read input values


GetLoanAmount(loanAmount);
while (loanAmount > 0.0)
{
GetRestOfData(yearlyRate, numberOfYears);
DeterminePayment(loanAmount, numberOfYears, yearlyRate,
payment);
PrintResults(dataOut, loanAmount, numberOfYears,
yearlyRate, payment);
GetLoanAmount(loanAmount);
}
dataOut.close();
return 0;
}

//******************************************************************

void PrintHeading(ofstream& dataOut)


{

dataOut << fixed << setprecision(2) << setw(12) << "Loan Amount"
<< setw(12) << "No. Years" << setw(15)
<< "Interest Rate" << setw(12) << "Payment"
<< setw(12) << "Total Paid" << endl;

}
DalePhatANS_complete 8/18/04 10:31 AM Page 1087

Answers to Selected Exercises | 1087

//******************************************************************

void GetLoanAmount(float& loanAmount)


{
cout << "Input the total loan amount; "
<< "a negative value stops processing." << endl;
cin >> loanAmount;
}

//******************************************************************

void GetRestOfData(float& interestRate, int& numberOfYears)


{
cout << "Input the interest rate." << endl;
cin >> interestRate;
cout << "Enter the number of years for the loan" << endl;
cin >> numberOfYears;
}

//******************************************************************

void DeterminePayment(float loanAmount, // Loan amount


int numberOfYears, // Term of loan
float yearlyRate, // Interest rate
float& payment) // Monthly payment
// Precondition:

{
// local variables
float monthlyRate;
int numberOfPayments;
monthlyRate = yearlyRate / 1200;
numberOfPayments = numberOfYears * 12;
payment = (loanAmount
* pow(1 + monthlyRate, numberOfPayments)
* monthlyRate)
/ (pow(1 + monthlyRate, numberOfPayments) - 1 );
}

//******************************************************************

void PrintResults(ofstream& dataOut, float loanAmount,


int numberOfYears, float yearlyRate, float payment)
{
DalePhatANS_complete 8/18/04 10:31 AM Page 1088

1088 | Answers to Selected Exercises

dataOut << fixed << setprecision(2) << setw(12) << loanAmount


<< setw(12) << numberOfYears << setw(12)
<< yearlyRate << setw(15) << payment
<< setw(12) << numberOfYears*12*payment << endl;
}

//******************************************************************

There is no correct answer that is easier to read.


2.

Clearly, values that do not make sense cause problems. inf and nan are C++ special
symbols that mean infinite and undefined. Loan amount, number of years, and interest
rate should be greater than zero.
3. Error checking has three parts: what is an error, where do you check for it, and what do
you do when it occurs. In this case, a nonpositive value for any of the inputs is an error,
and the errors should be checked for immediately after the values are input. What should
you do when nonpositive values are input? You have several choices. You can prompt
the user to re-enter the bad value, enclosing the reading within a loop. Of course, if a
correct value is never input, an infinite loop occurs. Another option is to write an error
message and stop the program; for example, you can add a Boolean variable to each
input function that returns true if the value(s) are OK and false otherwise. After each call,
this variable can be checked before the program continues.
Because there are so many possible solutions, we do not show one. Check over yours
and be sure you have the three parts.
4. void PrintResults( /* inout */ ofstream& dataOut, // Output file
/* in */ float loanAmount, // Loan amount
/* in */ int numberOfYears, // Term of loan
/* in */ float yearlyRate, // Interest rate
/* in */ float payment ) // Payment

{
float amountPaid;
DalePhatANS_complete 8/18/04 10:31 AM Page 1089

Answers to Selected Exercises | 1089

amountPaid = numberOfYears*12*payment;
dataOut << fixed << setprecision(2) << setw(12) << loanAmount
<< setw(12) << numberOfYears << setw(12)
<< yearlyRate << setw(15) << payment
<< setw(12) << amountPaid << setw(12)
<< amountPaid - loanAmount << endl;
}

void PrintHeading( /* inout */ ofstream& dataOut )


{
dataOut << fixed << setprecision(2) << setw(12)
<< "Loan Amount"
<< setw(12) << "No. Years" << setw(15)
<< "Interest Rate" << setw(12) << "Payment"
<< setw(12) << "Total Paid" << setw(12)
<< "Interest Paid << endl;

Chapter 8 Exam Preparation Exercises


1. True.
2. False. It is local to the function’s body.
3. False. It cannot be referenced before it is declared, and it cannot be referenced within any
block that declares an identifier with the same name.
4. True.
5. a. v, b. iv, c. i, d. vii, e. viii, f. vi, g. ii, h. iii.
6. The combination of param2 being a reference parameter and the erroneous use of an
assignment expression instead of an equality test in the first If statement results in the
argument to param2 being assigned the value in param1 every time the function is
called.
7. The function GetYesOrNo refers to the global variable a, so the program always outputs
the response to the function’s input request as the name.
8. The namespace is in global scope.
9. The std namespace is local to main and not accessible to the other functions.
10. a. Static, b. Automatic, c. Static.
11. int pi = 3.14159265;
12. It is initialized once, when control first reaches the statement.
13. It is initialized each time control reaches it.
14. False.
15. If a is less than or equal to b, the function fails to execute a return statement.
16. The return expression is of type float, and the return type of the function is int.
17. A void function should not have a return statement with an expression.
18. It makes a side effect error more likely.
DalePhatANS_complete 8/18/04 10:31 AM Page 1090

1090 | Answers to Selected Exercises

Chapter 8 Programming Warm-Up Exercises


1. #include <iostream>

using namespace std;

int Power (int, int);

int main ()
{
int pow;
int x;

cout << "Enter power: ";


cin >> pow;
cout << "Enter value to be raised to power: ";
cin >> x;
cout << Power(x, pow);
}

int Power(int x, int pow)


{
int result = 1;
while (pow > 0)
{
result = result * x;
pow--;
}
return result;
}

2. bool Equals (/* in */ float x,


/* in */ float y)

3. bool Equals (float, float);


4. bool Equals (/* in */ float x,
/* in */ float y)
{
return abs(x – y) < 0.00000001;
}

5. float ConeVolume (/* in */ float radius,


/* in */ float height);

6. float ConeVolume (/* in */ float radius,


/* in */ float height)
{
return 1.0/3.0 * 3.14159265 * radius * radius * height;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1091

Answers to Selected Exercises | 1091

7. int GetLeast (/* inout */ ifstream& infile)


{
int lowest;
int number;
infile >> number; // Get a number
lowest = INT_MAX; // Initially use greatest int
while (infile)
{
if (number < lowest)
lowest = number; // Remember lower number
infile >> number; // Get next number
}
return lowest;
}

8. string Reverse ( /* in */ string original)


{
string lanigiro;
int count;
count = 1;
lanigiro = "";
while (count <= original.length())
{
lanigiro = lanigiro +
original.substr(original.length() - count, 1);
count++;
}
return lanigiro;
)

9. int LowerCount ()
{
char inChar;
int count;
count = 0;
cin >> inChar;
while (cin && inChar != '\n')
{
if (islower(inChar))
count++;
cin >> inChar;
}
return count;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1092

1092 | Answers to Selected Exercises

10. float SquareKm (/* in */ float length,


/* in */ float width);
{
return length * 1.6 * width * 1.6;
}

11. bool Exahausted (/* in */ int filmRolls)


{
static int total = 0;
total = total + filmRolls;
if (total > 1000)
{
total = 0;
return true;
}
else
return false;
}

12. string MonthAbbrev (/* in */ int month)


{
if (month == 12) return "Dec";
else if (month == 11) return "Nov";
else if (month == 10) return "Oct";
else if (month == 9) return "Sep";
else if (month == 8) return "Aug";
else if (month == 7) return "Jul";
else if (month == 6) return "Jun";
else if (month == 5) return "May";
else if (month == 4) return "Apr";
else if (month == 3) return "Mar";
else if (month == 2) return "Feb";
else return "Jan";
}

13. string MonthAbbrev (/* in */ int month)


{
if (month == 12) return "Dec";
else if (month == 11) return "Nov";
else if (month == 10) return "Oct";
else if (month == 9) return "Sep";
else if (month == 8) return "Aug";
else if (month == 7) return "Jul";
else if (month == 6) return "Jun";
else if (month == 5) return "May";
else if (month == 4) return "Apr";
DalePhatANS_complete 8/18/04 10:31 AM Page 1093

Answers to Selected Exercises | 1093

else if (month == 3) return "Mar";


else if (month == 2) return "Feb";
else if (month == 1) return "Jan";
else return "Inv";
}

14. float RunningAvg (/* in */ float value)


{
static float total = 0.0;
static int count = 0;
total = total + value;
count++;
return total/float(count);
}

Chaper 8 Case Study Follow-Up Exercises


1.
Evaluate BloodPressure(Inout: healthProfile; In: name)

Prompt for name’s input


Get data
Evaluate input according to charts and print message

Evaluate Input and Print Level 2

if (systolic < 120)


Print on healthProfile “ Systolic reading is optimal”
else if (systolic < 130)
Print on healthProfile “ Systolic reading is normal”
else if (systolic < 140)
Print on healthProfile “ Systolic reading is high normal”
else if (systolic < 160)
Print on healthProfile “ Systolic indicates hypertension Stage 1”
else if (systolic < 180)
Print on healthProfile “ Systolic indicates hypertension Stage 2”
else
Print on healthProfile “ Systolic indicates hypertension Stage 3”

if (diastolic < 80)


Print on healthProfile “ Diastolic reading is optimal”
else if (diastolic < 85)
Print on healthProfile “ Diastolic reading is normal”
else if (diastolic < 90)
Print on healthProfile “ Diastolic reading is high normal”
DalePhatANS_complete 8/18/04 10:31 AM Page 1094

1094 | Answers to Selected Exercises

else if (diastolic < 100)


Print on healthProfile “ Diastolic indicates hypertension Stage 1”
else if (diastolic < 110)
Print on healthProfile “ Diastolic indicates hypertension Stage 2”
else
Print on healthProfile “ Diastolic indicates hypertension Stage 3”
2. //******************************************************************
// EvaluateBloodPressure Driver program
// This program provides an environment for testing the
// EvaluateBloodPressure function in isolation from the Profile
// program
//******************************************************************
#include <iostream>
#include <fstream>

using namespace std;

void EvaluateBloodPressure(ofstream&, string);


int main()
{
ofstream healthProfile;
healthProfile.open("ProfileBP");
string name = "John J. Smith";
for (int test = 1; test <= 12; test++)
EvaluateBloodPressure(healthProfile, name);
healthProfile.close();
return 0;
}

//******************************************************************

void EvaluateBloodPressure
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name ) // Patient's name
{
// Declare the health statistics
int systolic;
int diastolic;

// Enter the patient's health statistics


cout << "Enter the systolic blood pressure reading for" << name
<< ": ";
cin >> systolic;
cout << "Enter the diastolic blood pressure reading for "
<< name<< ": ";
DalePhatANS_complete 8/18/04 10:31 AM Page 1095

Answers to Selected Exercises | 1095

cin >> diastolic;

healthProfile << "Blood Pressure Profile " << endl;


if (systolic < 120)
healthProfile << " Systolic reading is optimal" << endl;
else if (systolic < 130)
healthProfile << " Systolic reading is normal" << endl;
else if (systolic < 140)
healthProfile << " Systolic reading is high normal" << endl;
else if (systolic < 160)
healthProfile << " Systolic indicates hypertension Stage 1"
<< endl;
else if (systolic < 180)
healthProfile << " Systolic indicates hypertension Stage 2"
<< endl;
else
healthProfile << " Systolic indicates hypertension Stage 3"
<< endl;

if (diastolic < 80)


healthProfile << " Diastolic reading is optimal" << endl;
else if (diastolic < 85)
healthProfile << " Diastolic reading is normal" << endl;
else if (diastolic < 90)
healthProfile << " Diastolic reading is high normal"
<< endl;
else if (diastolic < 100)
healthProfile << " Diastolic indicates hypertension Stage 1"
<< endl;
else if (diastolic < 110)
healthProfile << " Diastolic indicates hypertension Stage 2"
<< endl;
else
healthProfile << " Diastolic indicates hypertension Stage 3"
<< endl;
}

3. //******************************************************************
// Profile Program
// This program inputs a name, weight, height, blood pressure
// readings, and cholesterol values. If an input value is
// negative, an error message is written. Appropriate health
// messages are written for each of the input values.
//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1096

1096 | Answers to Selected Exercises

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

string Name();
void EvaluateCholesterol(ofstream& healthProfile, string name,
bool& dataOK);
void EvaluateBMI(ofstream& healthProfile, string name,
bool& dataOK);
void EvaluateBloodPressure(ofstream& healthProfile, string name,
bool& dataOK);
int main()
{
// Declare and open the output file
ofstream healthProfile;
healthProfile.open("Profile");
string name;
bool dataOK;
name = Name();

// Evaluate the patient's statistics


healthProfile << "Patient's name " << name << endl;
EvaluateCholesterol(healthProfile, name, dataOK);
EvaluateBMI(healthProfile, name, dataOK);
EvaluateBloodPressure(healthProfile, name, dataOK);
healthProfile << endl;
healthProfile.close();
return 0;
}

//******************************************************************
// Name function
// This function inputs a name and returns it in first,
// middle initial, and last order.
//******************************************************************

string Name()
{
// Declare the patient's name
string firstName;
string lastName;
char middleInitial;
DalePhatANS_complete 8/18/04 10:31 AM Page 1097

Answers to Selected Exercises | 1097

// Enter the patient's name


cout << "Enter the patient's first name: ";
cin >> firstName;
cout << "Enter the patient's last name: ";
cin >> lastName;
cout << "Enter the patient's middle initial: ";
cin >> middleInitial;
return firstName + ' ' + middleInitial + ". " + lastName;
}

//******************************************************************
// Cholesterol function
// This function inputs HDL (good cholesterol) and LDL (bad
// cholesterol) and prints out a health message based on their
// values on file healthProfile.
//******************************************************************

void EvaluateCholesterol
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)
{
int HDL;
int LDL;

cout << "Enter HDL for " << name << ": ";
cin >> HDL;
cout << "Enter LDL for " << name << ": ";
cin >> LDL;

dataOK = HDL > 0 && HDL > 0;


if ( !dataOK )
cout << " Cholesterol data must be positive; test aborted. ";
else
{
float ratio = LDL/HDL; // Calculate ratio of LDL to HDD

healthProfile << "Cholesterol Profile " << endl;

// Print message based on HDL value


if (HDL < 40)
healthProfile << " HDL is too low" << endl;
else if (HDL < 60)
healthProfile << " HDL is okay" << endl;
DalePhatANS_complete 8/18/04 10:31 AM Page 1098

1098 | Answers to Selected Exercises

else
healthProfile << " HDL is excellent" << endl;

// Print message based on LDL value


if (LDL < 100)
healthProfile << " LDL is optimal" << endl;
else if (LDL < 130)
healthProfile << " LDL is near optimal" << endl;
else if (LDL < 160)
healthProfile << " LDL is borderline high" << endl;
else if (LDL < 190)
healthProfile << " LDL is high" << endl;
else
healthProfile << " LDL is very high" << endl;

if (ratio < 3.22)


healthProfile << " Ratio of LDL to HDL is good"
<< endl;
else
healthProfile << " Ratio of LDL to HDL is not good"
<< endl;
}
}

//******************************************************************
// BMI Function
// This function inputs weight in pounds and height in inches and
// calculates the body mass index (BMI prints a health message
// based on the BMI. Input in English weights.
//******************************************************************

void EvaluateBMI
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)

{
const int BMI_CONSTANT = 703; // Constant in English formula
float pounds;
float inches;

cout << "Enter the weight in pounds for " << name << ": ";
cin >> pounds;
cout << "Enter the height in inches for " << name << ": ";
cin >> inches;
DalePhatANS_complete 8/18/04 10:31 AM Page 1099

Answers to Selected Exercises | 1099

dataOK = pounds > 0 && inches > 0;

if ( !dataOK)
cout << " BMI data must be positive; test aborted. ";
else
{
float bodyMassIndex = pounds * BMI_CONSTANT /
(inches * inches);
healthProfile << "Body Mass Index Profile" << endl;

// Print health message based on bodyMassIndex

healthProfile << " Body mass index is " << bodyMassIndex


<< ". " << endl;
healthProfile << " Interpretation of BMI " << endl;
if (bodyMassIndex < 18.5)
healthProfile << " Underweight: BMI is too low"
<< endl;
else if (bodyMassIndex < 24.9)
healthProfile << " Normal: BMI is average" << endl;
else if (bodyMassIndex < 29.9)
healthProfile << " Overweight: BMI is too high"
<< endl;
else
healthProfile << " Obese: BMI is dangerously high"
<< endl;
}
}

//******************************************************************
// Blood Pressure function
// This function gets blood pressure readings (systolic/diastolic)
// and prints out a health message based on their values
// in file healthProfile.
//******************************************************************

void EvaluateBloodPressure
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)

{
// Declare the health statistics
int systolic;
DalePhatANS_complete 8/18/04 10:31 AM Page 1100

1100 | Answers to Selected Exercises

int diastolic;
// Enter the patient's health statistics
cout << "Enter the systolic blood pressure reading for "
<< name << ": ";
cin >> systolic;
cout << "Enter the diastolic blood pressure reading for "
<< name << ": ";
cin >> diastolic;

dataOK = systolic > 0 && diastolic > 0;

if ( !dataOK )
cout << " Blood pressure data must be positive;"
<< " test aborted. ";
else
{
healthProfile << "Blood Pressure Profile " << endl;
if (systolic < 120)
healthProfile << " Systolic reading is optimal"
<< endl;
else if (systolic < 130)
healthProfile << " Systolic reading is normal"
<< endl;
else if (systolic < 140)
healthProfile << " Systolic reading is high normal"
<< endl;
else if (systolic < 160)
healthProfile
<< " Systolic indicates hypertension Stage 1"
<< endl;
else if (systolic < 180)
healthProfile
<< " Systolic indicates hypertension Stage 2"
<< endl;
else
healthProfile
<< " Systolic indicates hypertension Stage 3"
<< endl;

if (diastolic < 80)


healthProfile << " Diastolic reading is optimal"
<< endl;
else if (diastolic < 85)
healthProfile << " Diastolic reading is normal"
<< endl;
DalePhatANS_complete 8/18/04 10:31 AM Page 1101

Answers to Selected Exercises | 1101

else if (diastolic < 90)


healthProfile << " Diastolic reading is high normal"
<< endl;
else if (diastolic < 100)
healthProfile
<< " Diastolic indicates hypertension Stage 1"
<< endl;
else if (diastolic < 110)
healthProfile
<< " Diastolic indicates hypertension Stage 2"
<< endl;
else
healthProfile
<< " Diastolic indicates hypertension Stage 3"
<< endl;
}
}

4. Only the main function changes.


int main()
{
// Declare and open the output file
ofstream healthProfile;
healthProfile.open("Profile");
string name;
bool dataOK;
name = Name();

// Evaluate the patient's statistics


healthProfile << "Patient's name " << name << endl;
EvaluateCholesterol(healthProfile, name, dataOK);
if (dataOK)
EvaluateBMI(healthProfile, name, dataOK);
if (dataOK)
EvaluateBloodPressure(healthProfile, name, dataOK);
if (!dataOK)
cout << "Bad data entered; program aborted." << endl;

healthProfile << endl;


healthProfile.close();
return 0;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1102

1102 | Answers to Selected Exercises

Chapter 9 Exam Preparation Exercises


1. True.
2. False. It has local scope.
3. False. Converting a While that may execute zero times to a Do-While requires surround-
ing the Do-While with an If statement.
4. False. Both Break and Continue are allowed in any of the looping statements.
5. While and For are pretest loops, and Do-While is a posttest loop.
6. Control jumps to the case matching the switch expression, but then proceeds to exe-
cute the remaining statements in all of the succeeding cases.
7. while (true)
8. 1000 times.
9. A Do-While loop would be most appropriate.
10. A While statement would be the best choice.
11. OakMapleError
12. August
13. 2
1
0
3
2
1
4
3
2

14. 2
1
0
3
2
1
4
3
2

15. outCount = -1;


while (outCount < 2)
{
inCount = 3;
while (inCount > 0)
{
cout << outCount + inCount << endl;
inCount --;
}
outCount++;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1103

Answers to Selected Exercises | 1103

16. How now brown cow?


17. cout << "How now brown cow?";
18. 12

Chapter 9 Programming Warm-Up Exercises


1. switch (day)
{
case 0 : cout << "Sunday"; break;
case 1 : cout << "Monday"; break;
case 2 : cout << "Tuesday"; break;
case 3 : cout << "Wednesday"; break;
case 4 : cout << "Thursday"; break;
case 5 : cout << "Friday"; break;
case 6 : cout << "Saturday"; break;
}

2. switch (day)
{
case 0 : cout << "Sunday"; break;
case 1 : cout << "Monday"; break;
case 2 : cout << "Tuesday"; break;
case 3 : cout << "Wednesday"; break;
case 4 : cout << "Thursday"; break;
case 5 : cout << "Friday"; break;
case 6 : cout << "Saturday"; break;
default: cout << "Error";
}

3. Note that Break statements aren’t needed because each branch of the Switch exits the
function, accomplishing the required effect.
string DayOfWeek (/* in */ int day)
{
switch (day)
{
case 0 : return "Sunday";
case 1 : return "Monday";
case 2 : return "Tuesday";
case 3 : return "Wednesday";
case 4 : return "Thursday";
case 5 : return "Friday";
case 6 : return "Saturday";
default: return "Error";
}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1104

1104 | Answers to Selected Exercises

4. for (int day = 6, day >= 0, day--)


cout << DayOfWeek(day) << endl;

5. for (int day = 3, day <= 9, day++)


cout << DayOfWeek(day % 7) << endl;

6. char response;
do
{
cout << "Please enter 'Y' or 'N': ";
cin >> response;
if (response != 'Y' && response != 'N')
cout << "Invalid response. ";
} while (response != 'Y' && response != 'N');

7. int SumInt (/* in */ int goal)


{
// Assumes goal is positive
int num = 0;
int sum = 0;
do
{
num++;
sum = sum + num;
} while (sum < goal);
return num;
}

8. for (int row = 1; row <= 10; row++)


{
for (int col = 1; col <= 10; col++)
cout << setw(5) << row * col;
cout << endl;
}

9. for (int line = 1; line <= 10; line++)


{
for (int star = 1; star <= line; star++)
cout << '*';
cout << endl;
}

10. int line;


int star;
line = 1;
do
DalePhatANS_complete 8/18/04 10:31 AM Page 1105

Answers to Selected Exercises | 1105

{
star = 1;
do
{
cout << '*';
star++;
} while (star <= line);
cout << endl;
line++;
} while (line <= 10);

11. int line;


int star;
line = 1;
while (line <= 10)
{
star = 1;
while (star <= line)
{
cout << '*';
star++;
}
cout << endl;
line++;
}

12. void Rectangle (/* in */ int height,


/* in */ int width)
{
for (int col = 1; col <= width; col++)
cout << '*';
cout << endl;
for (int row = 2; row <= height – 1; row++)
{
cout << '*';
for (int col = 2; col < width – 1; col++)
cout << ' ';
cout << '*' << endl;
}
for (int col = 1; col <= width; col++)
cout << '*';
cout << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1106

1106 | Answers to Selected Exercises

13. int startHour = 3;


int endHour = 7;
int startMin = 15;
int endMin = 30;
int beginMin;
int lastMin;

for (int hour = startHour; hour <= endHour; hour++)


{
if (hour == startHour)
beginMin = startMin;
else
beginMin = 0;
if (hour == endHour)
lastMin = endMin;
else
lastMin = 59;

for (int min = beginMin; min <= lastMin; min++)


cout << hour << ':' << min << endl;
}

14. int startHour = 3;


int endHour = 7;
int startMin = 15;
int endMin = 30;
int beginMin;
int lastMin;

for (int hour = startHour; hour <= endHour; hour++)


{
if (hour == startHour)
beginMin = startMin;
else
beginMin = 0;
if (hour == endHour)
lastMin = endMin;
else
lastMin = 59;

for (int min = beginMin; min <= lastMin; min++)


for (int sec = 0; sec <= 59; sec++)
cout << hour << ':' << min << ':' << sec << endl;
}

15. Exercise 13 outputs 255 lines, and Exercise 14 outputs 15,300 lines.
DalePhatANS_complete 8/18/04 10:31 AM Page 1107

Answers to Selected Exercises | 1107

Chapter 9 Case Study Follow-Up Exercises


1. The first two clauses in the If statement could be combined with
if ((isupper(character) || (islower(character)) or if ((isalpha(character))

2. Words are ended by punctuation marks, blanks, or end of lines. A sum of these gives an
estimate of the number of words.
3. Average word length would be the total number of alphanumeric characters divided by
the number of words.
4. Average sentence length, percentage of two-character words, percentage of three-charac-
ter words, percentage of words over a certain threshold—all of these would be good can-
didates.

Chapter 10 Exam Preparation Exercises


1. False. bool cannot be unsigned.
2. True.
3. True. sizeof(int) returns 4 for a 32-bit int, and 8 for a 64-bit int.
4. True.
5. False. This is purely a matter of style.
6. char, short, int, long, bool.
7. A leading zero makes the literal a base 8 (octal) number. A leading 0X makes the literal a
base 16 (hexadecimal) number.
8. The assignment operators.
9. With ++count, the result of the expression is the same as the new (incremented) value of
count. With count++, the result of the expression is the old value of count (prior to
being incremented).
10. When the type name is not a single word, as in unsigned int.
11. toupper or tolower.
12. 'g'
13. 3.8283  104.
14. Absolute error is a fixed value of allowable error, whereas relative error multiplies the
allowable error by one of the values being compared.
15. The identifier VIOLET is declared twice in the same scope.
16. The value of the expression is 3.
17. Because the result of incrementing choice is an int, which cannot be assigned to an
enum type.
18. Because we must use the same type name for arguments, parameters, and function proto-
types. If the type doesn’t have a name, we can’t use it in this context.

Chapter 10 Programming Warm-Up Exercises


1. a. 5
b. 5L
c. 5UL
d. 05
e. 0X5
DalePhatANS_complete 8/18/04 10:31 AM Page 1108

1108 | Answers to Selected Exercises

2. a. 3.14159265F
b. 3.14159265
c. 3.14159265L
d. 3.14159265E0
3. a. days += 7;
b. radius *= 6.2831853;
c. workHours -= 40;
d. average /= count;
4. sizeof(long) * 8
5. a. a * b + c * d
b. a * b / (c * d)
c. a + b + c / (d + e) * f
d. (a + b) / (c + d) * (e + f)
e. -a + b <= c * d && a + b >= c – d
6. cin >> charIn;
if (isdigit( charIn))
numIn = charIn – '0';

7. int eCount;
string::size_type pos;
eCount = 0;
for (pos = 0; pos < inLine.length(); pos++)
if (inline[pos] == 'e')
eCount++;

8. int MonthNum (/* in */ string month)


{
switch (tolower(month[0]))
{
case 'a': switch (tolower(month[1]))
{
case 'p': return 4;
case 'u': return 8;
default : return 0;
}
case 'd': return 12;
case 'f': return 2;
case 'j': switch (tolower(month[3]))
{
case 'e': return 6;
case 'u': return 1;
case 'y': return 7;
default : return 0;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1109

Answers to Selected Exercises | 1109

case 'm': switch (tolower(month[2]))


{
case 'r': return 3;
case 'y': return 5;
default : return 0;
}
case 'n': return 11;
case 'o': return 10;
case 's': return 9;
default : return 0;
}
}

9. if (tolower(ampm[0]) == 'p')
hours = hours + 12;

10. abs(balance – audit) <= 0.001


11. abs(year – epoch) <= epoch * 0.0000001
12. enum Planets {MERCURY, VENUS, EARTH, MARS,
JUPITER, SATURN, URANUS, NEPTUNE, PLUTO};

13. Planets toPlanet (/* in */ string name)


{
switch (tolower(name[0]))
{
case 'm': switch (tolower(name[1]))
{
case 'e': return MERCURY;
case 'a': return MARS;
default : return EARTH;
}
case 'v': return VENUS;
case 'e': return EARTH;
case 'j': return JUPITER;
case 's': return SATURN;
case 'u': return URANUS;
case 'n': return NEPTUNE;
case 'p': return PLUTO;
default : return EARTH;
}
}

14. string PlanetToString (/* in */ Planet sphere)


{
switch (sphere)
{
case MERCURY: return "Mercury";
case VENUS: return "Venus";
DalePhatANS_complete 8/18/04 10:31 AM Page 1110

1110 | Answers to Selected Exercises

case EARTH: return "Earth";


case MARS: return "Mars";
case JUPITER: return "Jupiter";
case SATURN: return "Saturn";
case URANUS: return "Uranus";
case NEPTUNE: return "Neptune";
case PLUTO: return "Pluto";
default : return "Error";
}
}

15. for (Planet sphere = MERCURY;


sphere <= PLUTO;
sphere = Planet(sphere + 1))
cout << PlanetToString(sphere) << endl;

Chapter 10 Case Study Follow-Up Exercises


1. The counters could be defined globally before function main, where the entire program
could access them. However, this is considered bad style. In the next chapter, we cover
the record structure, which is a way that these variables could be bound into one struc-
ture and passed as a single variable.
2. If a hyphen is immediately followed by an end-of-line symbol, then it is used to divide a
word. Of course there might be an occasion when a hyphen just happens to fall on the
end of a line. Without access to a dictionary, you can never be sure.
3. //******************************************************************
// Style Program
// A stylistic analysis of the following features of text is
// computed:
// number of words
// average word length
// number of sentences
// average sentence length
// number of uppercase letters
// number of lowercase letters
// number of digits
//******************************************************************

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cctype>

using namespace std;


enum Features {UPPER, LOWER, DIGIT, IGNORE, EOW, EOS, COMPOUND};
DalePhatANS_complete 8/18/04 10:31 AM Page 1111

Answers to Selected Exercises | 1111

void OpenFiles(ifstream&, ofstream&);


Features Decode(char character);
void ProcessCharacter(char, int&, int&, int&, int&, int&, int&);

void PrintTable(ofstream& table, int, int, int, int, int, int);

int main()
{
// Prepare files for reading and writing
ifstream text;
ofstream table;

OpenFiles(text, table);

char character;

// Declare and initialize counters


int uppercaseCounter = 0;
int lowercaseCounter = 0;
int digitCounter = 0;
int wordCounter = 0;
int sentenceCounter = 0;
int ignoreCounter = 0;

text.get(character); // Input one character


do
{ // Process each character
ProcessCharacter(character, uppercaseCounter,
lowercaseCounter, digitCounter, sentenceCounter,
wordCounter, ignoreCounter);
text.get(character);
} while (text);

PrintTable(table, uppercaseCounter, lowercaseCounter,


digitCounter, sentenceCounter, wordCounter, ignoreCounter);
text.close();
table.close();
return 0;
}

//******************************************************************
// Function Decode examines the character and returns its type
DalePhatANS_complete 8/18/04 10:31 AM Page 1112

1112 | Answers to Selected Exercises

Features Decode( /* in */ char character ) // Character decoded


{
static bool hyphen = false;

if (hyphen)
{
hyphen = false;
if (character == '\n')
return IGNORE;
else
return COMPOUND;
}

if (isupper(character))
return UPPER;
else if (islower(character))
return LOWER;
else if (isdigit(character))
return DIGIT;
else
switch (character)
{
case '.' :
case '?' :
case '!' : return EOS;

case ' ' :


case ',' :
case ';' :
case ':' :
case '\n' : return EOW;

case '-' : hyphen = true;


return IGNORE;

}
return IGNORE;
}

//******************************************************************
// Function OpenFiles reads in the names of the input file and the
// output file and opens them for processing.

void OpenFiles( /* inout */ ifstream& text, // Input file


/* inout */ ofstream& table ) // Output file
DalePhatANS_complete 8/18/04 10:31 AM Page 1113

Answers to Selected Exercises | 1113

{
string inFileName;
string outFileName;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outFileName;
table.open(outFileName.c_str());
table << "Analysis of characters on input file " << inFileName
<< endl << endl;
}

//******************************************************************
// Function PrintTable prints the percentages represented by each
// of the five categories

void PrintTable
( /* inout */ ofstream& table, // Output file
/* in */ int uppercaseCounter, // Uppercase letters
/* in */ int lowercaseCounter, // Lowercase letters
/* in */ int digitCounter, // Digits
/* in */ int sentenceCounter, // '.', '?', '!'
/* in */ int wordCounter, // Words
/* in */ int ignoreCounter ) // Everything else
{
int totalAlphaNum;
totalAlphaNum = uppercaseCounter + lowercaseCounter +
digitCounter;
// Print results on file table
table << "Total number of alphanumeric characters: "
<< totalAlphaNum
<< endl;
table << "Number of uppercase letters: " << uppercaseCounter
<< endl;
table << "Number of lowercase letters: " << lowercaseCounter
<< endl;
table << "Number of digits: " << digitCounter << endl;
table << "Number of characters ignored: " << ignoreCounter
<< endl;

wordCounter = wordCounter + sentenceCounter;

table << "Number of Words: " << wordCounter << endl;


DalePhatANS_complete 8/18/04 10:31 AM Page 1114

1114 | Answers to Selected Exercises

table << "Number of Sentences: " << sentenceCounter << endl;

table << "Average word length: " << fixed << setprecision(2)
<< float(totalAlphaNum)/wordCounter << endl;
table << "Average sentence length: " << fixed \
<< setprecision(2)
<< float(wordCounter)
/ sentenceCounter << endl;

//******************************************************************
// Function ProcessCharacter examines character and increments the
// appropriate counter.

void ProcessCharacter
( /* in */ char character, // Character to be
// processed
/* inout */ int uppercaseCounter, // Uppercase letters
/* inout */ int lowercaseCounter, // Lowercase letters
/* inout */ int digitCounter, // Digits
/* inout */ int sentenceCounter, // '.', '?', '!'
/* inout */ int wordCounter, // Words
/* inout */ int ignoreCounter ) // Everything else
{
static bool endOfWord = false;

switch (Decode(character))
{
case UPPER : uppercaseCounter++;
endOfWord = false;
break;
case LOWER : lowercaseCounter++;
endOfWord = false;
break;
case DIGIT : digitCounter++;
endOfWord = false;
break;
case EOW : if (!endOfWord)
{
wordCounter++;
endOfWord = true;
}
break;
DalePhatANS_complete 8/18/04 10:31 AM Page 1115

Answers to Selected Exercises | 1115

case EOS :
sentenceCounter++;
endOfWord = true;
break;
case IGNORE: ignoreCounter++;
break;
case COMPOUND :
wordCounter++;
switch (Decode(character))
{

case UPPER : uppercaseCounter++;


break;
case LOWER : lowercaseCounter++;
break;
case DIGIT : digitCounter++;
break;
}

}
}

4. You could test to see if it had been set.


if (endOfWord)
endOfWord = false;

However, it takes about the same amount of time to just set it to the same value.
5. This program looks at each character in a file and classifies it as an uppercase letter, a
lowercase letter, a digit, an end-of-sentence symbol, an end-of-word symbol, or a
hyphen in the expanded version in Exercise 3. No errors can occur in classifying each
character, so no error detection is necessary. There may be logic errors in the determina-
tion of the number of words and sentences, but no error detection would find these.

Chapter 11 Exam Preparation Exercises


1. False.
2. True.
3. True.
4. True.
5.
yourName myName
first middle last first middle last
a. George
b. George Smith
c. George Smith George Smith
d. George Smith George Nathaniel Smith
e. George N. Smith George Nathaniel Smith
DalePhatANS_complete 8/18/04 10:31 AM Page 1116

1116 | Answers to Selected Exercises

6. Assignment, passing as a parameter, return value from a function.


7. An enumeration type holds values corresponding to different identifiers. A union holds
values of different types at different times.
8. a. sally.studentName.first = "Sally";
sally.studentName.middle = "Ellen";
sally,studentName.last = "Strong";

b. sally.gradeNumber = 7;
c. spring = sally.grades[3]
9. All of the fields of the struct are copied to the value parameter, and the function works
with the copy. Only the address of the struct would be passed to the reference parame-
ter, and the function would have direct access to the fields of the struct.
10. a. Makes the type of grade be char, and inputs a char to grade.
b. Compares the value in grade to see if it is in the range of ‘A' through ‘D'.
c. Computes the integer equivalent of the letter grade, changes the type of grade to
int, and assigns the numeric value to it.
11. Its domain and operations.
12. The data representation is a concrete form of the domain, expressed in terms of structures
and types supported by the programming language.
13. Private.
14. current.plus(period);
15. Observers, because they do not change the private data.
16. By matching the number, order, and types of the arguments with the parameter list.
17. Calendar primary;
Calendar primary(2004);

18. It is written with a tilde before the name.

Chapter 11 Programming Warm-Up Exercises


1. struct Time
{
int minutes;
int seconds;
}

2. someTime.minutes = 6;
someTime.seconds = 54;

3. struct Song
{
string title;
string album;
string artist;
Time playTime;
Category type;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1117

Answers to Selected Exercises | 1117

4. Song mySong;

mySong.title = "Long Run for a Collie Dog";


mySong.album = "Timmy's Nightmare"
mySong.artist = "Rebekah MacIntash";
mySong.playTime = someTime;
mySong.type = BLUES;

5. cout << mySong.playTime.minutes << ":"


<< mySong.playTime.seconds;
6. union Temporal
{
string asString;
int asInteger;
Time asTime;
}

7. Temporal shift;
shift = someTime;

8. //*****************************************
// SPECIFICATION FILE (Period)
// This file gives the specification of a
// class for geologic time periods
//*****************************************

class Period
{
public:
enum PeriodName { PRECAMBRIAN, CAMBRIAN, ORDOVICIAN,
SILURIAN, DEVONIAN, CARBONIFEROUS,
PERMIAN, TRIASSIC, JURASSIC,
CRETACEOUS, TERTIARY, QUATERNARY};

Period();
// Default constructor
// Creates object with value PRECAMBRIAN

Period(PeriodName);
// Constructor
// Creates object with value specified

String ToString() const;


// Observer
// Returns name of object as a string
DalePhatANS_complete 8/18/04 10:31 AM Page 1118

1118 | Answers to Selected Exercises

int ToInt() const;


// Observer
// Returns value of object as an int, 0 = PRECAMBRIAN

float StartDate() const;


// Observer
// Returns starting date of period in millions of years ago

void Increment();
// Transformer
// Advances value of object to next most recent period
// Won't advance past QUATERNARY

private:

PeriodName thisPeriod;

9. Period quaternary(QUATERNARY);
for (Period count; count.ToInt() <= quaternary.ToInt();
count.Increment())
cout << count.ToString() << ": " << count.StartDate() << endl;

10. Period::Period()
// Default constructor
// Creates object with value PRECAMBRIAN
{
PeriodName = PRECAMBRIAN;
}

Period::Period(/* in */ PeriodName aPeriod)


// Constructor
// Creates object with value specified
{
thisPeriod = aPeriod;
}

11. Period::ToInt() const


{
return int(thisPeriod);
}

12. The file would be called Period.h.


13. #include "Period.h"
DalePhatANS_complete 8/18/04 10:31 AM Page 1119

Answers to Selected Exercises | 1119

14. //*****************************************
// SPECIFICATION FILE (Money)
// This file gives the specification of a
// class for representing money as dollars
// and cents using integers.
//*****************************************

class Money
{
public:

Money();
// Default constructor
// Creates object with value $0.00

Money(int, int);
// Constructor
// Creates object with value specified
// in dollars and cents

int Dollars() const;


// Observer
// Returns dollars portion of object as an int

int Cents() const;


// Observer
// Returns cents portion of object as an int

float Amount() const;


// Observer
// Returns money value as a float

void Add(Money);
// Transformer
// Adds value of money object in parameter

void Sub(Money);
// Transformer
// Subtracts value of money object in parameter

private:

int dollars;
int cents;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1120

1120 | Answers to Selected Exercises

15. Money::Money()
// Default constructor
// Creates object with value $0.00
{
dollars = 0;
cents = 0;
}

Money::Money(/* in */ int userDollars,


/* in */ int userCents)
// Constructor
// Creates object with value specified
{
dollars = userDollars;
cents = userCents;
}

16. The file name would be Money.h.


17. #include "Money.h"
18. float Money::Amount() const
// Observer
// Returns money value as a float
{
return float(dollars) + float(cents)/100.0;
}

Chapter 11 Case Study Follow-Up Exercises


1. There are two constructors, one default and one parameterized. The other five functions
are observer functions. FirstName, MiddleName, and LastName return the value in the
class fields. MiddleInitial extracts the first character in the middle name and returns
it. ComparedTo takes two instances of the class and returns their relative positions in
terms of alphabetic ordering.
2. To test the NameType ComparedTo function, pairs of names must be compared that
allow each of the return statements to be executed. Pairs of names satisfying the follow-
ing conditions should be included:
a. The last name is less than the second last name.
b. The last name is greater than the second last name.
c. The last names are equal, and the first first name is less than the second first name.
d. The last names are equal, and the first first name is greater than the second first
name.
e. The last names and first names are equal, and the first middle name is less than the
second middle name.
f. The last names and first names are equal, and the first middle name is greater than
the second middle name.
g. The last names, first names, and middle names are the same.
DalePhatANS_complete 8/18/04 10:31 AM Page 1121

Answers to Selected Exercises | 1121

It is easier to choose one name and then vary the one to which it is compared. The letter
in the Reason for Test Case column refers back to the letters above. The name David John
Jones is compared to the input, which is the second name. This is not repeated in the
table. The expected output column does not show the completely documented output,
just the path.

Reason for Input Expected Output Observed


Test Case Output
a. David John Smith Jones comes before Smith
b. David John Allen Jones comes after Allen
c. William John Jones David Jones comes before William
Jones
d. Allen John Jones David Jones comes after Allen Jones
e. David William Jones David John Jones comes before David
William Jones
f. David Allen Jones David John Jones comes after David
Allen Jones
g. David John Jones They are the same

3. #include <iostream>
#include "NameType.h"

using namespace std;

int main()
{
NameType name1("David", "John", "Jones");

string name1w = name1.FirstName() + ' ' + name1.MiddleName()


+ ' ' + name1.LastName();

for (int count = 1; count <= 7; count++)


{
NameType name2;
string name2w = name2.FirstName() +
' ' + name2.MiddleName() + ' ' + name2.LastName();

switch (name1.ComparedTo(name2))
{
DalePhatANS_complete 8/18/04 10:31 AM Page 1122

1122 | Answers to Selected Exercises

case BEFORE :
cout << name1w << " comes before "
<< name2w << endl;
break;
case SAME :
cout << name1w << " is the same as "
<< name2w << endl;
break;
case AFTER :
cout << name1w << " comes after "
<< name2w << endl;
}

}
return 0;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1123

Answers to Selected Exercises | 1123

4. The initial comes before the same letter in a longer string. The period comes before any
letter in a longer string in that position.
5. Enhance the NameType class with a title field and an observer function to return its
value.
//*****************************************************************
// SPECIFICATION FILE (Name.h)
// This file gives the specification of the Name abstract
// data type. There are two constructors: one takes the first,
// middle, and last name as parameters and the second prompts for
// and reads the name from the standard input device.
//*****************************************************************
#include <iostream>
#include <string>
#include "relType.h"

using namespace std;

class Name
{
public:
Name();
// Default constructor
// Postcondition:
// first, middle, last, and title have been set to blanks

Name( /* in */ string firstName,


/* in */ string middleName,
/* in */ string lastName,
/* in */ string nameTitle );
// Parameterized constructor
// Postcondition:
// first is firstName AND middle is middleName AND
// last is lastName AND title is nameTitle

void SetName( /* in */ string firstName,


/* in */ string middleName,
/* in */ string lastName,
/* in */ string nameTitle );
// Postcondition:
// first is firstName AND middle is middleName AND
// last is lastName AND title is nameTitle
DalePhatANS_complete 8/18/04 10:31 AM Page 1124

1124 | Answers to Selected Exercises

void ReadName();
// Postcondition:
// Name is prompted for and read from the standard input
// device

string FirstName() const;


// Postcondition:
// Return value is this person's first name

string LastName() const;


// Postcondition:
// Return value is this person's last name

string MiddleName() const;


// Postcondition:
// Return value is this person's middle name

char MiddleInitial() const;


// Postcondition:
// Return value is this person's middle initial

string Title() const;


// PostCondition:
// Return value is this person's title

RelationType ComparedTo( /* in */ Name otherName ) const;


// Postcondition:
// Return value is
// BEFORE, if this name comes before otherName
// SAME, if this name and otherName are the same
// AFTER, if this name is after otherName

private:
string first; // Person's first name
string last; // Person's last name
string middle; // Person's middle name
string title; // Person's title
};

//*****************************************************************
// IMPLEMENTATION FILE (Name.cpp)
// The file implements the Name member functions.
//*****************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1125

Answers to Selected Exercises | 1125

#include "Name.h"
#include <iostream>

//******************************************************************
Name::Name()
// Default constructor
// Postcondition:
// first, middle, and last have been set to blanks
{
first = " ";
middle = " ";
last = " ";
title = " ";
}

//******************************************************************

Name::Name( /* in */ string firstName, // First name


/* in */ string middleName, // Middle name
/* in */ string lastName, // Last name
/* in */ string nameTitle) // Title
// Parameterized constructor
// Postcondition:
// firstName has been stored in first; middleName has been
// stored in middle; lastName has been stored in last;
// nameTitle has been stored in title
{
first = firstName; // Assign parameters
last = lastName;
middle = middleName;
title = nameTitle)
}

//******************************************************************

void Name::SetName( /* in */ string firstName, // First name


/* in */ string middleName, // Middle name
/* in */ string lastName, // Last name
/* in */ string nameTitle) // Title
// Postcondition:
// firstName has been stored in first; middleName has been
// stored in middle; lastName has been stored in last;
// nameTitle has been stored in title
DalePhatANS_complete 8/18/04 10:31 AM Page 1126

1126 | Answers to Selected Exercises

{
first = firstName; // Assign parameters
last = lastName;
middle = middleName;
title = nameTitle;
}

//******************************************************************

void Name::ReadName()
// Postcondition:
// Name prompted for and read from the standard input device
{
cout << "Enter first name: "; // Prompt for first name
cin >> first; // Get first name
cout << "Enter middle name: "; // Prompt for middle name
cin >> middle; // Get middle name
cout << "Enter last name: "; // Prompt for last name
cin >> last; // Get last name
cout << "Enter title: "; // Prompt for title
cin >> title; // Get title
}

//******************************************************************
string Name::FirstName() const
// Postcondition:
// Return value is first
{
return first;
}

//******************************************************************

string Name::LastName() const


// Postcondition:
// Return value is last
{
return last;
}

//******************************************************************

string Name::MiddleName() const


// Postcondition:
// Return value is middle
DalePhatANS_complete 8/18/04 10:31 AM Page 1127

Answers to Selected Exercises | 1127

{
return middle;
}

//******************************************************************

string Name::Title() const


// Postcondition:
// Return value is title
{
return title;
}

//******************************************************************

char Name::MiddleInitial() const


// Postcondition:
// Return value is middle initial
{
return middle[0];
}

//******************************************************************

RelationType Name::ComparedTo( /* in */ Name otherName ) const


// Precondition:
// Input parameter contains a valid name
// Postcondition:
// Return value is
// BEFORE, if this name comes before otherName
// SAME, if this name and otherName are the same
// AFTER, if this name is after otherName
{
if (last < otherName.last)
return BEFORE;
else if (otherName.last < last)
return AFTER;
else if (first < otherName.first)
return BEFORE;
else if (otherName.first < first)
return AFTER;
else if (middle < otherName.middle)
return BEFORE;
DalePhatANS_complete 8/18/04 10:31 AM Page 1128

1128 | Answers to Selected Exercises

else if (otherName.middle < middle)


return AFTER;
else
return SAME;
}

If you add the title to the ComparedTo function, the titles would be compared as strings.
Mr. would come before Mrs. and Dr. would come before Mr. There would be no semantic
sense in such a comparison.

Chapter 12 Exam Preparation Exercises


1. False.
2. True.
3. False.
4. True.
5. True.
6. C++ does not report an out-of-bounds access as an error. The program accesses the loca-
tion preceding the first element of the array, which may be a completely unrelated value
in memory.
7. Arrays can be passed as arguments to reference parameters. No other aggregate opera-
tions are allowed.
8. The base address is the memory location of the first element of an array. It is the value
that is passed to a reference parameter in a function call.
9. A string.
10. The inner loop would increment the column index, keeping the row constant. The outer
loop would increment the row index to move to the next row after each row is processed.
11. a. 27, b. 15, c. 100,000,000.
12. The For loop runs from 1 to 100 instead of 0 to 99. The last iteration will assign zero to
an out-of-bounds location.
13. Comparison of arrays is not allowed in C++.
14. Functions cannot return array types.
15. The rows and columns are reversed in the initializer list. This list fits an array that is
[4][3]. However, C++ would still place the 12 values within the array—just not in the
locations that we would expect by looking at their arrangement in the code.
16. Because the index value is input and then used without any checking, an out-of-bounds
array access is likely.
17. In addition to returning the maximum value, the function returns with the array ordered
least to greatest.
18. * **
* *
* **
* *
* **

19. ***
DalePhatANS_complete 8/18/04 10:31 AM Page 1129

Answers to Selected Exercises | 1129

20. * * *
* *
* * *
* *
* * *

21. a. for (int col = 0; col < 15; col++)


cout << examPrep[0][col] << " ";

b. for (int row = 0; row < 15; row++)


cout << examPrep[row][0] << " ";

c. for (int row = 0; row < 7; row++)


{
for (int col = 0; col < 15; col++)
cout << examPrep[row][col] << " ";
cout << endl;
}
d. for (int row = 11; row >= 0; row--)
{
for (int col = 14; col >= 0; col--)
cout << examPrep[row][col] << " ";
cout << endl;
}

Chapter 12 Programming Warm-Up Exercises


1. a. string topTenList[10];
b. enum Spectrum {RED, ORANGE, YELLOW, BLUE,
GREEN, INDIGO, VIOLET};
float colorMix[7];

c. struct dayRecord
{
int Day;
string activity;
};
enum DayNames {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY};
dayRecord Calendar[6][7];

2. typedef float DataSet[5];


DataSet input;
DataSet output;
DataSet working;
DalePhatANS_complete 8/18/04 10:31 AM Page 1130

1130 | Answers to Selected Exercises

3. DataSet set[3];
4. for (int row = 0; row < 3; row++)
for (int col = 0; col < 5; col++)
set[row][col] = 0.0;

5. bool Equals (/* in */ const DataSet first,


/* in */ const DataSet second)

6. bool Equals (/* in */ const DataSet first,


/* in */ const DataSet second)
{
for(int index = 0; index < 5; index++)
if (first[index] != second[index])
return false;
// Only reaches end of loop if all are equal
return true;
}

7. struct Size
{
int height;
int width;
};
enum Medium {OIL, WATERCOLOR, PASTEL, ACRYLIC,
PRINT, COLORPHOTO, BWPHOTO};
enum Room {MAIN, GREEN, BLUE, NORTH, SOUTH,
ENTRY, BALCONY};
struct ArtWork
{
string artist;
string title;
Medium medium;
Size size;
Room room;
float price;
}
typedef ArtWork GalleryList[120];
ArtWork currentList;
int numPieces;

8. a. currentList[36]
b. currentList[11].title
c. currentList[84].size.width
d. currentList[119].room
e. currentList[77].artist[0]
DalePhatANS_complete 8/18/04 10:31 AM Page 1131

Answers to Selected Exercises | 1131

9. for (int index = 0; index < numPieces; index++)


cout << currentList[index].artist << " "
<< currentList[index].title << " "
<< currentList[index].price << endl;

10. float total = 0.0;


for (int index = 0; index < numPieces; index++)
total = total + currentList[index].price;

11. for (int index = 0; index < numPieces; index++)


if (currentList[index].room == BLUE)
cout << currentList[index].title << endl;

12. float total = 0.0;


for (int index = 0; index < numPieces; index++)
if(currentList[index].medium == OIL)
if (currentList[index].size.width *
currentList[index].size.height > 400)
total = total + currentList[index].price;

13. enum Notes {C, CSHARP, D, DSHARP, E, F, FSHARP,


G, GSHARP, A, ASHARP, B};
float scale[8][12];

14. for (int octave = 0; octave < 8; octave++)


for (Notes note = A; note <= GSHARP; note = Notes(note + 1))
cin >> scale[octave][note];

15. for (Notes note = A; note <= GSHARP; note = Notes(note + 1))
cout << scale[3][note] << endl;

16. for (int octave = 0; octave < 8; octave++)


cout << scale[octave][C] << endl;

17. float humidity[10][52][50][3];


18. void Reset (float humidity[10][52][50][3])
{
for (int year = 0; year < 10; year++)
for (int week = 0; week < 52; week++)
for (int state = 0; state < 50; state++)
for (Type type = MAX; type <= AVERAGE;
type = Type(type + 1));
humidity = 0.0;
}

19. struct TimePlace


{
int year;
int week;
int state;
DalePhatANS_complete 8/18/04 10:31 AM Page 1132

1132 | Answers to Selected Exercises

float difference;
}

TimePlace MaxSpread(float humidity[10][52][50][3])


{
TimePlace max;
float difference;
max.year = 0;
max.week = 0;
max.state = 0;
max.difference = 0.0;
for (int year = 0; year < 10; year++)
for (int week = 0; week < 52; week++)
for (int state = 0; state < 50; state++)
{
difference = humidity[year][week][state][MAX] –
humidity[year][week][state][MIN];
if (difference > max.difference)
{
max.difference = difference;
max.year = year;
max.week = week;
max.state = state;
}
}
return max;
}

20. for (int year = 5; year < 10; year++)


for (int week = 0; week < 52; week++)
cout << humidity[year][week][22][AVERAGE] << endl;

Chapter 12 Case Study Follow-Up Exercises


1. The input file cannot be found, a grade is outside the range of 0 to 100, a grade is nega-
tive.
2. It would be more efficient to calculate and print the values without storing them. How-
ever, the Print Results module would have two major tasks: calculating values and print-
ing them. It is better style to separate these tasks.
3. When an index has semantic content, the index’s role in the problem is more than just as
an accessor into an array. The index has meaning within the problem itself. In this
problem, a grade was used as an index into the grade’s frequency counter. If grade is 60,
grades[grade] tells how many times the grade 60 has occurred in the file.
DalePhatANS_complete 8/18/04 10:31 AM Page 1133

Answers to Selected Exercises | 1133

4. void OpenFiles(ifstream& text, ofstream& outFile)


// Function OpenFiles reads in the names of the input file and the
// output file, opens them for processing, prompts for a heading
// for the output file, reads the heading, and prints
// it in the file

{
string inFileName;
string outFileName;
string heading;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outFileName;
outFile.open(outFileName.c_str());
cout << "Enter a heading for the output file." << endl;
cin >> heading;
outFile << heading << endl << endl;
}

5. It might be slightly better to have the input of the heading in the function that does the
printing.

Chapter 13 Exam Preparation Exercises


1. Because each component except the first has a unique predecessor, and each component
except the last has a unique successor.
2. That all of the components have the same type.
3. a. 20, b. 42, c. 42, d. 1.
4. while (index < length && fabs(item –data[index]) >= EPSILON)
We need to change it because floating point numbers cannot be compared reliably for
exact equality.
5. temp = data[value1];
data[value1] = data[value2];
data[value2] = temp;

6. It has identified the smallest value in the portion of the list that remains to be sorted.
7. a. 20, b. 21, c. 42, d. 22.
8. True.
9. True.
10. 5
11. Because the values in a sorted list are always kept in order.
12. Two iterations. Middle is initially 7, then location 11 (which holds the 12th value)
becomes middle.
13. 'H', 'o', 'p', and '\0'
DalePhatANS_complete 8/18/04 10:31 AM Page 1134

1134 | Answers to Selected Exercises

Chapter 13 Programming Warm-Up Exercises


1. bool Deleted (/* in */ ItemType someItem,
/* in */ List oldList,
/* in */ List newList)
{
return oldList.IsPresent(someItem) &&
!newList.IsPresent(someItem);
}

2. void List::Insert( /* in */ ItemType item)

// Inserts item into list without duplication

{
if (!IsPresent(item))
{
data[length] = item;
length++;
}
}

3. The List type is only defined to have enough room for 50 items. We must change
MAX_LENGTH in the specification file to be at least 100.
4. void DeleteAll( /* in */ ItemType item);
// Precondition:
// NOT IsEmpty()
// && item is assigned
// Postcondition:
// IF item is present in list
// All occurrences of item are deleted from list
// && Length() ==
// Length()[at]entry – number of occurrences of item
// ELSE
// List is unchanged

5. void List::DeleteAll( /* in */ ItemType item)

// Deletes all occurrences of item from the list

{
int index = 0;
while (index < length)
{
if (item == data[index])
{
DalePhatANS_complete 8/18/04 10:31 AM Page 1135

Answers to Selected Exercises | 1135

data[index] = data[length – 1];


length--;
}
index++;
}
}

6. void Replace( /* in */ ItemType item,


/* in */ ItemType newItem);
// Precondition:
// NOT IsEmpty()
// && oldItem is assigned
// && newItem is assigned
// Postcondition:
// IF oldItem is present in list
// First occurrences of oldItem is replaced by newItem
// ELSE
// List is unchanged

7. void List::Replace( /* in */ ItemType oldItem,


/* in */ ItemType newItem)

// Replaces first occurrence of oldItem with newItem

{
int index = 0;
while (index < length && oldItem != data[index])
index++;
if (index < length)
data[index] = newItem;
}

8. The Insert and BinSearch functions must be changed to enable descending order. We
don’t have to change IsPresent or Delete, because they both use BinSearch to locate
the item.
9. The only changes needed to make the binary search work with descending order are to
cause the search area to change to the last half of the current search area when the item
is less than the middle value, and vice versa. These changes are noted with comments in
the following code:
void SortedList::BinSearch(
/* in */ ItemType item,
/* out */ bool& found,
/* out */ int& position ) const
{
int first = 0;
DalePhatANS_complete 8/18/04 10:31 AM Page 1136

1136 | Answers to Selected Exercises

int last = length;


int middle;

found = false;
while (last >= first && !found)
{
middle = (first + last) / 2;
if (item > data[middle]) // Changed < to >
last = middle - 1;
else if (item < data[middle]) // Changed > to <
first = middle + 1;
else
found = true;
}
if (found)
position = middle;
}

10. void SortedList::DeleteAll( /* in */ ItemType item)

// Deletes all occurrences of item from the list

{
int first;
int index = 0;
while (index < length && item != data[index])
index++;
first = index;
while (index < length && item == data[index])
index++;
for (int position = index; position < length; position++)
data[first + position - index] = data[position];
length = length – (index – first);
}

11. The simplest way to do this is to use the member functions Delete and Insert. We could
also combine the code from both of these functions into a single function; however, the
savings from that approach would be minimal: We would avoid the decrementing and
incrementing of length, and save the overhead of calling the functions.
void SortedList::Replace( /* in */ ItemType oldItem,
/* in */ ItemType newItem)

// Replaces an occurrence of oldItem with newItem


DalePhatANS_complete 8/18/04 10:31 AM Page 1137

Answers to Selected Exercises | 1137

{
int oldLength;
oldLength = length;
Delete(oldItem);
if (oldLength > length) // Only insert if oldItem deleted
Insert(newItem);
}

12. SortedList inData;


ifStream unsorted;
ItemType oneItem;

unsorted >> oneItem;


while (unsorted && !inData.IsFull())
{
inData.Insert(oneItem);
unsorted >> oneItem;
}

13. void SortedList::FilePrint(


/* inout */ ofstream& outFile) const
{
int index;
for (index = 0; index < length; index++)
outFile << data[index] << endl;
}

Chapter 13 Case Study Follow-Up Exercises


1. There is a personal preference.
2. //******************************************************************
// Statistics Program
// This program calculates the average, high score, low score,
// number above the average, and number below the average for
// a file of test scores. The List ADT is used
// Assumption: File "testScores" is not empty and does not contain
// more than MAX_GRADES values.
// To save space, we omit from each function the precondition
// comments that document the assumptions made about valid input
// parameter data. These would be included in a program intended
// for actual use.
// CalculateAverage, CalculateHighest, and CalculateLowest are
// combined into one function.
//******************************************************************

#include <fstream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1138

1138 | Answers to Selected Exercises

#include <iostream>
#include <iomanip>
#include "list.h"

using namespace std;

// Function Prototypes

void OpenFiles(ifstream& inData, ofstream& outData);


void InputGrades(List& grades, ifstream& inData);
void Calculate(List grades, float& average, int& highest,
int& lowest);
int CalculateAboveAverage(List grades, float average);
int CalculateBelowAverage(List grades, float average);
void PrintResults(ofstream& outData, List grades, float average,
int highest, int lowest, int aboveAverage, int belowAverage);

int main()
{
List grades; // A list of grades

float average; // Average grade


int highest; // Highest grade
int lowest; // Lowest grade
int aboveAverage; // Number of grades above the average
int belowAverage; // Number of grades below the average

// Declare and open files


ifstream inData;
ofstream outData;
OpenFiles(inData, outData);
if ( !inData // i.outData )
{
cout << "Files did not open successfully"
<< endl;
return 1;
}
// Process grades
InputGrades(grades, inData);
Calculate(grades, average, highest, lowest);
aboveAverage = CalculateAboveAverage(grades, average);
belowAverage = CalculateBelowAverage(grades, average);
PrintResults(outData,grades, average, highest, lowest,
aboveAverage, belowAverage);
DalePhatANS_complete 8/18/04 10:31 AM Page 1139

Answers to Selected Exercises | 1139

inData.close();
outData.close();
return 0;
}

//*****************************************************************

void OpenFiles( /* inout */ ifstream& text,


/* inout */ ofstream& outFile )

// Function OpenFiles reads in the names of the input file and


// the output file and opens them for processing
// Postcondition:
// Files have been opened AND a label has been written on the
// output file

{
string inFileName;
string outDataName;

cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());

cout << "Enter the name of the output file" << endl;
cin >> outDataName;
outFile.open(outDataName.c_str());

// Write label on output


outFile << "Grade statistics using the List ADT" << endl
<< endl;
}

//******************************************************************

void InputGrades( /* inout */ List& grades, // Grade list


/* inout */ ifstream& inData ) // Input file

// Grades are input from file inData and inserted into grades.
// Precondition:
// File is not empty
// Postcondition:
// Each grade in the file has been inserted into list of grades
DalePhatANS_complete 8/18/04 10:31 AM Page 1140

1140 | Answers to Selected Exercises

{
int grade;
// Read grades and put them into the list
inData >> grade;
while (inData && !grades.IsFull())
{
grades.Insert(grade);
inData >> grade;
}
}

//*****************************************************************

void Calculate( /* in */ List grades,


/* out */ float& average,
/* out */ int& highest,
/* out */ int& lowest )

// This function calculates the average test score


// Postcondition:
// Return value is the average grade

{
int sum = 0;
int limit = grades.Length(); // limit is the number of grades
int grade;

highest = 0;
lowest = 100;

grades.Reset(); // Prepare for traversal

// Add each grade to sum


for (int index = 0; index < limit; index++)
{
grade = grades.GetNextItem();
sum = sum + grade;
if (grade > highest)
highest = grade;
if (grade < lowest)
lowest = grade;
}

average = float(sum) / float(limit); // Return average


}
DalePhatANS_complete 8/18/04 10:31 AM Page 1141

Answers to Selected Exercises | 1141

//*****************************************************************

int CalculateAboveAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade

// This function calculates the number of grades above the


// average
// Postcondition:
// Return value is the number of grades above average

{
int roundedAverage = (int) (average + 0.5);
int limit = grades.Length(); // Number of grades
int grade;
int number = 0;

grades.Reset(); // Prepare for iteration

// Calculate the number of grades above the average


for (int index = 0; index < limit; index++)
{
grade = grades.GetNextItem();
if (grade > roundedAverage)
number++;
}
return number;
}

//*****************************************************************

int CalculateBelowAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade

// This function calculates the number of grades below the


// average
// Postcondition:
// Return value is the number of grades below average

{
int truncatedAverage = (int) (average);
int limit = grades.Length(); // Number of grades
int grade;
DalePhatANS_complete 8/18/04 10:31 AM Page 1142

1142 | Answers to Selected Exercises

int number = 0;

grades.Reset(); // Prepare for iteration

// Calculate the number of grades below the average


for (int index = 0; index < limit; index++)
{
grade = grades.GetNextItem();
if (grade < truncatedAverage)
number++;
}
return number;
}

//*****************************************************************

void PrintResults( /* inout */ ofstream& outData, // Output file


/* in */ List grades, // Grade list
/* in */ float average, // Average
/* in */ int highest, // Max grade
/* in */ int lowest, // Min grade
/* in */ int aboveAverage, // Number above
/* in */ int belowAverage ) // Number below

// Statistics are printed on file outData


// Precondition:
// Output file has been successfully opened
// Postcondition:
// Statistics have been written on outData, appropriately
// labeled

{
outData << "The number of grades is " << grades.Length()
<< endl;
outData << fixed << setprecision(2) << "The average grade is "
<< average << endl;
outData << "The highest grade is " << highest << endl;
outData << "The lowest grade is " << lowest << endl;
outData << "The number of grades above the average is "
<< aboveAverage << endl;
outData << "The number of grades below the average is "
<< belowAverage << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1143

Answers to Selected Exercises | 1143

3. //******************************************************************
// Statistics Program
// This program calculates the average, high score, low score,
// number above the average, and number below the average for
// a file of test scores. The List ADT is used
// Assumption: File "testScores" is not empty and does not contain
// more than MAX_GRADES values.
// To save space, we omit from each function the precondition
// comments that document the assumptions made about valid input
// parameter data. These would be included in a program intended
// for actual use.
// CalculateAboveAverage and CalculateBelowAverage are combined
// into one function.
//******************************************************************

#include <fstream>
#include <iostream>
#include <iomanip>
#include "list.h"

using namespace std;

// Function Prototypes

void OpenFiles(ifstream& inData, ofstream& outData);


void InputGrades(List& grades, ifstream& inData);
void Calculate(List grades, float& average, int& highest,
int& lowest);
void CalculateAboveBelow(List grades, float average,
int& aboveAverage, int& belowAverage);
void PrintResults(ofstream& outData, List grades, float average,
int highest, int lowest, int aboveAverage, int belowAverage);

int main()
{
List grades; // A list of grades

float average; // Average grade


int highest; // Highest grade
int lowest; // Lowest grade
int aboveAverage; // Number of grades above the average
int belowAverage; // Number of grades below the average

// Declare and open files


DalePhatANS_complete 8/18/04 10:31 AM Page 1144

1144 | Answers to Selected Exercises

ifstream inData;
ofstream outData;
OpenFiles(inData, outData);
if ( !inData // i.outData )
{
cout << "Files did not open successfully"
<< endl;
return 1;
}

// Process grades
InputGrades(grades, inData);
Calculate(grades, average, highest, lowest);
CalculateAboveBelow(grades, average, aboveAverage, belowAverage);

PrintResults(outData,grades, average, highest, lowest,


aboveAverage, belowAverage);

inData.close();
outData.close();
return 0;
}

//*****************************************************************

void OpenFiles( /* inout */ ifstream& text,


/* inout */ ofstream& outFile )

// Function OpenFiles reads in the names of the input file and


// the output file and opens them for processing
// Postcondition:
// Files have been opened AND a label has been written on the
// output file

{
string inFileName;
string outDataName;

cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());

cout << "Enter the name of the output file" << endl;
cin >> outDataName;
DalePhatANS_complete 8/18/04 10:31 AM Page 1145

Answers to Selected Exercises | 1145

outFile.open(outDataName.c_str());

// Write label on output


outFile << "Grade statistics using the List ADT" << endl
<< endl;
}

//******************************************************************

void InputGrades( /* inout */ List& grades, // Grade list


/* inout */ ifstream& inData ) // Input file

// Grades are input from file inData and inserted into grades.
// Precondition:
// File is not empty
// Postcondition:
// Each grade in the file has been inserted into list of grades

{
int grade;
// Read grades and put them into the list
inData >> grade;
while (inData && !grades.IsFull())
{
grades.Insert(grade);
inData >> grade;
}
}

//*****************************************************************

void Calculate( /* in */ List grades,


/* out */ float& average,
/* out */ int& highest,
/* out */ int& lowest )

// This function calculates the average test score


// Postcondition:
// Return value is the average grade

{
int sum = 0;
int limit = grades.Length(); // limit is the number of grades
int grade;
DalePhatANS_complete 8/18/04 10:31 AM Page 1146

1146 | Answers to Selected Exercises

highest = 0;
lowest = 100;

grades.Reset(); // Prepare for traversal

// Add each grade to sum


for (int index = 0; index < limit; index++)
{
grade = grades.GetNextItem();
sum = sum + grade;
if (grade > highest)
highest = grade;
if (grade < lowest)
lowest = grade;
}

average = float(sum) / float(limit); // Return average


}

//*****************************************************************

void CalculateAboveBelow
( /* in */ List grades, // List of grades
/* in */ float average, // Average grade
/* out */ int& aboveAverage,
/* out */ int& belowAverage)

// This function calculates the number of grades above the


// average
// Postcondition:
// Return value is the number of grades above average

{
int roundedAverage = (int) (average + 0.5);
int truncatedAverage = (int) (average);
int limit = grades.Length(); // Number of grades
int grade;
aboveAverage = 0 ;
belowAverage = 0;
grades.Reset(); // Prepare for iteration

// Calculate the number of grades above the average


for (int index = 0; index < limit; index++)
DalePhatANS_complete 8/18/04 10:31 AM Page 1147

Answers to Selected Exercises | 1147

{
grade = grades.GetNextItem();
if (grade > roundedAverage)
aboveAverage++;
if (grade < truncatedAverage)
belowAverage++;
}

//*****************************************************************

int CalculateBelowAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade

// This function calculates the number of grades below the


// average
// Postcondition:
// Return value is the number of grades below average

int limit = grades.Length(); // Number of grades


int grade;
int number = 0;

grades.Reset(); // Prepare for iteration

// Calculate the number of grades below the average


for (int index = 0; index < limit; index++)
{
grade = grades.GetNextItem();
}
return number;
}

//*****************************************************************

void PrintResults( /* inout */ ofstream& outData, // Output file


/* in */ List grades, // Grade list
/* in */ float average, // Average
/* in */ int highest, // Max grade
/* in */ int lowest, // Min grade
/* in */ int aboveAverage, // Number above
/* in */ int belowAverage ) // Number below
DalePhatANS_complete 8/18/04 10:31 AM Page 1148

1148 | Answers to Selected Exercises

// Statistics are printed on file outData


// Precondition:
// Output file has been successfully opened
// Postcondition:
// Statistics have been written on outData, appropriately
// labeled

{
outData << "The number of grades is " << grades.Length()
<< endl;
outData << fixed << setprecision(2) << "The average grade is "
<< average << endl;
outData << "The highest grade is " << highest << endl;
outData << "The lowest grade is " << lowest << endl;
outData << "The number of grades above the average is "
<< aboveAverage << endl;
outData << "The number of grades below the average is "
<< belowAverage << endl;
}

4. This is a matter of personal style.

Chapter 14 Exam Preparation Exercises


1. a. viii, b. iii, c. ix, d. ii, e. vi, f. v, g. vii, h. i, i. iv.
2. True.
3. False.
4. True.
5. In the base class declaration file?
6. Declaration of a class data member to be an object of the class that we want to compose
into the new class being defined.
7. The additional data members are sliced off when the object is copied into the variable.
8. The class declaration for DerivedClass doesn’t specify that it is making the members of
BaseClass public, so they are not available to the client code. The heading should be
changed to:
class DerivedClass : public BaseClass

9. a. BaseClass: Private data members are baseField. DerivedClass: Private data


members are derivedField and baseField.
b. BaseClass: The member functions can access baseField. DerivedClass: The
member functions can only access derivedField.
c. BaseClass: The member functions BaseAlpha and BaseBeta can access each other
directly. DerivedClass: The functions DerivedAlpha and DerivedBeta can access
each other directly, and they can also access BaseAlpha.
d. BaseClass: A client may invoke BaseAlpha. DerivedClass: A client may invoke
DerivedAlpha, DerivedBeta, or BaseAlpha.
DalePhatANS_complete 8/18/04 10:31 AM Page 1149

Answers to Selected Exercises | 1149

10. a. The BaseClass constructor is called first.


b. The DerivedClass constructor is called last.
11. Because, in pass-by-value, the data members of the derived class arguments are copied
into the corresponding members of the base class object parameter, and if there is no cor-
responding member in the base class, the argument value is discarded. But in pass-by-
reference, only the address of the argument object is passed, so nothing needs to be
discarded.
12. The virtual designation should be used only with the base class declaration of BaseAl-
pha.
13. The is-a relationship applies to derived classes and their base classes. The has-a relation-
ship describes composition, where one object has a member that is another object.
14. c.

Chapter 14 Programming Warm-Up Exercises


1. class IDScore : public TestScore
{
public:
IDScore( /* in */ string name,
/* in */ int score),
/* in */ int IDNumber);
int GetIDNumber() const;
private:
int studentIDNumber;
};

2. #include "testscore.h"
#include <iostream>
#include <string>

using namespace std;

TestScore::TestScore(
/* in */ string name,
/* in */ int score)
{
studentName = name;
studentScore = score;
}

TestScore::string GetName() const


{
return studentName;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1150

1150 | Answers to Selected Exercises

TestScore::int GetScore() const


{
return studentScore;
}
3.
#include "idscore.h"
#include <iostream>
#include <string>

using namespace std;

IDScore::IDScore(
/* in */ string name,
/* in */ int score,
/* in */ int IDNumber )
: TestScore(name, score)
{
studentIDNumber = IDNumber
}

IDScore::int GetIDNumber() const


{
return StudentIDNumber;
}

4. #include "idscore.h"

class Exam
{
public:
SetScore(
/* in */ int location,
/* in */ IDScore score );
IDScore GetScore(
/* in */ int location ) const;

private:
IDScore examList[100];
}

5. #include "exam.h"

using namespace std;

Exam::SetScore(
DalePhatANS_complete 8/18/04 10:31 AM Page 1151

Answers to Selected Exercises | 1151

/* in */ int location,
/* in */ IDScore score )
{
examList[location] = score;
}

Exam::IDScore GetScore( /* in */ int location ) const


{
return examList[location];
}

6. class InternPhone : public Phone


{
public
InternPhone
( /* in */ int newCountry,
/* in */ int newAreaCode,
/* in */ int newNumber,
/* in / PhoneType newType );
void Write () const;
private:
int country;
}

7. using namespace std;

InternPhone::InternPhone(
( /* in */ int newCountry,
/* in */ int newAreaCode,
/* in */ int newNumber,
/* in */ PhoneType newType)

: Phone(newAreaCode, newNumber, newType)


{
country = newCountry;
}

8. void InternPhone::Write() const


{
cout << country;
Phone::Write();
cout << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1152

1152 | Answers to Selected Exercises

9. The Write function of the Phone class must be declared virtual.


class Phone
{
public:
virtual void Write() const;
};

In the WritePhone function, the parameter must be passed by reference:


void WritePhone( /* in */ Phone& somePhone )
{
somePhone.Write();
}

10. class InstallRecord : public Computer


{
public:
InstallRecord(
/* in */ string newName,
/* in */ string newBrand,
/* in */ string newModel,
/* in */ int newSpeed,
/* in */ string newSerial,
/* in */ int newNumber,
/* in */ string newLocation,
/* in */ SimpleDate newDate );
void Write() const;
string getNewLocation();
SimpleDate getSimpleDate();

private:
string location;
SimpleDate installDate;
};

11. Computer::Computer(
/* in */ string newName,
/* in */ string newBrand,
/* in */ string newModel,
/* in */ int newSpeed,
/* in */ string newSerial,
/* in */ int newNumber )
{
name = newName;
brand = newBrand;
model = newModel;
DalePhatANS_complete 8/18/04 10:31 AM Page 1153

Answers to Selected Exercises | 1153

speed = newSpeed;
serialNumber = newSerial;
inventoryNumber = newNumber;
}

12. InstallRecord::InstallRecord(
/* in */ string newName,
/* in */ string newBrand,
/* in */ string newModel,
/* in */ int newSpeed,
/* in */ string newSerial,
/* in */ int newNumber,
/* in */ string newLocation,
/* in */ SimpleDate newDate )
: Computer( newName, newBrand, newModel,
newSpeed, newSerial, newNumber )
{
location = newLocation;
installDate = newDate;
}

13. void Computer::Write() const;


{
cout << name << endl;
cout << brand << endl;
cout << model << endl;
cout << speed << endl;
cout << serialNumber << endl;
cout << inventoryNumber << endl;
}

14. void InstallRecord::Write() const;


{
Computer::Write();
cout << location << endl;
installDate.Write();
}

15. Add the following to the specification file:


void ReadTime();

// Postcondition:
// hours, minutes, seconds and time zone have been prompted
// for, read, and set
DalePhatANS_complete 8/18/04 10:31 AM Page 1154

1154 | Answers to Selected Exercises

Add the following to the implementation file:


void ExTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs, mins, and secs

{
string timeZone;
Time::ReadTime();
cout << "Please enter time zone: EST, CST, MST, "
<< "PST, EDT, CDT, MDT, or PDT." << endl;
cin >> timeZone;
if (timeZone == "PST")
zone = EST;
else if (timeZone == "MST")
zone = CST;
else if (timeZone == "PST")
zone = PST;
else if (timeZone = "EDT")
zone = EDT;
else if (timeZone == "CDT")
zone = CDT;
else if (timeZone == "MDT")
zone = MDT;
else
zone = PDT;
}

Chapter 14 Case Study Follow-Up Exercises


1. //******************************************************************
// SPECIFICATION FILE (AptTime.h)
// This file gives the specification of a Time ADT with
// action responsibilities and knowledge reponsibilities
//******************************************************************

class AptTime
{
public:
void Set( /* in */ int hours,
/* in */ int minutes );
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes
DalePhatANS_complete 8/18/04 10:31 AM Page 1155

Answers to Selected Exercises | 1155

void Write() const;


// Postcondition:
// Time has been output in the form HH:MM
int Hours() const;
// Postcondition:
// Return value is time

int Minutes() const;


// Postcondition:
// Return value is minutes

bool Equal( /* in */ AptTime otherTime ) const;

bool LessThan( /* in */ AptTime otherTime ) const;

AptTime( /* in */ int initHrs,


/* in */ int initMins);
// Precondition:
// 0 <= initHrs <= 23 AND 0 <= initMins <= 59
// Postcondition:
// Class object is constructed
// AND Time is set according to the incoming parameters

AptTime();
// Postcondition:
// hours and minutes have been set to 0

void ReadTime();
// Postcondition:
// hours and minutes have been prompted for, read,
// and set

private:
int hrs;
int mins;
};

//******************************************************************
// IMPLEMENTATION FILE (AptTime.cpp)
// This file implements the AptTime member functions
//******************************************************************
#include "aptTime.h"
#include <iostream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1156

1156 | Answers to Selected Exercises

using namespace std;


// Private members of class:
// int hrs;
// int mins;

//******************************************************************

void AptTime::Set( /* in */ int hours,


/* in */ int minutes )

// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}

//******************************************************************

void AptTime::Write() const

// Precondition:
// The Set function has been invoked at least once
// Postcondition:
// AptTime has been output in the form HH:MM
{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
}

//******************************************************************

bool AptTime::Equal( /* in */ AptTime otherAptTime ) const

// Precondition:
// The Set function has been invoked at least once
// for both this AptTime and otherAptTime
DalePhatANS_complete 8/18/04 10:31 AM Page 1157

Answers to Selected Exercises | 1157

// Postcondition:
// Function value == true, if this AptTime equals otherAptTime
// == false, otherwise

{
return (hrs == otherAptTime.hrs && mins == otherAptTime.mins);
}

//******************************************************************

bool AptTime::LessThan( /* in */ AptTime otherAptTime ) const


// Precondition:
// The Set function has been invoked at least once
// for both this AptTime and otherAptTime
// && This AptTime and otherAptTime represent AptTimes in the
// same day
// Postcondition:
// Function value == true, if this AptTime is earlier
// in the day than otherAptTime
// == false, otherwise
{
return (hrs < otherAptTime.hrs ||
hrs == otherAptTime.hrs && mins < otherAptTime.mins);
}

//******************************************************************
int AptTime::Hours() const
// Postcondition:
// Return value is hrs
{
return hrs;
}

//******************************************************************

int AptTime::Minutes() const


// Postcondition:
// Return value is mins
{
return mins;
}

//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1158

1158 | Answers to Selected Exercises

void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
}

//******************************************************************

AptTime::AptTime()
// Default constructor
// Postcondition
// hrs and mins have been set to 0
{
hrs = 0;
mins = 0;
}

//******************************************************************

AptTime::AptTime( /* in */ int hours,


/* in */ int minutes )
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}

2. Yes, it would be appropriate for active time to inherit from static time, because active
time is static time and more.
3. Here are the necessary changes.
• An enumerated type consisting of AM and PM would have to be defined.
• The constructors and the Set operation would have to include the AM/PM field.
• The Equal and LessThan operations would have to include AM/PM in the tests.
DalePhatANS_complete 8/18/04 10:31 AM Page 1159

Answers to Selected Exercises | 1159

4. //******************************************************************
// SPECIFICATION FILE (AptTime.h)
// This file gives the specification of an AptTime ADT with
// action responsibilities and knowledge responsibilities.
// A field for AM/PM is included.
//******************************************************************

enum AmPm {AM, PM};

class AptTimeEx
{
public:
void Set( /* in */ int hours,
/* in */ int minutes,
/* in */ AmPm amOrPm );
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes
// && timeOfDay == amOrPm

void Write() const;


// Postcondition:
// Time has been output in the form HH:MM

int Hours() const;


// Postcondition:
// Return value is time

int Minutes() const;


// Postcondition:
// Return value is minutes

AmPm MorningAfternoon() const;


// Postcondition:
// Return value is AM or PM

bool Equal( /* in */ AptTimeEx otherTime ) const;

bool LessThan( /* in */ AptTimeEx otherTime ) const;

AptTimeEx( /* in */ int initHrs,


/* in */ int initMins,
/* in */ AmPm amOrPm );
DalePhatANS_complete 8/18/04 10:31 AM Page 1160

1160 | Answers to Selected Exercises

// Precondition:
// 0 <= initHrs <= 23 AND 0 <= initMins <= 59
// Postcondition:
// Class object is constructed
// AND Time is set according to the incoming parameters

AptTimeEx();
// Postcondition:
// hours and minutes have been set to 0 AM

void ReadTime();
// Postcondition:
// hours, minutes, and AM or PM have been prompted
// for, read, and set

private:
int hrs;
int mins;
AmPm timeOfDay;
};

//******************************************************************
// IMPLEMENTATION FILE (AptTimeEx.cpp)
// This file implements the AptTimeEx member functions
//******************************************************************
#include "aptTimeEx.h"
#include <iostream>

using namespace std;


// Private members of class:
// int hrs;
// int mins;

//******************************************************************

void AptTimeEx::Set( /* in */ int hours,


/* in */ int minutes,
/* in */ AmPm amOrPm )

// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
DalePhatANS_complete 8/18/04 10:31 AM Page 1161

Answers to Selected Exercises | 1161

{
hrs = hours;
mins = minutes;
timeOfDay = amOrPm;
}

//******************************************************************

void AptTimeEx::Write() const

// Precondition:
// The Set function has been invoked at least once
// Postcondition:
// AptTimeEx has been output in the form HH:MM:SS

{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
if (timeOfDay == AM)
cout << " AM";
else
cout << " PM";
}

//******************************************************************

bool AptTimeEx::Equal( /* in */ AptTimeEx otherAptTimeEx ) const

// Precondition:
// The Set function has been invoked at least once
// for both this AptTimeEx and otherAptTimeEx
// Postcondition:
// Function value == true, if AptTimeEx equalsotherAptTimeEx
// == false, otherwise

{
return (hrs == otherAptTimeEx.hrs && mins == otherAptTimeEx.mins
&& otherAptTimeEx.timeOfDay == timeOfDay);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1162

1162 | Answers to Selected Exercises

//******************************************************************

bool AptTimeEx::LessThan( /* in */ AptTimeEx otherAptTimeEx ) const


// Precondition:
// The Set function has been invoked at least once
// for both this AptTimeEx and otherAptTimeEx
// && This AptTimeEx and otherAptTimeEx represent AptTimeExs in the
// same day
// Postcondition:
// Function value == true, if this AptTimeEx is earlier
// in the day than otherAptTimeEx
// == false, otherwise
{
if (timeOfDay == AM && otherAptTimeEx.timeOfDay == PM)
return true;
if (timeOfDay == PM && otherAptTimeEx.timeOfDay == AM)
return false;
return (hrs < otherAptTimeEx.hrs ||
hrs == otherAptTimeEx.hrs && mins < otherAptTimeEx.mins);
}

//******************************************************************

int AptTimeEx::Hours() const


// Postcondition:
// Return value is hrs
{
return hrs;
}

//******************************************************************

int AptTimeEx::Minutes() const


// Postcondition:
// Return value is mins
{
return mins;
}
//******************************************************************

AmPm AptTimeEx::MorningAfternoon() const


// Postcondition:
// Return value is AM or PM
DalePhatANS_complete 8/18/04 10:31 AM Page 1163

Answers to Selected Exercises | 1163

{
return timeOfDay;
}

//******************************************************************

void AptTimeEx::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
string dayNight;
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
cout << "Enter AM or PM" << endl;
cin >> dayNight;
if (toupper(dayNight[0]) == 'A')
timeOfDay = AM;
else
timeOfDay = PM;
}

//******************************************************************

AptTimeEx::AptTimeEx()
// Default constructor
// Postcondition
// hrs and mins have been set to 0 and timeOfDay to AM
{
hrs = 0;
mins = 0;
timeOfDay = AM;
}

//******************************************************************

AptTimeEx::AptTimeEx( /* in */ int hours,


/* in */ int minutes,
/* in */ AmPm amOrPm )
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes && timeOfDay == amOrPm
DalePhatANS_complete 8/18/04 10:31 AM Page 1164

1164 | Answers to Selected Exercises

{
hrs = hours;
mins = minutes;
timeOfDay = amOrPm;
}

5. #include <iostream>
#include "AptTimeEx.h"

using namespace std;

int main()
{
AptTimeEx time1(8, 30, AM);
AptTimeEx time2;
time1.Write();
cout << endl;
time2.Write();
cout << endl;
for (int count = 1; count < 4; count++)
{
time2.ReadTime();

if (time1.LessThan(time2))
{
time1.Write();
cout << " is less than ";
time2.Write();
cout << endl;
}
else
{
time1.Write();
cout << " is not less than ";
time2.Write();
cout << endl;
}

if (time1.Equal(time2))
{
time1.Write();
cout << " is equal to ";
time2.Write();
cout << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1165

Answers to Selected Exercises | 1165

else
{
time1.Write();
cout << " is not equal to ";
time2.Write();
cout << endl;
}
}
return 0;
}

6. This is an activity. No answer is expected.

Chapter 15 Exam Preparation Exercises


1. a. v, b. iii, c. i, d. iv, e. vi, f. ii.
2. a. ii, b. i, c. iii, d. v, e. vi, f. iv.
3. True.
4. True.
5. False.
6. True.
7. The pointed-to data is returned to the heap.
8. The pointer(s) are deleted but the pointed-to data is not. It thus becomes inaccessible, and
contributes to memory leakage.
9. It produces an inaccessible int because the int allocated with the first new operation is
not deleted.
10. It creates and references a dangling pointer in germanShortHair.
11. b.
12. b.
13. e (the ++ takes precedence over the *, so the address in finger is incremented).
14. faxLog
15. The shallow copy creates pointers from the new object to the original object’s pointed-to
data. When that data is deleted, the new object then has one or more dangling pointers.
16. A destructor.
17. False.
18. *libraryRecord

Chapter 15 Programming Warm-Up Exercises


1. int* intPointer;
int someInt;
intPointer = &someInt;
someInt = 451;
*intPointer = 451;
DalePhatANS_complete 8/18/04 10:31 AM Page 1166

1166 | Answers to Selected Exercises

2. char* charArrPointer;
char[4] initials;
charArrPointer = initials;
charArrPointer[1] = 'A';
charArrPointer[2] = 'E';
charArrPointer[3] = 'W';

3. struct Phone
{
int country;
int area;
int number;
}
Phone newPhone;
Phone* structPointer;
structPointer = &newPhone;
structPointer->country = 1;
structPointer->area = 888;
structPointer->number = 5551212;

4. struct Phone
{
int country;
int area;
int number;
}
Phone newPhone;
Phone& structReference = newPhone;
structReference.country = 1;
structReference.area = 888;
structReference.number = 5551212;

5. bool ShallowCompare
( /* in */ structPointer first,
/* in */ structPointer second )
{
return (first == second);
}

6. bool DeepCompare
( /* in */ structPointer first,
/* in */ structPointer second )
{
return (first->country == second->country &&
first->area == second->area &&
first->number == second->number);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1167

Answers to Selected Exercises | 1167

7. static max = data[0];


for(int index = 1; index < 100; index++)
if (data[index] > max)
max = data[index];
delete [] data;

8. int Greatest(
( /* inout */ int data[],
/* in */ int size )
{
static max = data[0];
for(int index = 1; index < size; index++)
if (data[index] > max)
max = data[index];
delete [] data;
return max;
}

9. int GetGreatestInput()
{
int size;
int* values;
cout << "Enter number of data values: ";
cin >> size;
values = new int[size];
for(int index = 0; index < size; index++)
{
cout << "Enter integer value: ";
cin >> values[index];
}
return Greatest(values, size);
}

10. ~Circuit()
{
delete [] source;
delete [] sink;
}

11. if (oldValue == NULL)


newValue = new int;
else
newValue = oldValue;

12. if (oldValue != newValue)


delete oldValue;
DalePhatANS_complete 8/18/04 10:31 AM Page 1168

1168 | Answers to Selected Exercises

Chapter 15 Case Study Follow-Up Exercises


1. The other functions can be tested within the context of testing the ComparedTo function.
Here are the cases that must be addressed.
a. The year is less than the second year.
b. The year is greater than the second year.
c. The years are equal, and the first month is less than the second month.
d. The years are equal, and the first month is greater than the second month.
e. The years and months are equal, and the first day is less than the second day.
f. The years and months are equal, and the first day is greater than the second day.
g. The years, months, and days are the same.
It is easier to choose one date and then vary the one to which it is compared. The letter in
the Reason for Test Case column refers back to the letters above. The date 10/30/2000 is
compared to the input, which is the second date. This is not repeated in the table. The
output column does not show the completely documented output, just the path.

Reason for Input Expected Output Observed


Test Case Output
a. 9/12/2001 2000 comes before 2001
b. 10/30/1956 2000 comes after 1956
c. 11/9/2000 10/2000 comes before 11/2000
d. 9/5/2000 10/2000 comes after 9/2000
e. 10/31/2000 10/30/2000 comes before 10/31/2000
f. 10/4/2000 10/30/2000 comes after 10/4/2000
g. 10/30/2000 They are the same
If the test plan seems familiar, look at the solution to Case Study Follow-Up Exercise
11.2.
#include <iostream>
#include "Date.h"

using namespace std;

int main()
{
int month;
int day;
int year;

Date date1;
date1.Set(10, 30, 2000);
cout << "date1 is " << date1.Month() << "/" << date1.Day()
<< "/" << date1.Year() << endl;
Date date2;
for (int count = 1; count <= 7; count++)
DalePhatANS_complete 8/18/04 10:31 AM Page 1169

Answers to Selected Exercises | 1169

{
cout << "Enter month" << endl;
cin >> month;
cout << "Enter day" << endl;
cin >> day;
cout << "Enter year" << endl;
cin >> year;
date2.Set(month, day, year);

switch (date1.ComparedTo(date2))
{
case BEFORE : cout << "date1 comes before date2" << endl;
break;
case SAME : cout << "date1 is the same as date2"
<< endl;
break;
case AFTER : cout << "date1 comes after date2" << endl;
}
}
return 0;
}

2. Copy constructors are needed when initializing a variable in a declaration, when passing
a variable as a value parameter, and when returning the variable as the value of a func-
tion. None of these cases occurs in the problem for which the SortedList class was
implemented; thus, no copy constructor was needed. A destructor is implicitly invoked
when the class object is destroyed. In the problem for which we used the SortedList
class, the objects were declared in the main function; thus, a destructor would not have
been called, and was thus unnecessary.
However, it would be safer and better style to include these functions because you
can never tell how a user might use objects of this class in their programs.
3. Recall that a top-down design produces a hierarchy of tasks, and an object-oriented
design produces a hierarchy of objects. Clearly the process used to build the appointment
calendar demonstrated object-oriented design.
4. The next step is to put all the pieces together to form a collection of days ordered by
date. The Case Studies in Chapters 12 and 13 demonstrated two different ways to imple-
ment a collection: using the data itself as an index and keeping a list of the data. Thus,
the collection of days can be implemented as follows:
• A list of days
• A one-dimensional array in which the month is used as an index into a list of days for
the month
• A two-dimensional array in which the month is one index and the day is the other
index and each cell contains the appointments for one day
DalePhatANS_complete 8/18/04 10:31 AM Page 1170

1170 | Answers to Selected Exercises

Chapter 16 Exam Preparation Exercises


1. a. An individual element of a linked list.
b. The members of a node that contain the data stored at that location in the list.
c. The member of a node that contains the address of the next node in the list.
d. The pointer that keeps track of where processing is taking place in the list.
2. False.
3. True.
4. a. The address of the next node in the list.
b. The data in the current node.
c. The data in the next node in the list.
d. The address of the node after the next node.
e. The data in the node after the next node.
f. The data in the fourth node in the list.
5. a. It stores the index. b. It stores the address.
6. a. An empty list. b. That processing has reached the end of the list.
7. Search the list to find the node whose successor is greater than the new node. Set the link
field of the new node to equal the link field of the currPtr node. Set the link field of the
currPtr node equal to the address of the new node.
8. Set a temporary pointer equal to the link field of the current node, set the current node
link field equal to the link field of its successor, and delete the data pointed- to by the
temporary pointer.
9. a. Linked, b. Array, c. Array, d. Array.
10. A direct array representation keeps the elements physically adjacent in the array. A
linked list implemented with an array allows elements to be in any physical order in the
array, and connects them logically using a link field in each element.
11. The typedef refers to NodeType before it has been declared. We need to add a forward
declaration of NodeType before the typedef that uses it.
12. a. An array—the list is small and bounded, and searches are done frequently.
b. A linked list—the list varies unpredictably in size, and does not require frequent
searching.
c. A linked list—the list is unbounded, and deletion is at the head.

Chapter 16 Programming Warm-Up Exercises


1. a. node[head].component
b. currPtr = node[currPtr].link
c. node[node[currPtr].link].component
d. node[node[node[currPtr].link].link].component
2. a. head->component
b. currPtr = currPtr->link
c. (currPtr->link)->link
d. ((currPtr->link)->link)->link
DalePhatANS_complete 8/18/04 10:31 AM Page 1171

Answers to Selected Exercises | 1171

3. head = new NodeType;


head->component = 100;
currPtr = head;

4. newNodePtr = new NodeType;


newNodePtr->component = 212;
currPtr->link = newNodePtr;
currPtr = newNodePtr;

5. newNodePtr = new NodeType;


newNodePtr->component = 32;
currPtr->link->link = newNodePtr;
currPtr = newNodePtr;

6. NodePtr savePtr;
savePtr = head;
head = currPtr->link;
head->link = savePtr;
currPtr->link = currPtr->link->link;

7. auxPtr = currPtr;
while (auxPtr->link != NULL)
auxPtr= currPtr->link;
auxPtr->NULL;

8. auxPtr = currPtr;
if (auxPtr != NULL)
if (auxPtr->link == NULL)
auxPtr = NULL;
else
{
while (auxPtr->link != NULL)
auxPtr= currPtr->link;
auxPtr->NULL;
}

9. void Sort(NodePtr& head, NodePtr& currPtr)


{
NodePtr; // head of sorted list
NodePtr lastPtr; // pointer to end of new list
NodePtr tailPtr = NULL; // trailing pointer when searching
NodePtr tempPtr; // used for traversal
NodePtr smallPtr; // pointer to smallest
NodePtr smallTrailing; // pointer to one before smallest
while (head != NULL)
{
tempPtr = head;
DalePhatANS_complete 8/18/04 10:31 AM Page 1172

1172 | Answers to Selected Exercises

smallPtr = head;
tailPtr = NULL;
smallTrailing = NULL;
while (tempPtr != NULL) // find smallest
{
if (smallPtr->component > tempPtr->component)
{
smallPtr = tempPtr;
smallTrailing = tailPtr;
}
tailPtr = tempPtr;
tempPtr = tempPtr->link;
}

// remove node
if (smallTrailing == NULL) // only one node left
head = smallPtr -> link; // set end of loop
else
smallTrailing->link = smallPtr->link; // remove node

// insert into new list


if (headS == NULL) // first node
{
headS = smallPtr;
headS->link = NULL;
lastPtr = headS;
}
else // other nodes
{
lastPtr->link = smallPtr;
lastPtr = smallPtr;
lastPtr->link = NULL;
}

}
head = headS;
currPtr = headS;
}

10. CopyReverse(NodeType* head, NodeType*& headR)


{
headR = NULL; // head of new list

NodePtr newNode;
NodePtr tempPtr = head; // used for traversal
DalePhatANS_complete 8/18/04 10:31 AM Page 1173

Answers to Selected Exercises | 1173

while (tempPtr != NULL)


{
newNode = new NodeType;
newNode->component = tempPtr->component;

newNode->link = headR;
headR = newNode;
tempPtr = tempPtr->link
}
}

Chapter 16 Case Study Follow-Up Exercises


1. No, we could not. The items in the lists implemented thus far are encapsulated; the items
cannot be changed. One of the operations required for the list of days is inserting an
entry into the appropriate day, thus changing the contents of the day object.
2. void Day::InsertEntry( /* in */ Entry newEntry )

// Postcondition:
// If list is full, EntryListIsfull exception is thrown; if
// time is already filled, DuplicateTime exception is thrown;
// else newEntry is inserted in list

{
if (list.IsFull())
throw EntryListIsFull();
else
if (list.IsPresent(newEntry))
throw DuplicateTime();
else
list.Insert(newEntry);
}

3. #include "Name.h"
// ShortName specification
class ShortName : public Name
{
public:
void ReadName();
ShortName(/* in */ string firstName,
/* in */ string middleName,
/* in */ string lastName);
ShortName();
string FirstName() const;
// Postcondition:
// Return value is this person's first name
DalePhatANS_complete 8/18/04 10:31 AM Page 1174

1174 | Answers to Selected Exercises

string LastName() const;


// Postcondition:
// Return value is this person's last name

private:
string first;
string last;
};

#include "ShortName.h"
// ShortName implementation
void ShortName::ReadName()
// Postcondition:
// Name prompted for and read from the standard
// input device
{
cout << "Enter first and last names "
<< "separated by a blank." << endl;
cin >> first >> last;
Name:SetName(first, " ", last);
}

ShortName::ShortName(/* in */ string firstName,


/* in */ string middleName,
/* in */ string lastName)
: Name(firstName, middleName, lastName)
{

ShortName::ShortName()
{

string ShortName::FirstName() const


// Postcondition:
// Return value is this person's first name
{
return Name::FirstName();
}

string ShortName::LastName() const


DalePhatANS_complete 8/18/04 10:31 AM Page 1175

Answers to Selected Exercises | 1175

// Postcondition:
// Return value is this person's last name
{
return Name::LastName();
}
4. void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23)and minutes (<=59) "
<< "separated by a blank" << endl;
cin >> hrs >> mins;
}

5. This is a matter of taste, but most of you will prefer the shorter entry.
6. There are several ways to look at this question. If we knew for sure that the calendar only
contained appointments for one year, then it probably would be more efficient to just
check the day; however, there is nothing in the program that assumes that only one year
is represented. As it stands now, the calendar can represent any number of years. Thus,
using the date comparison takes care of both situations.

Chapter 17 Exam Preparation Exercises


1. True.
2. False.
3. Function template.
4. a. Template class, b. Neither (it’s a class object)
5. Instantiate—To generate a new function (from a function template) or a new class type
(from a class template)
• Template parameter—The parameter specified in a function template or class template.
• Template argument—The argument—usually a type name—that is substituted for a tem-
plate parameter when a template is instantiated.
• Specialization—A version of a template for a particular template argument.
• User-defined specialization—A template without a template parameter that is an alter-
native version of an existing template.
6. a. float, b. 3.85, c. Yes.
7. The Try-catch statement.
8. The Throw statement.
9. Each Catch clause must have a formal parameter.
10. a. False. There can be many Catch clauses, as long as their parameters are different.
b. True.
c. False. A throw statement can appear anywhere. A Throw statement often is located in
a function that is called from a Try clause.
DalePhatANS_complete 8/18/04 10:31 AM Page 1176

1176 | Answers to Selected Exercises

11. a. Control would continue with the statements following the entire Try-catch statement.
Almost certainly, this would be wrong. For example, the final comments indicate
“close the output file,” but the output file has already been closed in the Catch clause.
b. If we change throw to return, the calling code won’t have any idea that a BadData
exception occurred. This may or may not be wrong, depending on the design of the
program.
12. In the Catch clause, insert return 1; after the output statement.
13. The exception passes to the function that called the function containing the call. If that
one also doesn’t have a handler for the exception, the process repeats with the next
higher caller. If the exception reaches main without finding a handler, it is uncaught; an
error message is then output, and the program terminates abnormally.
14. It rethrows the exception.
15. bad_alloc

Chapter 17 Programming Warm-Up Exercises


1. template<class SomeType>
void PrintSquare(SomeType number)
{
cout << number * number;
}

2. PrintSquare<int>(10);
PrintSquare<long>(10L);
PrintSquare<float>(10.0);

or

PrintSquare(10);
PrintSquare(10L);
PrintSquare(10.0);

3. template<>
void PrintSquare(string value)
{
cout << value << value;
}

4. a. int Twice( int num )


{
return 2*num;
}
float Twice( float num )
{
return 2.0*num;
}

b. cout << Twice(someInt) << ' ' << Twice(someFloat) << endl;
DalePhatANS_complete 8/18/04 10:31 AM Page 1177

Answers to Selected Exercises | 1177

5. template<class NumType>
NumType Sum( NumType arr[], int size )
{
int i; // Index variable
NumType sum = 0; // Sum of the elements

for (i = 0; i < size; i++)


sum = sum + arr[i];
return sum;
}

6. template<class SomeType>
void GetData( string promptStr, SomeType& data )
{
cout << promptStr << ' ';
cin >> data;
}

7. template<>
void GetData( string promptStr, AutoType& data )
{
char ch; // The input character

cout << promptStr << ' ';


cin >> ch;
if (ch == 's')
data = SEDAN;
else if (ch == 'c')
data = COUPE;
else
data = OTHER;
}

8. a. GList<int> intList;
GList<float> floatList;

b. i = 10;
while (i <= 80 && !intList.IsEmpty())
{
// Below, use "while", not "if", because
// duplicates are allowed in a list
DalePhatANS_complete 8/18/04 10:31 AM Page 1178

1178 | Answers to Selected Exercises

while (intList.IsPresent(i))
{
intList.Delete(i);
floatList.Insert(0.5 * float(i));
}
i++;
}

9. template<class Type1, class Type2>


class MixedPair
{
public:
Type1 First() const;
Type2 Second() const;
void Print() const;
MixedPair( Type1 m, Type2 n );
private:
Type1 first;
Type2 second;
};

10. MixedPair<int, float> pair1(5, 29.48);


MixedPair<string, int> pair2("Book", 36);

11. template<class Type1, class Type2>


MixedPair<Type1, Type2>:: MixedPair( Type1 m, Type2 n )
// Constructor
{
first = m;
second = n;
}

template<class Type1, class Type2>


Type1 MixedPair<Type1, Type2>::First() const
{
return first;
}

template<class Type1, class Type2>


Type2 MixedPair<Type1, Type2>::Second() const
{
return second;
}

template<class Type1, class Type2>


DalePhatANS_complete 8/18/04 10:31 AM Page 1179

Answers to Selected Exercises | 1179

void MixedPair<Type1, Type2>::Print() const


{
cout << '(' << first << ", " << second << ')' << endl;
}

12. a. class MathError


{}; // Don't forget the semicolon

b. throw MathError(); // Don't forget the parentheses


13. try
{
str3 = str1 + str2;
}
catch ( length_error )
{
cout << "*** Error: String too long" << endl;
return 1;
}

14. class SumTooLarge // Exception class


{};

int Sum( int int1, int int2 )


{
if (int1 > INT_MAX - int2)
throw SumTooLarge();
return int1 + int2;
}

15. try
{
cout << Sum(oneInt, anotherInt) << endl;
}
catch ( SumTooLarge )
{
cout << "*** Error: Sum is too large" << endl;
throw;
}

16. a. class OpenFailed // Exception class


{};

void OpenForInput( /* inout */ ifstream& someFile )

// Prompts the user for the name of an input file


// and attempts to open the file
DalePhatANS_complete 8/18/04 10:31 AM Page 1180

1180 | Answers to Selected Exercises

// Postcondition:
// The user has been prompted for a file name
// && IF the file could not be opened
// An error message has been printed
// && An OpenFailed exception has been thrown

{
string fileName; // User-specified file name

cout << "Input file name: ";


cin >> fileName;

someFile.open(fileName.c_str());
if ( !someFile )
{
cout << "** Can't open " << fileName << " **" << endl;
throw OpenFailed();
}
}

b. Note that the calling code below does not print an error message. The error message
has already been printed by OpenForInput, as advertised by its postcondition.
ifstream inFile;

try
{
OpenForInput(inFile);
}
catch ( OpenFailed )
{
return 1;
}
// Success keep executing

Chapter 17 Case Study Follow-Up


1. Duplicate identifiers are not allowed because they are ambiguous.
2. One way to solve the problem would be to put the definition of NodeType in a separate
file and have DayList and SortedList2 include that file. Another solution would be to
put each definition within a namespace.
3. The test plan used in Chapter 16 should be enhanced with cases to test all of the excep-
tions. Each of the exception classes must be thrown from each possible place.
DalePhatANS_complete 8/18/04 10:31 AM Page 1181

Answers to Selected Exercises | 1181

Exceptions Input Values Expected Output Observed


Output

DuplicateTime InsertDay 1 3 2004 2 “Entry with same time is already


InsertApt 1 3 2004 10:30 in the list."
InsertApt 1 3 2004 10:30
DuplicateDay InsertDay 1 3 2004 “Day with same date is already
defined."
EntryListIsFull InsertApt 1 3 2004 9:30 “Entry list is full for this
InsertApt 1 3 2004 date."
UndefinedString Insertpt "Input string was not valid."
"Read menu and try again."
UndefinedDay InsertApt 1 4 2004 "An operation has been defined
DeleteApt 1 4 2004 on an undefined day"
IsFree 1 4 2004
PrintDay 1 4 2004

4. Here are the classes that are changed.


//****************************************************************
// SPECIFICATION FILE (AptTime.h)
// This file gives the specification of an AptTime ADT with
// action responsibilities and knowledge reponsibilities
//****************************************************************
#ifndef APT_TIME
#define APT_TIME
#include "relType.h"
class AptTime
{
public:
void Set( /* in */ int hours,
/* in */ int minutes );
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes

void Write() const;


// Postcondition:
// Time has been output in the form HH:MM

int Hours() const;


// Postcondition:
// Return value is time
DalePhatANS_complete 8/18/04 10:31 AM Page 1182

1182 | Answers to Selected Exercises

int Minutes() const;


// Postcondition:
// Return value is minutes

RelationType ComparedTo( /* in */ AptTime otherTime ) const;

// Precondition:
// This and input parameter contains valid times
// Postcondition:
// Return value is
// BEFORE, if this time comes before otherTime
// SAME, if this time and otherTime are the same
// AFTER, if this time comes after otherTime

AptTime( /* in */ int initHrs,


/* in */ int initMins);
// Precondition:
// 0 <= initHrs <= 23 AND 0 <= initMins <= 59
// Postcondition:
// Class object is constructed
// AND Time is set according to the incoming parameters

AptTime();
// Postcondition:
// hours and minutes have been set to 0

void ReadTime();
// Postcondition:
// hours and minutes have been prompted for, read,
// and set

private:
int hrs;
int mins;
};

#endif

//******************************************************************
// IMPLEMENTATION FILE (AptTime.cpp)
// This file implements the AptTime member functions
//******************************************************************
#include "aptTimeEx.h"
#include <iostream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1183

Answers to Selected Exercises | 1183

using namespace std;


// Private members of class:
// int hrs;
// int mins;

//******************************************************************

void AptTime::Set( /* in */ int hours,


/* in */ int minutes )

// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}

//******************************************************************

void AptTime::Write() const

// Postcondition:
// AptTime has been output in the form HH:MM
{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
}

//******************************************************************

// Precondition:
// This and input parameter contains valid times
// Postcondition:
// Return value is
// BEFORE, if this time comes before otherTime
// SAME, if this time and otherTime are the same
// AFTER, if this time comes after otherTime
DalePhatANS_complete 8/18/04 10:31 AM Page 1184

1184 | Answers to Selected Exercises

{
if (hrs == otherAptTime.hrs && mins == otherAptTime.mins)
return SAME;
else
if (hrs < otherAptTime.hrs ||
hrs == otherAptTime.hrs && mins < otherAptTime.mins)
return BEFORE;
}

//******************************************************************

int AptTime::Hours() const


// Postcondition:
// Return value is hrs
{
return hrs;
}

//******************************************************************

int AptTime::Minutes() const


// Postcondition:
// Return value is mins
{
return mins;
}

//******************************************************************

void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
}

//******************************************************************

AptTime::AptTime()
// Default constructor
// Postcondition
// hrs and mins have been set to 0
DalePhatANS_complete 8/18/04 10:31 AM Page 1185

Answers to Selected Exercises | 1185

{
hrs = 0;
mins = 0;
}

//******************************************************************

AptTime::AptTime( /* in */ int hours,


/* in */ int minutes )
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// && 0 <= seconds <= 59
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}

//*****************************************************************
// SPECIFICATION FILE (Entry.h)
// This file contains the specification of the Entry ADT,
// which has two contained classes, Name and AptTime
//*****************************************************************
#ifndef ENTRY
#define ENTRY
#include "AptTimeEx.h"
#include "Name.h"
#include <string>
#include "relType.h"

using namespace std;

class Entry
{
public:
string NameStr() const;
// Returns a string made up of first name, blank, last name
// Postcondition:
// Return value is first name of Name object, blank, and
// last name of Name object

string TimeStr() const;


// Returns a string made up of hour, colon, minutes
DalePhatANS_complete 8/18/04 10:31 AM Page 1186

1186 | Answers to Selected Exercises

// Postcondition:
// Return value is hours from Time object, colon, and
// minutes of Time object

RelationType ComparedTo(Entry entry) const;


// Compares time with entry.time
// Postcondition:
// BEFORE, if this time comes before entry.time
// SAME, if this time and entry.time are the same
// AFTER, if this time is after entry.time

Entry();
// Default constructor
// Postcondition:
// Entry object has been constructed

Entry( /* in */ string firstName, // First name


/* in */ string middleName, // Middle name
/* in */ string lastName, // Last name
/* in */ int initHours, // Hours
/* in */ int initMinutes ); // Minutes
// Parameterized constructor
// Postcondition:
// Entry object has been constructed with firstName,
// middleName, and lastName as arguments to Name
// parameterized constructor; Time object has
// initHours and initMinutes as arguments
// to Time parameterized constructor

void ReadEntry();
// Postcondition:
// Name and time have been prompted for and read

private:
Name name;
AptTime time;
};
#endif

//*****************************************************************
// IMPLEMENTATION FILE (Entry.cpp)
// This file contains the specification of the Entry ADT,
// which has two contained classes, Name and Time
//*****************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1187

Answers to Selected Exercises | 1187

#include "EntryEx.h"
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

string Entry::NameStr() const

// Returns a string made up of first name, blank, last name


// Postcondition:
// Return value is first name of Name object, blank, and
// last name of Name object

{
return (name.FirstName() + ' ' + name.LastName());
}

string Entry::TimeStr() const

// Returns a string made up of hour, colon, minutes


// Post condition:
// Return value is minutes from Time object, colon, and
// seconds of Time object

{
ifstream tempIn;
ofstream tempOut;
tempOut.open("convert");
tempOut << time.Hours() << ":" << time.Minutes() << endl;
tempOut.close();
tempIn.open("convert");
string temp;
tempIn >> temp;
tempIn.close();
return temp;
}

void Entry::ReadEntry()

// Postcondition:
// Values have been read from the keyboard into name and time.
DalePhatANS_complete 8/18/04 10:31 AM Page 1188

1188 | Answers to Selected Exercises

{
name.ReadName();
time.ReadTime();
}

RelationType Entry::ComparedTo(Entry entry) const


// Compares time with entry.time
// Postcondition:
// BEFORE, if this time comes before entry.time
// SAME, if this time and entry.time are the same
// AFTER, if this time is after entry.time
{
return time.ComparedTo(entry.time);
}

Entry::Entry()

// Default constructor
// Postcondition:
// Entry object has been constructed
{
}

Entry::Entry( /* in */ string firstName,


/* in */ string middleName,
/* in */ string lastName,
/* in */ int initHours,
/* in */ int initMinutes)
// Constructor initializers
: name(firstName, middleName, lastName),
time(initHours, initMinutes)

// Parameterized constructor
// Postcondition:
// Entry object has been constructed with firstName,
// middleName, and lastName as arguments to Name
// parameterized constructor; initHours, initMinutes,
// and initSeconds as arguments to Time parameterized
// constructor

{
}
// SPECIFICATION FILE (SortedList2.h)
// This file gives the specification of a sorted list abstract data
// type. The list items are maintained in ascending order of
// value
//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1189

Answers to Selected Exercises | 1189

template<class ItemType>
// Forward declaration

template<class ItemType>
class SortedList2
{
public:
bool IsEmpty() const;

// Postcondition:
// Return value is true if list is empty;
// false otherwise

bool IsFull() const;

// Postcondition:
// Return value is true if list is full;
// false otherwise

void Insert( /* in */ ItemType item );

// Precondition:
// item is assigned
// Postcondition:
// item is in list
// && List components are in ascending order

void Delete( /* in */ ItemType item );

// Precondition:
// item is somewhere in list
// Postcondition:
// First occurrence of item is no longer in list
// && List components are in ascending order

void Reset();

// Postcondition:
// Iteration is initialized

ItemType GetNextItem();

// Precondition:
// No transformers have been invoked since last call
DalePhatANS_complete 8/18/04 10:31 AM Page 1190

1190 | Answers to Selected Exercises

// Postcondition:
// Returns component at the current position
// in the SortedList

int Length();

// Postcondition:
// Return value is length of list

SortedList2();

// Constructor
// Postcondition:
// Empty list is created

SortedList2(int maxLength);

// Constructor
// Postcondition:
// Empty list is created

SortedList2( const SortedList2& otherList );

// Copy-constructor
// Postcondition:
// List is created as a duplicate of otherList

~SortedList2();

// Destructor
// Postcondition:
// List is destroyed

bool IsPresent(ItemType item);

// Searches the list for item, reporting whether it was found


// Postcondition:
// Return value is true, if item is the list;
// false, otherwise

private:
NodeType<ItemType>* head;
NodeType<ItemType>* currentPos;
int length;
int maxSize;
};
DalePhatANS_complete 8/18/04 10:31 AM Page 1191

Answers to Selected Exercises | 1191

#include "SortedList2.cpp"

//******************************************************************
// IMPLEMENTATION FILE (SortedList.cpp)
// This file implements the SortedList2 class member functions
// List representation: a linked list of dynamic nodes
//******************************************************************
#include <iostream>
#include <cstddef> // For NULL
#include "relType.h"
using namespace std;

template<class ItemType>
struct NodeType
{
ItemType item;
NodeType<ItemType>* link;
};

// Private members of class:


// NodeType* head; External pointer to linked list

//******************************************************************

template<class ItemType>
SortedList2<ItemType>::SortedList2()

// Constructor

// Postcondition:
// head == NULL AND maxSize set to 1000

{
head = NULL;
length = 0;
maxSize = 1000;
}

//******************************************************************
template<class ItemType>
SortedList2<ItemType>::SortedList2(int maxLength)
DalePhatANS_complete 8/18/04 10:31 AM Page 1192

1192 | Answers to Selected Exercises

// Constructor

// Postcondition:
// head == NULL

{
head = NULL;
length = 0;
maxSize = maxLength;
}

//******************************************************************

template<class ItemType>
SortedList2<ItemType>::SortedList2( const SortedList2<ItemType>&
otherList )

// Copy-constructor

// Postcondition:
// IF otherList.head == NULL (i.e., the other list is empty)
// head == NULL
// ELSE
// head points to a new linked list that is a copy of
// the linked list pointed to by otherList.head

{
TNodeType<ItemType>* fromPtr; // Pointer into list being copied
TNodeType<ItemType>* toPtr; // Pointer into list being built

if (otherList.head == NULL)
{
head = NULL;
return;
}

// Copy first node

fromPtr = otherList.head;
head = new TNodeType<ItemType>;
head->item = fromPtr->item;

// Copy remaining nodes

toPtr = head;
fromPtr = fromPtr->link;
DalePhatANS_complete 8/18/04 10:31 AM Page 1193

Answers to Selected Exercises | 1193

while (fromPtr != NULL)


{
toPtr->link = new TNodeType<TNodeType>;
toPtr = toPtr->link;
toPtr->item = fromPtr->item;
fromPtr = fromPtr->link;
}
toPtr->link = NULL;
length = otherList.length;
currentPos = otherList.currentPos;
}

//******************************************************************

template<class ItemType>
SortedList2<ItemType>::~SortedList2()

// Destructor

// Postcondition:
// All linked list nodes have been deallocated from free store

{
TNodeType<ItemType>* temp; // Temporary variable

while ( !IsEmpty() )
{
temp = head;
head = head->link;
delete temp;
}
}
//******************************************************************

template<class ItemType>
bool SortedList2<ItemType>::IsEmpty() const

// Postcondition:
// Return value is true if head == NULL; false otherwise

{
return (head == NULL);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1194

1194 | Answers to Selected Exercises

//****************************************************************

template<class ItemType>
bool SortedList2<ItemType>::IsFull() const

// Postcondition:
// Return value is false

{
return length == maxSize;
}

//****************************************************************

template<class ItemType>
void SortedList2<ItemType>::Insert( /* in */ ItemType item )

// Precondition:
// item members of list nodes are in ascending order
// && item is assigned
// Postcondition:
// New node containing item is in its proper place
// in linked list
// && item members of list nodes are in ascending order

{
TNodeType<ItemType>* currentPtr; // Moving pointer
TNodeType<ItemType>* prevPtr; // Trailing pointer
TNodeType<ItemType>* newNodePtr; // Pointer to new node

// Set up node to be inserted

newNodePtr = new TNodeType<ItemType>;


newNodePtr->item = item;

// Find previous insertion point


prevPtr = NULL;
currentPtr = head;
while (currentPtr != NULL &&
currentPtr->item.ComparedTo(item) == BEFORE)
{
prevPtr = currentPtr;
currentPtr = currentPtr->link;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1195

Answers to Selected Exercises | 1195

// Insert new node

newNodePtr->link = currentPtr;
if (prevPtr == NULL)
head = newNodePtr;
else
prevPtr->link = newNodePtr;
length++;
}

//******************************************************************

template<class ItemType>
void SortedList2<ItemType>::Delete( /* in */ ItemType item )

// Precondition:
// item members of list nodes are in ascending order
// Postcondition:
// Node containing first occurrence of item is no longer in
// linked list
// && item members of list nodes are in ascending order

{
TNodeType<ItemType>* currentPtr;
TNodeType<ItemType>* prevPtr;

currentPtr = head;
prevPtr = NULL;

while (currentPtr != NULL


&& !(currentPtr->item.ComparedTo(item) == SAME))
{
prevPtr = currentPtr;
currentPtr = currentPtr->link;
}

if (currentPtr != NULL)
{
prevPtr->link = currentPtr->link;
length--;
}

}
DalePhatANS_complete 8/18/04 10:31 AM Page 1196

1196 | Answers to Selected Exercises

template<class ItemType>
void SortedList2<ItemType>::Reset()

// Postcondition:
// Iteration is initialized

{
currentPos = NULL;
}

template<class ItemType>
ItemType SortedList2<ItemType>::GetNextItem()

// Precondition:
// No transformers have been invoked since last call
// Postcondition:
// Returns item at the current position in the SortedList and
// resets current to next position or first position if
// last item is returned

{
ItemType item;
if (currentPos == NULL)
currentPos = head;
item = currentPos->item;
currentPos = currentPos->link;
return item;
}

template<class ItemType>
int SortedList2<ItemType>::Length()

// Postcondition:
// Return value is length

{
return length;
}

template<class ItemType>
bool SortedList2<ItemType>::IsPresent(ItemType item)

// Searches the list for item, reporting whether it was found


// Postcondition:
// Return value is true if item is the list;
// false otherwise
DalePhatANS_complete 8/18/04 10:31 AM Page 1197

Answers to Selected Exercises | 1197

{
TNodeType<ItemType>* currentPtr; // Moving pointer

// Search for item

currentPtr = head;
while (currentPtr != NULL
&& currentPtr->item.ComparedTo(item) != SAME)
currentPtr = currentPtr->link;

return !(currentPtr == NULL);


}
5. The output should be the same as the output in the text.

Chapter 18 Exam Preparation Exercises


1. b. looping.
2. True.
3. True.
4. False. Tail recursion occurs when nothing is done after the return from the recursive call.
5. F(4) = 0 and F(6) = 0. F(5) is undefined.
6. F(3) = 8, F(4) = 16, F(5) = 32.
7. Infinite recursion.
8. It will run out of space on the run time stack.
9. True.
10. c. The value in the variable.
11. c. The distance to the end of the structure
12. 30
20
10

13. 10
20
30
30
20
10

14. abcc
d
e

15. abcd
e
f
DalePhatANS_complete 8/18/04 10:31 AM Page 1198

1198 | Answers to Selected Exercises

Chapter 18 Programming Warm-Up Exercises


1. int DigitSum(int number)
{
if (number > 0)
return number%10 + DigitSum(number/10);
else
return 0;
}

2. int OneDigit (int number)


{
if (number <= 9)
return number;
else
return OneDigit(DigitSum(number));
}

3. int Search(const int[] data, value, max, min)


{
int mid;
if (max = min)
if (data[max] = value)
return max;
else
return -1;
else
{
mid = (max + min) / 2;
if (data[mid] > value)
return Search(data, value, mid-1, min);
else if (data[mid] < value)
return Search(data, value, max, mid+1);
else
return mid
}
}

4. void Ex4()
{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;
DalePhatANS_complete 8/18/04 10:31 AM Page 1199

Answers to Selected Exercises | 1199

if (number != 0)
{
cout << number << endl;
Ex4();
cout << number << endl;
}
}

5. void Ex5(int sum)


{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;

if (number != 0)
{
cout << "Total: " << sum + number <<endl;
Ex5(sum + number);
cout << number << endl;
}
}

6. void Ex6(int sum, int& revSum)


{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;

if (number != 0)
{
cout << "Total: " << sum + number <<endl;
Ex6(sum + number, revSum);
revSum = revSum + number;
cout << number << " Total: " << revSum << endl;
}
}

7. void Ex7(int& greatest)


{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;

if (number > greatest)


greatest = number;
if (number != 0)
DalePhatANS_complete 8/18/04 10:31 AM Page 1200

1200 | Answers to Selected Exercises

{
Ex7(greatest);
cout << number << endl;
}

}
The greatest must be written immediately following the call.

8. void Ex8(int& greatest)


{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;

if (number > greatest)


greatest = number;

if (number != 0)
{
cout << "Greatest: " << greatest << endl;
Ex8(greatest);
cout << number << endl;
}

}
The greatest must be written immediately following the call.

9. #include <iostream>

using namespace std;

void Ex9(int&);
int main()
{
int sum = 0;
int revSum = 0;
Ex9(revSum);
cout << "The greatest is " << revSum;
return 0;
}

//*******************

void Ex9(int& greatest)


DalePhatANS_complete 8/18/04 10:31 AM Page 1201

Answers to Selected Exercises | 1201

{
int number;
int greatestSoFar = 0;
cout << "Enter a positive number, 0 to end: ";
cin >> number;
if (number > 0)
{
Ex9(greatestSoFar);
if (number > greatestSoFar)
greatest = number;
else
greatest = greatestSoFar;
cout << number << " Greatest: " << greatest
<< endl;
}
}

10. void CopyReverse(PtrType head1, PtrType& head2)


// Assumption: head2 is originally NULL
{
PtrType tempPtr;
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
CopyReverse(head1->link, head2);

}
}

11. void Copy(PtrType head1, PtrType& head2)


// Assumption: head2 is originally NULL
{
PtrType tempPtr;
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
Copy(head1->link, head2->link);

}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1202

1202 | Answers to Selected Exercises

12. void CopyDouble(PtrType head1, PtrType& head2)


// Assumption: head2 is originally NULL
{

PtrType tempPtr;
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
CopyReverse(head1->link, head2);
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
Copy(head1->link, head2->link);
}
}
}

or

void CopyDouble(PtrType head1, PtrType& head2)


{
CopyReverse(head1, head2);
Copy(head1, head2);
}

Chapter 18 Case Study Follow-Up Exercises


1. The algorithm still works correctly, but because of the lopsided splits it is not so quick. Is
this situation likely to occur? That depends on how we choose our splitting value and on
the original order of the data in the array. If we use data[first] as the splitting value
and the array is already sorted, then every split is lopsided. One side contains one ele-
ment, while the other side contains all but one of the elements. Thus, our QuickSort is
not a quick sort. This splitting algorithm favors an array in random order.
2. The middle value might be a good splitting value: data[(first + last)/2].
3. Exchange the values data[0] and data[(first + last)/2] at the beginning of each call. Then
the same algorithm can be used.

You might also like