182
1125 Appendix C Introduction to Flowcharting This appendix provides a brief introduction to flowcharting. It includes example flowcharts for programs that appear in Chapters 1–6. A flowchart is a diagram that depicts the “flow” of a program. It contains symbols that rep- resent each step in the program. The figure shown here is a flowchart for Program 1-1, the pay- calculating program in Chapter 1. Flowchart for Program 1-1 START END Display message ”How many hours did you work?” Display message ”How much do you get paid per hour?” Multiply hours by rate and store result in pay Read hours Read rate Display pay

Appendix C Introduction to Flowcharting - CiteSeerX

Embed Size (px)

Citation preview

1125

Appendix CIntroduction to Flowcharting

This appendix provides a brief introduction to flowcharting. It includes example flowcharts forprograms that appear in Chapters 1–6.

A flowchart is a diagram that depicts the “flow” of a program. It contains symbols that rep-resent each step in the program. The figure shown here is a flowchart for Program 1-1, the pay-calculating program in Chapter 1.

Flowchart for Program 1-1

START

END

Display message”How many hours did

you work?”

Display message”How much

do you get paid per hour?”

Multiply hoursby rate and store result

in pay

Read hours

Read rate

Display pay

GaddA4.book Page 1125 Monday, July 21, 2003 11:53 AM

1126 Appendix C: Introduction to Flowcharting

Notice there are three types of symbols in this flowchart: rounded rectangles (representing termi-nal points), parallelograms (representing input/output operations), and a rectangle (representinga process).

The rounded rectangles, or terminal points, indicate the flowchart’s starting and ending points.The parallelograms designate input or output operations. The rectangle depicts a process such asa mathematical computation, or a variable assignment. Notice that the symbols are connectedwith arrows that indicate the direction of program flow.

ConnectorsSometimes a flowchart is broken into two or more smaller flowcharts. This is usually done when aflowchart does not fit on a single page, or must be divided into sections. A connector symbol,which is a small circle with a letter or number inside it, allows you to connect two flowcharts.

In the figure below, the A connector indicates that the second flowchart segment begins where thefirst flowchart segment ends.

Terminal ProcessesInput/OutputOperations

A

END

START A

A

GaddA4.book Page 1126 Monday, July 21, 2003 11:53 AM

Appendix C: Introduction to Flowcharting 1127

Flowchart StructuresThere are four general flowchart structures:

� Sequence

� Decision

� Repetition

� Case

A sequence structure indicates a series of actions or steps, performed in order. The flowchart forthe pay-calculating program is an example of a sequence structure. The following flowchart isalso a sequence structure. It depicts the steps performed in Program 2-20, from Chapter 2.

Flowchart for Program 2-20

The following flowchart, which is another sequence structure, depicts the steps performed inProgram 3-14, the inventory program in Chapter 3. Notice the use of connector symbols to linkthe two flowchart segments.

END

START

Displaytotal wages

Calculate totalwages as regular

wages plusovertime wages

Calculate regularwages as regularpay rate times regular hours

Calculate overtimewages as overtime

pay rate timesovertime hours

GaddA4.book Page 1127 Monday, July 21, 2003 11:53 AM

1128 Appendix C: Introduction to Flowcharting

Flowchart for Program 3–14

START

END

Ask user to enterbeginning

inventory value for both stores

Store begInvin store1 and store2

Read begInv

Read sold

Ask user to enternumber of widgets

sold at store 1

A

A

Subtract soldfrom store1

Subtract soldfrom store2

Read sold

Ask user to enternumber of widgets

sold at store 2

Display inventory values for

both stores

GaddA4.book Page 1128 Monday, July 21, 2003 11:53 AM

Appendix C: Introduction to Flowcharting 1129

The Decision StructureIn a decision structure the next action to be performed depends on the outcome of a true/false test.A statement that is either true or false is evaluated. In the simplest form of decision structure, if theresult of the test is true, a set of instructions is executed and if the result of the test is false, theseinstructions are skipped. In a flowchart a new symbol, the diamond, is used to represent the true/false statement being tested. The following figure shows the general form of this decision structure.

In the following flowchart segment, the statement x < y is tested. If this statement is true, thestatements in process A are executed. If the statement is false, the process A statements are skipped.

condition

statement(s)

false

true

x < y

process A

false

true

GaddA4.book Page 1129 Monday, July 21, 2003 11:53 AM

1130 Appendix C: Introduction to Flowcharting

A slightly more complex form of the decision structure allows one set of statements to be exe-cuted if the test condition is true and another set to be executed if the test condition is false. Thefollowing figure illustrates this form of the decision structure.

In the following flowchart segment, the statement x < y is again tested. But this time a set ofstatements is executed regardless of whether x < y evaluates to true or false. If it is true, the state-ments that make up process A are executed. If it is false, the statements that make up process B areexecuted instead.

The following flowchart depicts the logic of Program 4–5, from Chapter 4. The decision structureshows that one of two possible messages is displayed on the screen, depending on the value of theexpression number % 2.

true falsecondition

statementset 2

statementset 1

true

process A process B

falsex < y

GaddA4.book Page 1130 Monday, July 21, 2003 11:53 AM

Appendix C: Introduction to Flowcharting 1131

Flowchart for Program 4–5

The Case StructureA case structure is a still more complex form of decision structure in which many different possi-ble actions can be taken depending on the value of an integer or character variable or an integerexpression. The following flowchart segment shows the general form of a case structure.

The following flowchart depicts the logic of Program 4–23, which is also from Chapter 4. One of4 possible paths is followed, depending on the value stored in the variable choice.

true

Displaynumber

”is even.”

number % 2equals 0

Read number

Ask user to enter an integer

Displaynumber”is odd.”

false

START

END

GaddA4.book Page 1131 Monday, July 21, 2003 11:53 AM

1132 Appendix C: Introduction to Flowcharting

Flowchart for Program 4–23

Repetition StructuresA repetition structure represents part of the program that repeats. This type of structure is com-monly known as a loop. The following figure shows an example of a repetition structure.

Notice the use of the diamond symbol. A repetition structure tests a statement that indicateswhether or not some condition exists. If the statement is true, meaning the condition exists, a setof actions is performed. Then the statement is tested again. If it is still true, the condition stillexists and the actions are repeated. This continues until the statement is no longer true.

START

Ask user to enterA, B, or C

Read choice

CASEchoice

Display ”Youentered C.“

Displayerror message

Display ”Youentered A.“

Display ”Youentered B.“

OtherA B C

END

true

false

process Ax < y

GaddA4.book Page 1132 Monday, July 21, 2003 11:53 AM

Appendix C: Introduction to Flowcharting 1133

In the flowchart segment just shown, the statement x < y is tested. If it is true, then the state-ments that make up process A are executed and x < y is evaluated again. Process A is repeated as longas x is less than y. When x is no longer less than y, the repetition stops and the structure is exited.

There are two forms of repetition structure: pre-test and post-test. A pre-test repetitionstructure tests its condition before it performs an action. The flowchart segment we have justexamined shows a pre-test structure. Notice that process A does not execute at all if the conditionx < y is not true to begin with. The pre-test repetition structure is normally coded in C++ as awhile loop.

A post-test repetition structure tests its condition after it performs an action. This type ofloop always performs its action at least once. The following flowchart segment shows an example.

The post-test repetition structure is coded in C++ as a do-while loop.The following flowchart depicts the logic of Program 5-4, which appears in Chapter 5. It uses

a pre-test loop.

Flowchart for Program 5-4

true

false

process A

x < y

START

number = 1

Display tableheadings

Display numberand number

squared

number <= 10

true

false

Add 1 to number

END

GaddA4.book Page 1133 Monday, July 21, 2003 11:53 AM

1134 Appendix C: Introduction to Flowcharting

ModulesA program module (such as a function in C++) is represented in a flowchart by the special symbolshown below:

The position of the module symbol indicates the point the module is executed, as shown in thefollowing figure:

A separate flowchart can then be constructed for the module. The following figure shows a flow-chart for the main function of Program 6-14, the health club membership program that appearsin Chapter 6.

START

END

Read input

Call calcPayfunction

Display results

GaddA4.book Page 1134 Monday, July 21, 2003 11:53 AM

Appendix C: Introduction to Flowcharting 1135

Flowchart for Program 6-14

START

Prompt fornumber of monthsand read months

CalldisplayMenu

Call computeFeespassing Adult data

Call computeFeespassing Child data

Call computeFeespassing Senior data

CASEChoice

END

true

1 2 3

true

false

Call getChoiceand store thereturned value

in choice

choiceis not 4

choiceis not 4

false

GaddA4.book Page 1135 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1136 Monday, July 21, 2003 11:53 AM

1137

Appendix DNamespaces

IntroductionNamespaces are an ANSI C++ feature that allows programmers to create a scope for global identifi-ers. They are useful in preventing errors when two or more global declarations use the same name.

For example, assume you are a programmer in the accounting department of a business.Your company has purchased two libraries of C++ class objects from a software vendor. One ofthe libraries is designed to handle customer accounts, and contains a class object named payable.The other library is designed to handle company payroll, and also has a class object named pay-able. You are writing a program that integrates both sets of classes, but the compiler generates anerror because the two class objects have the same name. You cannot modify the class librariesbecause the software vendor does not sell the source code, only libraries of object code.

This problem can be solved when the software vendor places each set of classes in its ownnamespace. Each namespace has its own name, which must be used to qualify the name of itsmembers. For instance, the payable object that is part of the customer accounts library mightexist in a namespace named customer, while the object that is part of the employee payrolllibrary might exist in a namespace named payroll. When you, the application programmer,work with the objects, you must specify the namespace that the object is a member of. One way ofaccomplishing this is by qualifying the name of the object with the namespace name, using thescope resolution operator. For example, the payable object that is a member of the customernamespace is specified as customer::payable, and the object that is a member of the payrollnamespace is specified as payroll::payable. Another way to specify the namespace is by plac-ing a using namespace statement in the source file that references the namespace’s memberobject. For example, the following statement (placed near the beginning of a source file) instructsthe compiler that the file uses members of the customer namespace.

using namespace customer;

Likewise, the following statement instructs the compiler that the source file uses members of thepayroll namespace:

using namespace payroll;

GaddA4.book Page 1137 Monday, July 21, 2003 11:53 AM

1138 Appendix D: Namespaces

When a using namespace statement has been placed in a source file, it is no longer necessary forstatements in that source file to qualify the names of the namespace’s members with thenamespace name and the scope resolution operator.

Defining a NamespaceA namespace is defined in the following manner.

namespace namespace_name{

declarations…}

For example, look at Program D-1. It defines the test namespace, which has three members: x, y,and z.

In Program D-1, the variables x, y, and z are defined in the test namespace’s scope. Each timethe program accesses one of these variables, test:: must precede the variable name. Otherwise, acompiler error will occur.

Program D-1

// Demonstrates a simple namespace#include <iostream>using namespace std;

namespace test{

int x, y, z;}

int main(){

test::x = 10;test::y = 20;test::z = 30;cout << "The values are:\n";cout << test::x << " " << test::y

<< " " << test::z << endl;return 0;

}

Program OutputThe values are:10 20 30

GaddA4.book Page 1138 Monday, July 21, 2003 11:53 AM

Appendix D: Namespaces 1139

Program D-2 demonstrates how programmers can use namespaces to resolve naming con-flicts. The program defines two namespaces, test1 and test2. Both namespaces have variablesnamed x, y, and z as members.

An alternative approach to qualifying the names of namespace members is to use the usingnamespace statement. This statement tells the compiler which namespace to search for anidentifier, when the identifier cannot be found in the current scope. Program D-3 demon-strates the statement.

Program D-2

// Demonstrates two namespaces#include <iostream>using namespace std;

namespace test1{

int x, y, z;}

namespace test2{

int x, y, z;}

int main(){

test1::x = 10;test1::y = 20;test1::z = 30;cout << "The test1 values are:\n";cout << test1::x << " " << test1::y

<< " " << test1::z << endl;test2::x = 1;test2::y = 2;test2::z = 3;cout << "The test2 values are:\n";cout << test2::x << " " << test2::y

<< " " << test2::z << endl;return 0;

}

Program OutputThe test1 values are:10 20 30The test2 values are:1 2 3

GaddA4.book Page 1139 Monday, July 21, 2003 11:53 AM

1140 Appendix D: Namespaces

The using namespace demo; statement eliminates the need to precede testObject withdemo::. The compiler automatically uses the namespace demo to find the identifier.

Program D-3

Contents of nsdemo.h// This file defines a namespace// named demo. In the demo namespace// a class named NsDemo is declared,// and an instance of the class named// testObject is defined.

namespace demo{

class NsDemo{public:

int x, y, z;};

NsDemo testObject;}

Contents of Main File, PrD-3.cpp// This program demonstrates the // using namespace statement.#include <iostream>#include "nsdemo.h"using namespace std;

using namespace demo;

int main(){

testObject.x = 10;testObject.y = 20;testObject.z = 30;cout << "The values are:\n" << testObject.x << " " << testObject.y << " " << testObject.z << endl;return 0;

}

Program OutputThe values are:10 20 30

GaddA4.book Page 1140 Monday, July 21, 2003 11:53 AM

Appendix D: Namespaces 1141

ANSI C++ and the std NamespaceAll the identifiers in the ANSI standard header files are part of the std namespace. In ANSI C++,cin and cout are written as std::cin and std::cout. If you do not wish to specify std:: withcin or cout (or any of the ANSI standard identifiers), you must write the following statement inyour program:

using namespace std;

GaddA4.book Page 1141 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1142 Monday, July 21, 2003 11:53 AM

1143

Appendix EIntroduction to UMLContributed by Art Gittleman

The Unified Modeling Language (UML) has become the standard for object-oriented modeling.The UML class diagram of Figure E-1 represents the BankAccount class, showing the commonstructure of all BankAccount objects. The top section in the figure gives the class name; the mid-dle section lists the variables used to represent the state of a BankAccount; and the bottom sectionlists each BankAccount’s operations used to provide its services.

The class describes the attributes (data) and behavior (operations) each object instance pos-sesses; it is like a pattern or template for specifying the state and behavior of each of its instances.

We create one or more BankAccount objects to instantiate the BankAccount class. In the UMLnotation, object diagrams, as pictured in Figure E-2, represent objects. The objects myAccount andyourAccount are instances of the BankAccount class.

Figure E-1 The BankAccount Class Diagram

BankAccount

balance

getBalance()deposit()withdraw()

GaddA4.book Page 1143 Monday, July 21, 2003 11:53 AM

1144 Appendix E: Introduction to UML

Object diagrams also have three parts. In the top part of the figure, we name the object andindicate the class that defines it, underlining both as in

myAccount:BankAccount

The middle section shows the balance with a specific value, for example

balance = 24.50

The BankAccount class specifies each account must have a balance. In the object itself, thebalance has a specific value. This is analogous to the concept of a chair that specifies a seat andlegs, contrasted with an actual chair object that has a hard seat and curved legs.

The third part of the object diagram in Figure E-2 lists the services the object provides. EachBankAccount object can deposit, withdraw, or get its balance.

Use Cases and ScenariosWe identify the types of objects we need by considering the typical uses of the system, called usecases, and various scenarios, which show, in a step-by-step manner, the interaction between the userand the use cases. When designing with objects, we may start by identifying the use cases. For exam-ple, if we were modeling a customer order at a fast food restaurant, one use case would be a cus-tomer placing an order. To better understand each use of the system, we describe typical scenarios.For each use case, we develop a primary scenario showing the normal interactions and several sec-ondary scenarios that list the interactions that take place in more unusual or error situations.

Associations and Relationships Between ClassesWe also use UML to show the associations between classes. An association represents a relation-ship between instances of the associated classes. For example, a customer places an order with awaiter, while a waiter asks the cook to make a burger. The diagram in Figure E-3 is a simplifica-tion of these associations.

Figure E-2 Two BankAccount Objects

myAccount:BankAccount

balance = 24.50

getBalance()deposit()withdraw()

yourAccount:BankAccount

balance = 142.11

getBalance()deposit()withdraw()

GaddA4.book Page 1144 Monday, July 21, 2003 11:53 AM

Appendix E: Introduction to UML 1145

UML diagrams show inheritance by using unfilled arrows to denote the relationship. Forexample, Figure E-4 shows an inheritance relationship between the BankAccount class and itsSavingsAccount and CheckingAccount subclasses. The subclasses inherit from their parentsuperclass.

UML provides many more diagram types and tools for modeling object-oriented systems.See http://www.rational.com/uml for more information.

Figure E-3 Association Between Classes

Figure E-4 Inheritance

Customer Waiter

Cook

BankAccount

balance

getBalance()deposit()withdraw()

SavingsAccount

interestRate

postInterest()

CheckingAccount

minBalancecharge

processCheck()

GaddA4.book Page 1145 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1146 Monday, July 21, 2003 11:53 AM

1147

Appendix FPassing Command Line Arguments

If you are working in a command line environment such as UNIX, Linux, or the DOS prompt, itmight be helpful to write programs that take arguments from the command line. For example,suppose we have a program called sum, which takes two numbers as command line argumentsand displays their sum. We could enter the following command at the operating system prompt:

sum 12 16

The arguments, which are separated by a space, are 12 and 16. Because a C++ program starts itsexecution with function main, command line arguments are passed to main. Function main canbe optionally written with two special parameters. These parameters are traditionally namedargc and argv. The argc parameter is an int, and the argv parameter is an array of char point-ers. Here is an example function header for main, using these two parameters:

int main(int argc, char *argv[])

The argc parameter contains the number of items that were typed on the command line, includ-ing the name of the program. For example, if the sum program described above is executed withthe command sum 12 16, the argc parameter will contain 3.

As previously mentioned, the argv parameter is an array of char pointers. In the functionheader, the brackets are empty because argv is an external array of unknown size. The numberthat is stored in argc, however, will be the number of elements in the argv array. Each pointer inthe argv array points to a C-string holding a command line argument. Once again, assume thesum program is executed with the command sum 12 16. The elements of the argv array will refer-ence the items on the command line in the following manner:

argv[0] = "sum"argv[1] = "12"argv[2] = "16"

Before we look at the code for the sum program, let’s look at Program F-1. It is a simple programthat simply displays its command line arguments. (The program is named argdemo.cpp.)

Now, let’s look at the code for the sum program.

GaddA4.book Page 1147 Monday, July 21, 2003 11:53 AM

1148 Passing Command Line Arguments

Program F-1 (argdemo.cpp)

// This program demonstrates how to read// command line arguments.#include <iostream>using namespace std;

int main(int argc, char *argv[]){

cout << "You entered " << (argc - 1) cout << " command line arguments.\n";if (argc > 1){

cout << "Here they are:\n";for (int count = 1; count < argc; count++)

cout << argv[count] << endl;}return 0;

}

Example Session on a UNIX System$ argdemo Hello World [Enter]You entered 2 command line arguments.Here they are:HelloWorld$

Program F-2 (sum.cpp)

// This program takes two command line arguments,// assumed to be numbers, and displays their sum.#include <iostream>#include <cmath> // Needed for atofusing namespace std;

int main(int argc, char *argv[]){

double total = 0;

if (argc > 1){

for (int count = 1; count < argc; count++)total += atof(argv[count]);

cout << total << endl;}return 0;

}

GaddA4.book Page 1148 Monday, July 21, 2003 11:53 AM

Passing Command Line Arguments 1149

Example Session on a UNIX System$ sum 12 16 [Enter]28$ sum 1 2 3 4 5 [Enter]15$

Program F-2 (sum.cpp)

GaddA4.book Page 1149 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1150 Monday, July 21, 2003 11:53 AM

1151

❖Appendix GHeader File and Library Function Reference

This appendix provides a reference for the C++ library functions discussed in the book. The fol-lowing table gives an alphabetical list of functions. Tables of functions that are organized by theirheader files follow it.

Alphabetical Listing of Selected Library Functions

Function Details

abs(m) Header File: cstdlibDescription:Accepts an integer argument. Returns the absolute value of the argument as an integer.Example:a = abs(m);

atof(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to a double and returns that value.Example:num = atof("3.14159");

atoi(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to an int and returns that value.Example:num = atoi("4569");

atol(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to a long and returns that value.Example:num = atol("5000000");

(table continues)

GaddA4.book Page 1151 Monday, July 21, 2003 11:53 AM

1152 Appendix G: Header File and Library Function Reference

cos(m) Header File: cmathDescription:Accepts a double argument. Returns the cosine of the argument. The argument should be an angle expressed in radians. The return type is double.Example:a = cos(m);

exit(status) Header File: cstdlibDescription:Accepts an int argument. Terminates the program and passes the value of the argument to the operating system.Example:exit(0);

exp(m) Header File: cmathDescription:Accepts a double argument. Computes the exponential function of the argument, which is ex. The return type is double.Example:a = exp(m);

fmod(m, n) Header File: cmathDescription:Accepts two double arguments. Returns, as a double, the remainder of the first argument divided by the second argument. Works like the modulus operator, but the arguments are doubles. (The modulus operator only works with integers.) Take care not to pass zero as the second argument. Doing so would cause division by zero.Example:a = fmod(m, n);

isalnum(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a letter of the alphabet or a digit. Otherwise, it returns false.Example:if (isalnum(ch)) cout << ch << " is alphanumeric.\n";

isdigit(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a digit from 0 to 9. Otherwise, it returns false.Example:if (isdigit(ch)) cout << ch << " is a digit.\n";

(table continues)

Alphabetical Listing of Selected Library Functions (continued)

Function Details

GaddA4.book Page 1152 Monday, July 21, 2003 11:53 AM

Appendix G: Header File and Library Function Reference 1153

islower(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a lowercase letter. Otherwise, it returns false.Example:if (islower(ch)) cout << ch << " is lowercase.\n";

isprint(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a printable character (including a space). Returns false otherwise.Example:if (isprint(ch)) cout << ch << " is printable.\n";

ispunct(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a printable character other than a digit, letter, or space. Returns false otherwise.Example:if (ispunct(ch)) cout << ch << " is punctuation.\n";

isspace(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a whitespace character. Whitespace characters are any of the following:• space................' '• newline..............'\n'• tab..................'\t'• vertical tab.........'\v'Otherwise, it returns false.Example:if (isspace(ch)) cout << ch << " is whitespace.\n";

isupper(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is an uppercase letter. Otherwise, it returns false.Example:if (isupper(ch)) cout << ch << " is uppercase.\n";

(table continues)

Alphabetical Listing of Selected Library Functions (continued)

Function Details

GaddA4.book Page 1153 Monday, July 21, 2003 11:53 AM

1154 Appendix G: Header File and Library Function Reference

log(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the natural logarithm of the argument.Example:a = log(m);

log10(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the base-10 logarithm of the argument.Example:a = log10(m);

pow(m, n) Header File: cmathDescription:Accepts two double arguments. Returns the value of its first argument raised to the power of the second argument.Example:a = pow(m, n);

rand() Header File: cstdlibDescription:Generates a pseudorandom number.Example:x = rand();

sin(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the sine of the argument. The argument should be an angle expressed in radians.Example:a = sin(m);

sqrt(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the square root of the argument.Example:a = sqrt(m);

(table continues)

Alphabetical Listing of Selected Library Functions (continued)

Function Details

GaddA4.book Page 1154 Monday, July 21, 2003 11:53 AM

Appendix G: Header File and Library Function Reference 1155

srand(m) Header File: cstdlibDescription:Accepts an unsigned int argument. The argument is used as a seed value to randomize the results of the rand() function.Example:srand(m);

strcat(str1, str2) Header File: cstringDescription:Accepts two C-strings as arguments. The function appends the contents of the second string to the first string. (The first string is altered; the second string is left unchanged.)Example:strcat(string1, string2);

strcmp(str1, str2) Header File: cstringDescription:Accepts pointers to two string arguments. If str1 and str2 are the same, this function returns 0. If str2 is alphabetically greater than str1, it returns a positive number. If str2 is alphabetically less than str1, it returns a negative number.Example:if (strcmp(str1, str2) == 0) cout << "The strings are equal.\n";

strcpy(str1, str2) Header File: cstringDescription:Accepts two C-strings as arguments. The function copies the second string to the first string. The second string is left unchanged.Example:strcpy(string1, string2);

strlen(str) Header File: cstringDescription:Accepts a C-string as an argument. Returns the length of the string (not including the null terminator)Example:len = strlen(name);

(table continues)

Alphabetical Listing of Selected Library Functions (continued)

Function Details

GaddA4.book Page 1155 Monday, July 21, 2003 11:53 AM

1156 Appendix G: Header File and Library Function Reference

strncpy(str1, str2, n)

Header File: cstringDescription:Accepts two C-strings and an integer argument. The third argument, an integer, indicates how many characters to copy from the second string to the first string. If str2 has fewer than n characters, str1 is padded with '\0' characters.Example:strncpy(string1, string2, n);

strstr(str1, str2) Header File: cstringDescription:Searches for the first occurrence of str2 in str1. If an occurrence of str2 is found, the function returns a pointer to it. Otherwise, it returns a null pointer (address 0).Example:cout << strstr(string1, string2);

tan(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the tangent of the argument. The argument should be an angle expressed in radians. Example:a = tan(m);

tolower(ch) Header File: cctypeDescription:Accepts a char argument. Returns the lowercase equivalent of its argument.Example:ch = tolower(ch);

toupper(ch) Header File: cctype.hDescription:Accepts a char argument. Returns the uppercase equivalent of its argument.Example:ch = toupper(ch);

Alphabetical Listing of Selected Library Functions (continued)

Function Details

GaddA4.book Page 1156 Monday, July 21, 2003 11:53 AM

Appendix G: Header File and Library Function Reference 1157

Selected cstdlib functions

Function Details

atof(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to a double and returns that value.Example:num = atof("3.14159");

atoi(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to an int and returns that value.Example:num = atoi("4569");

atol(str) Header File: cstdlibDescription:Accepts a C-string as an argument. The function converts the string to a long and returns that value.Example:num = atol("5000000");

exit(status) Header File: cstdlibDescription:Accepts an int argument. Terminates the program and passes the value of the argument to the operating system.Example:exit(0);

rand() Header File: cstdlibDescription:Generates a pseudorandom number.Example:x = rand();

srand(m) Header File: cstdlibDescription:Accepts an unsigned int argument. The argument is used as a seed value to randomize the results of the rand() function.Example:srand(m);

GaddA4.book Page 1157 Monday, July 21, 2003 11:53 AM

1158 Appendix G: Header File and Library Function Reference

Selected cmath Functions

Function Details

abs(m) Header File: cmathDescription:Accepts an integer argument. Returns the absolute value of the argument as an integer.Example:a = abs(m);

cos(m) Header File: cmathDescription:Accepts a double argument. Returns the cosine of the argument. The argument should be an angle expressed in radians. The return type is double.Example:a = cos(m);

exp(m) Header File: cmathDescription:Accepts a double argument. Computes the exponential function of the argument, which is ex. The return type is double.Example:a = exp(m);

fmod(m, n) Header File: cmathDescription:Accepts two double arguments. Returns, as a double, the remainder of the first argument divided by the second argument. Works like the modulus operator, but the arguments are doubles. (The modulus operator only works with integers.) Take care not to pass zero as the second argument. Doing so would cause division by zero.Example:a = fmod(m, n);

log(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the natural logarithm of the argument.Example:a = log(m);

(table continues)

GaddA4.book Page 1158 Monday, July 21, 2003 11:53 AM

Appendix G: Header File and Library Function Reference 1159

log10(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the base-10 logarithm of the argument.Example:a = log10(m);

pow(m, n) Header File: cmathDescription:Accepts two double arguments. Returns the value of its first argument raised to the power of the second argument.Example:a = pow(m, n);

sin(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the sine of the argument. The argument should be an angle expressed in radians.Example:a = sin(m);

sqrt(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the square root of the argument.Example:a = sqrt(m);

tan(m) Header File: cmathDescription:Accepts a double argument. Returns, as a double, the tangent of the argument. The argument should be an angle expressed in radians. Example:a = tan(m);

Selected cmath Functions (continued)

Function Details

GaddA4.book Page 1159 Monday, July 21, 2003 11:53 AM

1160 Appendix G: Header File and Library Function Reference

Selected cstring Functions

Function Details

strcat(str1, str2) Header File: cstringDescription:Accepts two C-strings as arguments. The function appends the contents of the second string to the first string. (The first string is altered; the second string is left unchanged.)Example:strcat(string1, string2);

strcmp(str1, str2) Header File: cstringDescription:Accepts pointers to two string arguments. If str1 and str2 are the same, this function returns 0. If str2 is alphabetically greater than str1, it returns a positive number. If str2 is alphabetically less than str1, it returns a negative number.Example:if (strcmp(string1, string2) == 0) cout << "The strings are equal.\n";

strcpy(str1, str2) Header File: cstringDescription:Accepts two C-strings as arguments. The function copies the second string to the first string. The second string is left unchanged.Example:strcpy(string1, string2);

strlen(str) Header File: cstringDescription:Accepts a C-string as an argument. Returns the length of the string (not including the null terminator)Example:len = strlen(name);

strncpy(str1, str2, n)

Header File: cstringDescription:Accepts two C-strings and an integer argument. The third argument, an integer, indicates how many characters to copy from the second string to the first string. If str2 has fewer than n characters, str1 is padded with '\0' characters.Example:strncpy(string1, string2, n);

(table continues)

GaddA4.book Page 1160 Monday, July 21, 2003 11:53 AM

Appendix G: Header File and Library Function Reference 1161

strstr(str1, str2) Header File: cstringDescription:Searches for the first occurrence of str2 in str1. If an occurrence of str2 is found, the function returns a pointer to it. Otherwise, it returns a NULL pointer (address 0).Example:cout << strstr(string1, string2);

Selected cctype Functions and Macros

Function Details

isalnum(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a letter of the alphabet or a digit. Otherwise, it returns false.Example:if (isalnum(ch)) cout << ch << " is alphanumeric.\n";

isdigit(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a digit from 0 to 9. Otherwise, it returns false.Example:if (isdigit(ch)) cout << ch << " is a digit.\n";

islower(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a lowercase letter. Otherwise, it returns false.Example:if (islower(ch)) cout << ch << " is lowercase.\n";

isprint(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a printable character (including a space). Returns false otherwise.Example:if (isprint(ch)) cout << ch << " is printable.\n";

(table continues)

Selected cstring Functions (continued)

Function Details

GaddA4.book Page 1161 Monday, July 21, 2003 11:53 AM

1162 Appendix G: Header File and Library Function Reference

ispunct(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a printable character other than a digit, letter, or space. Returns false otherwise.Example:if (ispunct(ch)) cout << ch << " is punctuation.\n";

isspace(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is a whitespace character. Whitespace characters are any of the following:• space................ ' '• newline.............. '\n'• tab.................. '\t'• vertical tab......... '\v'Otherwise, it returns false.Example:if (isspace(ch)) cout << ch << " is whitespace.\n";

isupper(ch) Header File: cctypeDescription:Accepts a char argument. Returns true if the argument is an uppercase letter. Otherwise, it returns false.Example:if (isupper(ch)) cout << ch << " is uppercase.\n";

tolower(ch) Header File: cctypeDescription:Accepts a char argument. Returns the lowercase equivalent of its argument.Example:ch = tolower(ch);

toupper(ch) Header File: cctypeDescription:Accepts a char argument. Returns the uppercase equivalent of its argument.Example:ch = toupper(ch);

Selected cctype Functions and Macros (continued)

Function Details

GaddA4.book Page 1162 Monday, July 21, 2003 11:53 AM

1163

Appendix HThe Binary Number System and Bitwise Operations

One of the many powers that C++ gives the programmer is the ability to work with the individualbits of an integer field. The purpose of this appendix is to give an overview of how integer typesare stored in binary and explain the bitwise operators that the C++ offers. Finally, we will look atbit fields, which allow us to treat the individual bits of a variable as separate entities.

Integer FormsThe integer types that C++ offers are as follows:

charintshortlongunsigned charunsigned (same as unsigned int)unsigned shortunsigned long

When you assign constant values to integers in C++, you may use decimal, octal, or hexadecimal.Placing a zero in the first digit creates an octal constant. For example, 0377 would be interpretedas an octal number. Hexadecimal constants are created by placing 0x or 0X (zero-x, not O-x) infront of the number. The number 0X4B would be interpreted as a hex number.

Binary RepresentationRegardless of how you express constants, integer values are all stored the same way internally—inbinary format. Let’s take a quick review of binary number representation.

Let’s assume we have a one-byte field. The diagram below shows our field broken into itsindividual bits.

GaddA4.book Page 1163 Monday, July 21, 2003 11:53 AM

1164 Appendix H: The Binary Number System and Bitwise Operations

The leftmost bits are called the high order bits and the rightmost bits are called the low order bits.Bit number 7 is the highest order bit, so it is called the most significant bit.

Each of these bits has a value assigned to it. The diagram below shows the values of each bit:

These values are actually powers of two. The value of bit 0 is 20, which is 1. The value of bit 1 is 21,which is 2. Bit 2 has the value 22, which is 4. It progresses to the last bit.

When a number is stored in this field, the bits may be set to either 1 or 0. Here is an example.

Here, bits 1, 2, 5, and 6 are set to 1. To calculate the overall value of this bit pattern, we add up allof the bit values of the bits that are set to 1.

Bit 1’s value 2Bit 2’s value 4Bit 5’s value 32Bit 6’s value 64

Overall Value 102

The bit pattern 01100110 has the decimal value 102.

Negative Integer ValuesOne way that a computer can store a negative integer is to use the leftmost bit as a sign bit. Whenthis bit is set to 1, it would indicate a negative number, and when it is set to 0 the number wouldbe positive. The problem with this, however, is that we would have two bit patterns for the num-ber 0. One pattern would be for positive 0, the other would be for negative 0. Because of this,most systems use two’s complement representation for negative integers.

Bit Bit Bit Bit Bit Bit Bit Bit

7 6 5 4 3 2 1 0

High Order -------------------------> Low Order

Bit Bit Bit Bit Bit Bit Bit Bit

7 6 5 4 3 2 1 0

Values –> 128 64 32 16 8 4 2 1

Bit Bit Bit Bit Bit Bit Bit Bit

7 6 5 4 3 2 1 0

0 1 1 0 0 1 1 0

Values –> 128 64 32 16 8 4 2 1

GaddA4.book Page 1164 Monday, July 21, 2003 11:53 AM

Appendix H: The Binary Number System and Bitwise Operations 1165

To calculate the two’s compliment of a number, first you must get the one’s compliment. Thismeans changing each 1 to a 0, and each 0 to a 1. Next, add 1 to the resulting number. What youhave is the two’s compliment. Here is how the computer stores the value –2.

2 is stored as 00000010Get the one’s compliment 11111101Add 1 1

And the result is 11111110

As you can see, the highest order bit is still set to 1, indicating not only that this is a negative num-ber, but it is stored in two’s compliment representation.

Bitwise OperatorsC++ provides operators that let you perform logical operations on the individual bits of integervalues, and shift the bits right or left.

The Bitwise Negation OperatorThe bitwise negation operator is the ~ symbol. It is a unary operator that performs a negation, orone’s compliment on each bit in the field. The expression

~val

returns the one’s compliment of val. It does not change contents of val. It could be used in thefollowing manner:

negval = ~val;

This will store the one’s compliment of val in negval.

The Bitwise AND OperatorThe bitwise AND operator is the & symbol. This operator performs a logical AND operation oneach bit of two operands. This means that it compares the two operands bit by bit. For each posi-tion, if both bits are 1, the result will be 1. If either or both bits are 0, the results will be 0. Here isan example:

andval = val & 0377;

The result of the AND operation will be stored in andval. There is a combined assignment ver-sion of this operator. Here is an example:

val &= 0377;

GaddA4.book Page 1165 Monday, July 21, 2003 11:53 AM

1166 Appendix H: The Binary Number System and Bitwise Operations

This is the same as

val = val & 0377;

The Bitwise OR OperatorThe bitwise OR operator is the | symbol. This operator performs a logical OR operation on eachbit of two operands. This means that it compares the two operands bit by bit. For each position, ifeither of the two bits is 1, the result will be 1. Otherwise, the results will be 0. Here is an example:

orval = val | 0377;

The result of the OR operation will be stored in orval. There is a combined assignment versionof this operator. Here is an example:

val |= 0377;

This is the same as

val = val | 0377;

The Bitwise EXCLUSIVE OR OperatorThe bitwise EXCLUSIVE OR operator is the ^ symbol. This operator performs a logical XORoperation on each bit of two operands. This means that it compares the two operands bit by bit.For each position, if one of the two bits is 1, but not both, the result will be 1. Otherwise, theresults will be 0. Here is an example:

xorval = val ^ 0377;

The result of the XOR operation will be stored in xorval. There is a combined assignment ver-sion of this operator. Here is an example:

val ^= 0377;

This is the same as

val = val ^ 0377;

Using Bitwise Operators with MasksSuppose we have the following variable declarations:

char value = 110, cloak = 2;

The binary pattern for each of these two variables will be as follows:

value --> 0 1 1 0 1 1 1 0 = 110

cloak --> 0 0 0 0 0 0 1 0 = 2

GaddA4.book Page 1166 Monday, July 21, 2003 11:53 AM

Appendix H: The Binary Number System and Bitwise Operations 1167

The operation

value &= cloak;

will perform a logical bitwise AND on the two variables value and cloak. The result will bestored in value. Remember a bitwise AND will produce a 1 only when both bits are set to 1. Hereis a diagram showing the result of the AND operation.

AND

equals

The 0’s in the cloak variable “hide” the values that are in the corresponding positions of thevalue variable. This is called masking. When you mask a variable, the only bits that will “showthrough” are the ones that correspond with the 1’s in the mask. All others will be turned off.

Turning Bits OnSometimes you may want to turn on selected bits in a variable and leave all of the rest alone. Thisoperation can be performed with the bitwise OR operator. Let’s see what happens when we ORthe value and cloak variables we used before, but using a different value for cloak.

char value = 110, cloak = 16;value |= mask;

This diagram illustrates the result of the OR operation:

OR

equals

This caused bit 4 to be turned on and all the rest to be left alone.

value --> 0 1 1 0 1 1 1 0

cloak --> 0 0 0 0 0 0 1 0

result --> 0 0 0 0 0 0 1 0

value --> 0 1 1 0 1 1 1 0

cloak --> 0 0 0 1 0 0 0 0

result --> 0 1 1 1 1 1 1 0

GaddA4.book Page 1167 Monday, July 21, 2003 11:53 AM

1168 Appendix H: The Binary Number System and Bitwise Operations

Turning Bits OffSuppose that instead of turning specific bits on, you wish to turn them off. Assume we have thefollowing declaration:

char status = 127, cloak = 8;

Bit 3 of cloak is set to 1, and all the rest are set to 0. If we wish to set bit 3 of status to 0 we mustAND it with the negation of cloak. In other words, we must get the one’s compliment of cloak,then AND it with status. The statement would look like this:

status &= ~cloak;

Here is what cloak’s bit pattern looks like:

And here is the one’s compliment of cloak:

Here is what we get when we AND status and the one’s compliment of cloak:

AND

equals

Bit 3 of status is turned off, and all other bits were left unchanged.

Toggling BitsTo toggle a bit is to flip it off when it is on, and on when it is off. This can be done with the EXCLUSIVEOR operator. We will use the following variables to illustrate.

char status = 127, cloak = 8;

Our objective is to toggle bit 3 of status, so we will use the XOR operator.

status ^= cloak;

Here is the diagram of the operation:

cloak --> 0 0 0 0 1 0 0 0

~cloak --> 1 1 1 1 0 1 1 1

status --> 0 1 1 1 1 1 1 1

~cloak --> 1 1 1 1 0 1 1 1

result --> 0 1 1 1 0 1 1 1

status --> 0 1 1 1 1 1 1 1

GaddA4.book Page 1168 Monday, July 21, 2003 11:53 AM

Appendix H: The Binary Number System and Bitwise Operations 1169

XOR

equals

Bit 3 of status will be set to 0. If we repeat this operation with the new value of status, this iswhat will happen:

XOR

equals

Bit 3 of status will be toggled again, restoring it to its previous state.

Testing the Value of a BitTo test the value of an individual bit, you must use the AND operator. For example, if we want totest the variable bitvar to see if bit 2 is on, we must use a mask that has bit 2 turned on. Here isan example of the test:

if ((bitvar & 4) == 4)cout << "Bit 2 is on.\n";

Remember that ANDing a value with a mask will produce a value that hides all of the bits butthe ones turned on in the mask. If bit 2 of bitvar is on, the expression bitvar & 4 will returnthe value 4.

The parentheses around bitvar & 4 are necessary because the == operator has higher prece-dence than the & operator.

The Bitwise Left Shift OperatorThe bitwise left shift operator is two less-than signs (<<). It takes two operands. The operand onthe left is the one to be shifted, and the operand on the right is the number of places to shift.When the bit values are shifted left, the vacated positions to the right are filled with 0 and the bitsthat shift out of the field are lost. Suppose we have the following variables:

char sand = 2, shiftsand;

cloak --> 0 0 0 0 1 0 0 0

result --> 0 1 1 1 0 1 1 1

status --> 0 1 1 1 0 1 1 1

cloak --> 0 0 0 0 1 0 0 0

result --> 0 1 1 1 1 1 1 1

GaddA4.book Page 1169 Monday, July 21, 2003 11:53 AM

1170 Appendix H: The Binary Number System and Bitwise Operations

The following statement will store in shiftsand the value of sand shifted left two places.

shiftsand = sand << 2;

Let’s see what is happening behind the scenes with the value in sands

Realize, however that sand itself is not being shifted. The variable shiftsand is being set to thevalue of sand shifted left two places. If we wanted to shift sand itself, we could use the combinedassignment version of the left shift operator.

sand <<= 2;

Shifting a number left by n places is the same as multiplying it by 2n. So the example above is thesame as

sand *= 4;

The bitwise shift will almost always work faster, however.

The Bitwise Right Shift OperatorThe bitwise right shift operator is two greater-than signs (>>). Like the left shift operator, it takestwo operands. The operand on the left is the one to be shifted, and the operand on the right is thenumber of places to shift. When the bit values are shifted right, and the variable is signed, whatthe vacated positions to the left are filled with depends on the machine. They could be filled with0 or with the value of the sign bit. If the variable is unsigned, the places will be filled with 0. Thebits that shift out of the field are lost.

Suppose we have the following variables:

char sand = 8, shiftsand;

The following statement will store in shiftsand the value of sand shifted right two places.

shiftsand = sand >> 2;

Let’s see what is happening behind the scenes with the value in sand.

Before shift 0 0 0 0 0 0 1 0

After shift 0 0 0 0 1 0 0 0

Before shift 0 0 0 0 1 0 0 0

After shift 0 0 0 0 0 0 1 0

GaddA4.book Page 1170 Monday, July 21, 2003 11:53 AM

Appendix H: The Binary Number System and Bitwise Operations 1171

As before, sand itself is not being shifted. The variable shiftsand is being set to the value of sandshifted right two places. If we wanted to shift sand itself, we could use the combined assignmentversion of the right shift operator.

sand >>= 2;

Shifting a number right by n places is the same as dividing it by 2n (as long as the number is notnegative). So, the example is the same as

sand /= 4;

The bitwise shift will almost always work faster, however.

Bit FieldsC++ allows you to create data structures that use bits as individual variables. Bit fields must bedeclared as part of a structure. Here is an example.

struct {unsigned field1 : 1;unsigned field2 : 1;unsigned field3 : 1;unsigned field4 : 1;} fourbits;

The variable fourbits contains four bit fields: field1, field2, field3, and field4. Followingthe colon after each name is a number that tells how many bits each field should be made up of. Inthis example, each field is 1 bit in size. This structure is stored in memory in a regular unsignedint. Since we are only using four bits, the remaining ones will go unused.

Values may be assigned to the fields just as if it were a regular structure. In this example, weassign the value 1 to the field1 member:

fourbits.field1 = 1;

Since these fields are only 1 bit in size, we can only put a 1 or a 0 in them. We can expand thecapacity of bit fields by making them larger, as in the following example:

struct {unsigned field1 : 1;unsigned field2 : 2;unsigned field3 : 3;unsigned field4 : 4;} mybits;

Here, mybits.field1 is only 1 bit in size, but others are larger. mybits.field2 occupies 2 bits,mybits.field3 occupies 3 bits, and mybits.field4 occupies 4 bits. Here is a table that showsthe maximum values of each field:

GaddA4.book Page 1171 Monday, July 21, 2003 11:53 AM

1172 Appendix H: The Binary Number System and Bitwise Operations

This data structure uses a total of 10 bits. If you create a bit field structure that uses more bits thanwill fit in an int, the next int sized area will be used. Suppose we declare the following bit fieldstructure on a system that has 16 bit integers.

struct {unsigned tiny : 1;unsigned small : 4;unsigned big : 6;unsigned bigger : 8;unsigned biggest : 9;} flags;

The problem that occurs here is that flags.bigger will straddle the boundary between the firstand second integer area. The compiler won’t allow this to happen. flags.tiny, flags.small,and flags.big will occupy the first integer area, and flags.bigger will reside in the secondinteger area. There will be five unused bits in the first. Likewise, since flags.bigger andflags.biggest cannot fit within one integer area, flags.biggest will reside in a third area.There will be eight unused bits in the second area, and seven unused bits in the third.

You can force a field to be aligned with the next integer area by putting an unnamed bit fieldwith a length of 0 before it. Here is an example:

struct {unsigned first : 1; : 0;unsigned second : 1; : 0;unsigned third : 2;} scattered;

The unnamed fields with the 0 width force scattered.second and scattered.third to bealigned with the next int area.

You can create unnamed fields with lengths other than 0. This way you can force gaps to existat certain places. Here is an example.

struct {unsigned first : 1; : 2;unsigned second : 1; : 3;unsigned third : 2;} gaps;

Field Name Number of Bits Maximum Value

mybits.field1 1 1

mybits.field2 2 3

mybits.field3 3 7

mybits.field4 4 15

GaddA4.book Page 1172 Monday, July 21, 2003 11:53 AM

Appendix H: The Binary Number System and Bitwise Operations 1173

This will cause a 2-bit gap to come between gaps.first and gaps.second, and a 3-bit gap tocome between gaps.second and gaps.third.

Bit fields are not very portable when the physical order of the fields and the exact location ofthe boundaries are used. Some machines order the bit fields from left to right, but others orderthem from right to left.

GaddA4.book Page 1173 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1174 Monday, July 21, 2003 11:53 AM

1175

Appendix IC++ Casts and Run-Time Type Identification

IntroductionThere are many times when a programmer needs to use type casts to tell the compiler to convertthe type of an expression to another type. For example, suppose that you have the sum of n inte-ger values in an integer variable sum, and would like to compute the average and store it in a vari-able average of type float. In this case, you must tell the compiler to first convert sum to floatbefore performing the division by using a type cast:

float average;average = (float)sum / n;

This type of casting is called the C- style of casting. Alternatively, you can use the newer C++ func-tional style of casting:

float average;average = float(sum) / n;

The functional style of casting will work for primitive built-in types such as char, float, intand double, as well as for user-defined class types that provide convert constructors. The effect offunctional style casting is in most cases the same as that of C-style casting.

Another example of casting occurs frequently in reading from an I/O device (perhaps amodem, a network connection, or a disk) from which data arrives as a stream of bytes. In thiscase, to store the data in a data item of some type, say a structure

struct PersonData{

char name[20];int age;

};PersonData data;

GaddA4.book Page 1175 Monday, July 21, 2003 11:53 AM

1176 Appendix I: C++ Casts and Run-Time Type Identification

the address of data must be treated as the address of a location where a sequence of bytes will bestored. In other words, a pointer to data must be treated as a pointer to a byte. Since C++ treatsbytes as if they were characters, this just means that a pointer to the type PersonData must beregarded as if it were a pointer to char. Again, this is accomplished through the use of a type cast:

char *pChar = (char *)&data;

This statement takes a pointer to the structure data, treats it as a pointer to char using a typecast, and uses the resulting value to initialize the newly created pointer variable pChar.

It is clear that these two examples of casting are different, not only in their purpose, butalso in the way that they are implemented by the compiler. In converting an int to a float, thecompiler must change the internal bit representation of an integer into the bit representation ofa float, whereas in the second example, no transformation of the bit representation is per-formed. The designers of the C++ standard decided to introduce different casting notations torepresent these two different kinds of casts as well as two other kinds of casts also used in thelanguage. The designers introduced four different ways of casting:

1. static_cast

2. reinterpret_cast

3. const_cast

4. dynamic_cast

Using the new style casts clarifies the programmer’s intent to the compiler and enables the com-piler to catch casting errors.

In this appendix, we will discuss the four ANSI C++ style type casts and briefly touch on therelated topic of using the typeid operator.

static_castThe most commonly used type of cast is the static_cast, which is used to convert an expressionto a value of a specified type. For example, to convert an expression expr1 to a value of typeType1 and assign it to a variable var1, you would write

type1 var1 = static_cast< type1 >(expr1);

in place of the traditional C-style cast

type1 var1 = (type1) expr1;

For example, to perform the conversion of int to float mentioned in the first example of theintroductory section, you would write

float average = static_cast< float >(sum) / n;

GaddA4.book Page 1176 Monday, July 21, 2003 11:53 AM

Appendix I: C++ Casts and Run-Time Type Identification 1177

A static_cast is used to convert an expression of one type to a second type when the com-piler has information on how to perform the indicated conversion. For example, static_castcan be used to perform all kinds of conversions between char, int, long, float, and doublebecause the knowledge for performing those types of conversions is already built into the com-piler. A static_cast can also be used if information on how to perform the conversion has beenprovided by the programmer through type conversion operators. For example, consider the class

class FeetInches{ private: int feet; int inches; public: FeetInches(int f, int i) { feet = f; inches = i; } // type conversion operator operator float() { return feet + inches/12.0;

}};

This class provides information to the compiler on how to convert a FeetInches object to afloat. As a result, the following main function will compile correctly and print 3.5 and 3 when itexecutes.

#include <iostream>#include "FeetInchesEx.h"using namespace std;

int main(){ FeetInches ftObject(3, 6); // use static_cast to convert to float float ft = static_cast< float >(ftObject); cout << ft; // use static_cast to convert to int cout << endl << static_cast< int >(ftObject); return 0;}

Here we have assumed that the class declaration is stored in the indicated header file. The staticcast to float succeeds because of the presence of the type conversion operator, while the cast toint succeeds because the compiler already knows how to convert float to int.

GaddA4.book Page 1177 Monday, July 21, 2003 11:53 AM

1178 Appendix I: C++ Casts and Run-Time Type Identification

An example of an improper use of static_cast might be instructive. Assuming the same dec-laration of FeetInches as earlier, the following main function will be rejected by the compiler:

int main(){

FeetInches ftObject(3, 6);// illegal use of static_cast

char *pInt = static_cast< int * >(&ftObject); cout << *pInt; return 0;}

The program fails to compile because the compiler has been given no information on how to con-vert a pointer to a FeetInches object to a pointer to int.

Finally, a static_cast can be used to cast a pointer to a base class to a pointer to a derivedclass. We will see an example of this in the last section of this appendix.

reinterpret_castA reinterpret_cast is used to force the compiler to treat a value as if it were of a different typewhen the compiler knows of no way to perform the type conversion. A reinterpret_cast ismostly used with pointers, when a pointer to one type needs to be treated as if it were a pointer toa different type. In other words, reinterpret_cast is useful with the second kind of casting dis-cussed in the introductory section. No change in the bit representation takes place: The valuebeing cast is just used as is.

The notation for reinterpret_cast is similar to that for static_cast. To force expressionexpr1 to be regarded as a value of type type1, we would write

type1 var1 = reinterpret_cast< type1 >(expr1);

instead of the old C-style cast. For example, if for some reason we needed to treat a FeetInchesobject as a pair of integers, we could set a pointer to int to point to the object, and then access theinteger components of the object by dereferencing the pointer. The reinterpret_cast wouldbe used to force the change of type in the pointer. The following main program would print 3 onone line and 6 on the next.

int main(){ FeetInches ftObject(3, 6); // point to beginning of object int *p = reinterpret_cast< int * >(&ftObject); cout << *p << endl; // advance the pointer by size of one int p++; cout << *p; return 0;}

GaddA4.book Page 1178 Monday, July 21, 2003 11:53 AM

Appendix I: C++ Casts and Run-Time Type Identification 1179

The compiler will reject the use of reinterpret_cast where there is already adequate informa-tion on how to perform the type conversion. In particular, the following statement generates acompiler error:

cout << reinterpret_cast< int >(ftObject);

Well-designed programs that do not work directly with hardware should have little need forthis type of casting. Indeed, a need to use reinterpret_cast may well be an indication of adesign error.

const_castThis type of casting is only used with pointers to constants, and is used to treat a pointer to a con-stant as though it were a regular pointer. A pointer to a constant may not be used to change thememory location it points to. For example, we may define a pair of integer variables and a pointerto a constant int as follows:

int k = 4;int m = 20;const int *pToC;

We may then make the pointer pToC point to different integer variables, as in

pToC = &k;cout << *pToC; // prints 4pToC = &m;cout << *pToC; // prints 20

but we cannot use pToC to change whatever variable pToC points to. For example, the code

*pToC = 23;

is illegal. Moreover, you cannot assign the value of a pointer to a constant to another pointer thatis not itself a pointer to a constant, since the constant might then be changed through the secondpointer:

int *p1; // not a pointer to constantp1 = pToC; // error!!

For the same reason, a pointer to a constant can only be passed to a function if the corre-sponding formal parameter is a pointer to a constant. Thus, with the function definition

void print(int *p){

cout << *p;}

the call

print(pToC);

GaddA4.book Page 1179 Monday, July 21, 2003 11:53 AM

1180 Appendix I: C++ Casts and Run-Time Type Identification

would be illegal. Such a call, however, would be all right if the function were modified to take aparameter that is a pointer to a constant. Thus, in the presence of

void constPrint(const int *p){

cout << *p;}

the call

constPrint(pToC);

would be alowed.We have purposely kept these examples simple. In real programs, the pointer to a constant

might be returned by a member function of a class, and point to a member of the class that needsto be protected from modification. This pointer might need to be passed to a function such asprint above which perhaps through poor planning was not written to take a pointer to a con-stant. In this case, the compiler can be persuaded to accept the call by “casting away” the “const-ness” of the pointer using a const_cast:

print( const_cast< int * >(pToC) );

Naturally, const_cast can also be used to allow assignment of a pointer to a constant to aregular pointer:

int *p = const_cast< int * >(pToC);

As in the case of reinterpret_cast, we note that the use of const_cast should not be neces-sary in most well-designed programs.

dynamic_castPolymorphic code is code that is capable of being invoked with objects belonging to differentclasses within the same inheritance hierarchy. Because objects of different classes have differentstorage requirements, polymorphic code does not use the objects directly. Instead, it accessesthem through references or pointers. In this appendix, we will deal mainly with the access of poly-morphic objects through pointers: access through references is similar.

Polymorphic code processes objects of different classes by treating them as belonging to thesame base class. At times, however, it is necessary to determine at run time the specific derivedclass of the object, so that its methods can be invoked. Objects designed to be processed by poly-morphic code carry type information within them to make run-time type identification possible.In C++, such objects must belong to a polymorphic class. A polymorphic class is a class with atleast one virtual member function, or one that is derived from such a class.

In C++, a dynamic_cast is used to take a pointer (or reference) to an object of a polymor-phic class, determine whether the object is of a specified target class, and if so, return that pointer

GaddA4.book Page 1180 Monday, July 21, 2003 11:53 AM

Appendix I: C++ Casts and Run-Time Type Identification 1181

cast as a pointer to the target class. If the object cannot be regarded as belonging to the targetclass, dynamic_cast returns the special pointer value 0.

A typical use of dynamic_cast is as follows. Let pExpr be a pointer to an object of somederived class of a polymorphic class PolyClass, and let DerivedClass be one of several classesderived from PolyClass. We can determine whether the object pointed to by pExpr is aDerivedClass object by writing

DerivedClass *dP = dynamic_cast<DerivedClass *>(pExpr);if (dP) { // the object *dP belongs to DerivedClass … }else { // *dp does not belong to DerivedClass … }

Here DerivedClass is what we have called the specified target class.As an example, consider a farm that keeps cows for milk as well as a number of dogs to guard

the homestead. All the animals eat (have an eat member function), the cows give milk (have agiveMilk member function), and the dogs keep watch (have a guardhouse member function).We can describe all of these by using the following hierarchy of classes:

#include <iostream>using namespace std;

class DomesticAnimal{ public: virtual void eat() { cout << "Animal eating: Munch munch." << endl; }};

class Cow:public DomesticAnimal{ public: void giveMilk() { cout << "Cow giving milk." << endl; }};

class Dog:public DomesticAnimal{

GaddA4.book Page 1181 Monday, July 21, 2003 11:53 AM

1182 Appendix I: C++ Casts and Run-Time Type Identification

public: void guardHouse() { cout << "Dog guarding house." << endl; }};

Note that the eat member function has been declared as a virtual member function in order tomake all the classes polymorphic.

Many applications work with collections, usually arrays of objects belonging to the sameinheritance hierarchy. For example, our farm may have two cows and two dogs, which can bestored in an array as follows:

DomesticAnimal *a[4] = {new Dog, new Cow, new Dog, new Cow };

We have to use an array of pointers since an array of DomesticAnimal would not be able to holdDog or Cow objects, either of which would normally require more storage than a DomesticAni-mal. Now suppose that we wanted to go through the entire array of animals and milk all the cows.We couldn’t just go through the array with a loop such as

for (int k = 0; k < 4; k++) a[k]->giveMilk();

for then we would cause run-time errors whenever a[k] points to a Dog. A dynamic_cast willtake a pointer such as a[k], look at the actual type of the object being pointed to, and return theaddress of the object if the object matches the target type of the dynamic_cast. If the object doesnot match the target type of the cast, then 0 is returned in place of the address. As mentioned, thegeneral format for casting an expression expr1 to a target type TargetType is

dynamic_cast< TargetType >(expr1);

where TargetType must be a pointer or reference type. In our case, to determine if a domesticanimal pointed to by a[k] is a cow we would write

Cow *pC = dynamic_cast< Cow * >(a[k]);

and then test pC to see if it was 0. If it is 0, we know the animal is not a cow and that it is useless toattempt to milk it; otherwise, we can milk the animal by invoking

a[k]->giveMilk();

Here is a main function that puts all of this together.

int main(){ DomesticAnimal *a[4] = {new Dog, new Cow, new Dog, new Cow, };

GaddA4.book Page 1182 Monday, July 21, 2003 11:53 AM

Appendix I: C++ Casts and Run-Time Type Identification 1183

for (int k = 0; k < 4; k++) { Cow *pC = dynamic_cast<Cow *>(a[k]); if (pC)

{ // pC not 0, so we found a cow pC->giveMilk();

} else { cout << "This animal is not a cow." << endl; } } return 0;}

When executed, the output will be

This animal is not a cow.Cow giving milk.This animal is not a cow.Cow giving milk.

The dynamic_cast is so called because the type of the object of a polymorphic class cannotalways be determined statically, that is, at compile time without running the program. For exam-ple, in the statement

a[k]->giveMilk();

it is impossible to determine at compile time whether a[k] points to a Dog or a Cow since it canpoint to objects of either type. In contrast, static_cast uses information available at compiletime.

Run-Time Type IdentificationAs we have seen, dynamic_cast can be used to identify the class type of a polymorphic objectwithin an inheritance hierarchy at run time. More generally, the typeid operator can be used toidentify the type of any expression at run time. The typeid operator can be applied to both dataand type expressions:

typeid(data_expression)

or

typeid(type_expression)

For example, if we have the definitions

int i;Cow c;Cow *pC;

GaddA4.book Page 1183 Monday, July 21, 2003 11:53 AM

1184 Appendix I: C++ Casts and Run-Time Type Identification

then we could apply the typeid operator to the data items i+12, c, and pC, giving

typeid(i+12)typeid(c)typeid(pC)

which would respectively be equal to the results of applying typeid to the corresponding typeexpressions

typeid(int)typeid(Cow)typeid(Cow *)

In the program in the last section, evaluating the expression

typeid(a[k]) == typeid(DomesticAnimal)

would always yield the value true. To find out if the animal pointed to by a[k] is a cow, we wouldtest the expression

typeid(*a[k]) == typeid(Cow)

to see if it was true. If it was true, we could then use a static_cast to cast a[k] to the appropri-ate type in order to milk the cow:

static_cast<Cow *>(a[k])->giveMilk();

The cast is necessary since without it, the statement

a[k]->giveMilk();

will not compile. This is because the type of a[k] is a pointer to a DomesticAnimal, and domes-tic animals do not have a giveMilk() member function.

GaddA4.book Page 1184 Monday, July 21, 2003 11:53 AM

1185

Appendix JMulti-Source File Programs

Programming students normally begin by writing programs that are contained in a single file.Once the size of a program grows large enough, however, it becomes necessary to break it up intomultiple files. This results in smaller files that compile more quickly and are easier to manage. Inaddition, dividing the program into several files facilitates the parceling out of different parts ofthe program to different programmers when the program is being developed by a team.

Generally, a multi-file program consists of two types of files: those that contain function def-initions, and those that contain function prototypes and templates. Here is a common strategyfor creating such a program:

� Group all specialized functions that perform similar tasks into the same file. For exam-ple, a file might be created for functions that perform mathematical operations. Another file might contain functions for user input and output.

� Group function main and all functions that play a primary role into one file.

� For each file that contains function definitions, create a separate header file to hold the prototypes for each function and any necessary templates.

As an example, consider a multi-file banking program that processes loans, savings accounts,and checking accounts. Figure J-1 illustrates the different files that might be used. Notice the file-naming conventions used and how the files are related.

� Each file that contains function definitions has a filename with a .cpp extension.

� Each .cpp file has a corresponding header file with the same name, but with the a .h file extension. The header file contains function prototypes and templates for all functions that are part of the corresponding .cpp file.

� Each .cpp file has an #include directive for its own header file. If the .cpp file contains calls to functions in another .cpp file, it will also have an #include directive for the header file for that function.

GaddA4.book Page 1185 Monday, July 21, 2003 11:53 AM

1186 Appendix J: Multi-Source File Programs

Compiling and Linking a Multi-File ProgramIn a program with multiple source code files, all of the .cpp files are compiled into separate objectfiles. The object files are then linked into a single executable file. Integrated development environ-ments, such as those provided by Borland’s C++ Builder and Microsoft Visual C++, facilitate thisprocess by allowing you to organize a collection of source code files into a project and then usemenu items to add files to the project. The individual source files can be compiled, and an execut-able program can be created, by invoking a command called MAKE or BUILD on the projectmenu.

> Note: See Appendix K for instructions on creating multi-file projects in Microsoft Visual C++ 6.0, Appendix L for instructions on creating multi-file projects in Borland C++ Builder 5, and appendix M for instructions on creating projects in Microsoft Visual C++ .NET.

If you are using a command line compiler, such as gcc, you can compile all source files andcreate an executable by passing the names of the source files to the compiler as command linearguments.

g++ -o bankprog bank.cpp loans.cpp checking.cpp savings.cpp

Figure J-1

File: 1: bank.cpp

Contains main and allprimary functions

File: 2: bank.h

Contains prototypesfor functionsin bank.cpp.

File: 3: loans.cpp

Contains all functionsfor processing loans

File: 4: loans.h

Contains prototypes for functionsin loans.h

File: 7: checking.cpp

Contains all functionsfor processing checkingaccounts

File: 8: checking.h

Contains prototypes for functionsin checking.cpp

File: 5: savings.cpp

Contains all functionsfor processing savingsaccounts

File: 6: savings.h

Contains prototypes for functionsin savings.cpp

GaddA4.book Page 1186 Monday, July 21, 2003 11:53 AM

Appendix J: Multi-Source File Programs 1187

This command will compile the four source code files and link them into an executable calledbankprog. Notice that the file listed after the -o is the name of the file where the executable willbe placed. The following .cpp files are the source code files, with the first one listed being the filethat contains the main function. Notice that the .h header files do not need to be listed becausethe contents of each one will automatically be added to the program when it is #included by thecorresponding .cpp file.

Global Variables in a Multi-File ProgramNormally, global variables can only be accessed in the file in which they are defined. For this rea-son, they are said to have file scope. However, the scope of a global variable defined in one file canbe extended to make it accessible to functions in another file by placing an extern declaration ofthe variable in the second file, as shown here.

extern int accountNum;

The extern declaration does not define another variable; it just permits access to a variabledefined in some other file.

Only true variables, not constant variables, should be declared to be extern.

const int maxCustomers = 35; // Don't declare this as extern.

This is because some compilers compile certain types of constant variables right into the code anddo not allocate space for them in memory, thereby making it impossible to access the constantvariable from another file. So how can functions in one file be allowed to use the value of a vari-able defined in another file while ensuring that they do not alter its value? The solution is to usethe const key word in conjunction with the extern declaration. Thus the variable is defined inthe original file, as shown here:

string nameOfBank = "First Federal Savings Bank";

In the other file that will be allowed to access that variable, the const key word is placed on theextern declaration, as shown here:

extern const string nameOfBank;

If you want to protect a global variable from any use outside the file in which it is defined,you can declare the variable to be static. This limits its scope to the file in which it is defined andhides its name from other files:

static float balance;

Figure J-2 shows some global variable declarations in the example banking program. Thevariables customer and accountNum are defined in bank.cpp. Since they are not declared to bestatic variables, their scope is extended to loans.cpp, savings.cpp, and checking.cpp, thethree files that contain an extern declaration of these variables. Even though the variables aredefined in bank.cpp, they may be accessed by any function in the three other files.

GaddA4.book Page 1187 Monday, July 21, 2003 11:53 AM

1188 Appendix J: Multi-Source File Programs

Figure J-2

checking.cpp savings.cpp

#include "checking.h" #include "savings.h" ... ... (other #include (other #include directives) directives)

extern char customer[]; extern char customer[]; extern int accountNum; extern int accountNum; static float balance; static float balance; static float checkAmnt; static int interest; static float deposit; static float deposit; static float withdrawl; function5() { function7() ... { } ... function6() } { function8() ... { } ... }

bank.cpp loans.cpp

#include "bank.h" #include "loans.h" #include "loans.h" ... #include "savings.h" (other #include #include "checking.h" directives) ... (other #include extern char customer[]; directives) extern int accountNum; static float loanAmount; char customer[35]; static int months; int accountNum; static float interest; static float payment; int main() { function3() ... { } ... function1() } { function4() ... { } ... function2() } { ... }

GaddA4.book Page 1188 Monday, July 21, 2003 11:53 AM

Appendix J: Multi-Source File Programs 1189

Figure J-2 includes examples of static global variables. These variables may not be accessedoutside the file they are defined in. The variable interest, for example, is defined as a static glo-bal in both loans.cpp and savings.cpp. This means each of these two files has its own variablenamed interest, which is not accessible outside the file it is defined in. The same is true of thevariables balance and deposit, defined in savings.cpp and checking.cpp.

In our example, the variable customer is defined to be an array of characters. It could havebeen defined to be a string object, but it was made a C-string instead to illustrate how anextern declaration handles arrays. Notice that in bank.cpp, the array is defined with a sizedeclarator

char customer[35];

but in the extern declarations found in the other files, it is referenced as

extern char customer[];

In a one-dimensional array, the size of the array is normally omitted from the extern declaration.In a multidimensional array, the size of the first dimension is usually omitted. For example, thetwo-dimensional array defined in one file as

int myArray[20][30];

would be made accessible to other files by placing the following declaration in them.

extern int myArray[][30];

Object-Oriented Multi-File Programs When creating object-oriented programs that define classes and create objects of those classes, itis common to store class declarations and member function definitions in separate files. Typically,program components are stored in the following fashion.

� The class declaration—The class declaration is stored in its own header file, which is called the class specification file. The name of the specification file is usually the same as the class, with a .h extension.

� Member function definitions—The member function definitions for the class are stored in a separate .cpp file, which is called the class implementation file. This file, which must #include the class specification file, usually has the same name as the class, with a .cpp extension.

� Client functions that use the class—Any files containing functions that create and use class objects should also #include the class specification file. They must then be linked with the compiled class implementation file.

These components are illustrated in the following example, which creates and uses an Addressclass. Notice how a single program is broken up into separate files. The .cpp files making up theprogram can be separately compiled and then linked to create the executable program.

GaddA4.book Page 1189 Monday, July 21, 2003 11:53 AM

1190 Appendix J: Multi-Source File Programs

//***********************************************************************// contents of address.h // This is the specification file that contains the class declaration.//***********************************************************************#include <string>using namespace std;

class Address{private:

string name;string street;string city;

public:Address(string name, string street, string city);Address( );void print();

};

//***********************************************************************// contents of address.cpp // This is the implementation file that contains the function definitions// for the class member functions. //***********************************************************************#include "address.h" #include <iostream>

Address::Address(string name_in, string street_in, string city_in) {

name = name_in;street = street_in;city = city_in;

}

Address::Address(){

name = street = city = "";}

void Address::print(){

cout << name << endl << street << endl << city << endl;

}

GaddA4.book Page 1190 Monday, July 21, 2003 11:53 AM

Appendix J: Multi-Source File Programs 1191

//***********************************************************************// contents of userfile.cpp // This file contains the client code that uses the Address class.//***********************************************************************#include "address.h"

int main( ){

// Create an address and print it.Address addr("John Doe", "123 Main Street", "Hometown, USA");addr.print();

// Other code could go here.return 0;

}

For additional information on creating multi-file programs using Microsoft Visual C++ andBorland Builder 5, see Appendices K, L, and M.

GaddA4.book Page 1191 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1192 Monday, July 21, 2003 11:53 AM

1193

Appendix KIntroduction to Microsoft Visual C++ 6.0

This appendix serves as a quick reference for performing the following operations using theMicrosoft Visual C++ integrated development environment (IDE):

� Starting a new project and entering code

� Saving a project to disk

� Compiling and executing a project

� Opening an existing project

� Creating multi-file projects

Starting a New ProjectThe first step in creating a program with Visual C++ is to start a project. A project is a group ofone or more files that make up a software application. (Even if your program consists of no morethan a single source code file, it still must belong to a project.)

To start a project:1. Launch Microsoft Visual C++. The IDE window opens, as shown in Figure K-1.

GaddA4.book Page 1193 Monday, July 21, 2003 11:53 AM

1194 Appendix K: Introduction to Microsoft Visual C++ 6.0

2. Click File on the menu bar. On the File menu, click New. You see the dialog box shown in Figure K-2.

3. All of the programs in this book are console programs, so click WIN32 Console Application in the list of project types.

Figure K-1

Figure K-2

GaddA4.book Page 1194 Monday, July 21, 2003 11:53 AM

Appendix K: Introduction to Microsoft Visual C++ 6.0 1195

4. Enter the name of the project (such as lab6, or program5) in the Project name text box. (Do not enter an extension.)

5. When you create a project, Visual C++ creates a folder where all the project files are normally stored. The folder is called the project folder and it has the same name as the project. The Location text box lets you type in or browse to a location on your system where the project folder will be created. If you do not want to keep the default location, click the ellipses (...) button to select a different one. Once you have selected a folder the dialog box should appear similar to Figure K-3.

6. Click the OK button. You now see the dialog shown in Figure K-4.

Figure K-3

Figure K-4

GaddA4.book Page 1195 Monday, July 21, 2003 11:53 AM

1196 Appendix K: Introduction to Microsoft Visual C++ 6.0

7. Make sure “An empty project” is selected and click the Finish button. You see the dialog box shown in Figure K-5.

8. Click the OK button. You return to the IDE, as shown in Figure K-6.

Figure K-5

Figure K-6

GaddA4.book Page 1196 Monday, July 21, 2003 11:53 AM

Appendix K: Introduction to Microsoft Visual C++ 6.0 1197

9. Now you must insert a new C++ source file into the project. Click Project on the menu bar. On the Project menu, click Add To Project, then click New… You see the dialog box shown in Figure K-7.

10. In the list of file types, click C++ Source File.

11. In the File name text box, enter the name of the source file. (This can be the same as the project name, if you wish.) Be sure to type the .cpp extension. Your screen should look simi-lar to Figure K-8.

12. Click the OK button. You will return to the IDE. The right pane is now a text editor. This is where you type your C++ source code, as shown in Figure K-9.

Figure K-7

Figure K-8

GaddA4.book Page 1197 Monday, July 21, 2003 11:53 AM

1198 Appendix K: Introduction to Microsoft Visual C++ 6.0

Saving Your Project to DiskIt is important to periodically save your work. To do so, click File on the menu bar, then clickSave Workspace on the File menu.

Opening an Existing ProjectTo open an existing project, click File on the menu bar, then click on Open Workspace… Use theresulting dialog box to browse to the location of your project. When you have located yourproject, double-click it.

Compiling and ExecutingOnce you have entered a program’s source code, you may compile and execute it by any of the fol-lowing methods:

� By clicking the button

� By pressing Ctrl+F5

� By clicking Build on the menu bar, and then clicking Execute.

Figure K-9

GaddA4.book Page 1198 Monday, July 21, 2003 11:53 AM

Appendix K: Introduction to Microsoft Visual C++ 6.0 1199

The window at the bottom of the screen shows status messages as the program is compiled. Errormessages are also displayed there. If you see an error message, double-click it and the editor willmove the text cursor to the line of code where the error was encountered.

For example, look at the program in Figure K-10. The first cout statement is missing a semi-colon. When you double-click the error message, the text cursor moves to the line with the error.(Actually, in this case the cursor appears on the line after the statement with the missing semico-lon. The compiler did not detect that the semicolon was missing until it encountered the begin-ning of the next line. Finding errors is not always straightforward.)

If the program compiles successfully, an MS-DOS window appears and the program runs. This isillustrated in Figure K-11.

Creating a Multi-File ProjectMany of your programs consist of more than one file. For example, consider the followingprogram:

// Filename: RectData.cpp// This program uses multiple files#include <iostream>#include "rectang.h" // contains Rectangle class declarationusing namespace std;

Figure K-10

GaddA4.book Page 1199 Monday, July 21, 2003 11:53 AM

1200 Appendix K: Introduction to Microsoft Visual C++ 6.0

// Don't forget to link this program with rectang.cpp!int main(){

Rectangle box;float wide, long;

cout << "This program will calculate the area of a\n";cout << "rectangle. What is the width? ";cin >> wide;cout << "What is the length? ";cin >> long;box.setData(Wide, Long);box.calcArea();cout << "Here rectangle's data:\n";cout << "Width: " << box.getWidth() << endl;cout << "Length: " << box.getLength() << endl;cout << "Area: " << box.getArea() << endl;return 0;

}

This program relies on two other files: rectang.h and rectang.cpp. Before compiling this pro-gram, Rectang.h and Rectang.cpp must be added to the project. The steps listed here show youhow to set the project up with all three of the existing files as members.

1. Start a new project by following steps 1 through 8 under the section Starting a New Project, at the beginning of this appendix. Name the project RectData.

2. Insert the main C++ source file into the project. Click Project on the menu bar. On the Project menu, click Add To Project, then click Files… You see the Insert Files into Project dialog box. Use the dialog box to find the file RectData.cpp on the student disk, under the Appendix K folder. When you locate the file, click it and then click the OK button. The file RectData.cpp is now a member of the project.

Figure K-11

GaddA4.book Page 1200 Monday, July 21, 2003 11:53 AM

Appendix K: Introduction to Microsoft Visual C++ 6.0 1201

3. Now insert the Rectang.cpp source file into the project. Click Project on the menu bar. On the Project menu, click Add To Project, then click Files… Again, you see the Insert Files into Project dialog box. Use the dialog box to find the file Rectang.cpp on the student disk. When you locate the file, click it and then click the OK button. The file Rectang.cpp is now a member of the project.

4. Now insert the Rectang.h header file into the project. Click Project on the menu bar. On the Project menu, click Add To Project, then click Files… As before, you see the Insert Files into Project dialog box. Use the dialog box to find the file Rectang.h on the student disk. When you locate the file, click it and then click the OK button. The file Rectang.h is now a mem-ber of the project.

5. At this point, RectData.cpp, Rectang.cpp, and Rectang.h are members of the project. The left pane of the IDE, which is called the workspace window, is shown in Figure K-12. This window allows you to navigate among all the files in the project.

The two tabs at the bottom of the workspace window allow you to switch between Class View andFile View. Click on the File View tab. You should see a display similar to Figure K-13.

6. Click the small + sign that appears next to RectData files. The display expands, as shown in Figure K-14, to show folders labeled Source Files, Header Files, and Resource Files. These folders organize the names of the files that are members of the project.

Figure K-12

Figure K-13

Figure K-14

GaddA4.book Page 1201 Monday, July 21, 2003 11:53 AM

1202 Appendix K: Introduction to Microsoft Visual C++ 6.0

7. Notice that the Source Files and Header Files folders have small + signs next to them. This indicates the folders hold filenames. Click on the small + sign next to the Source Files and Header Files folders. The filenames RectData.cpp, Rectang.cpp, and Rectang.h are listed, as shown in Figure K-15.

8. Double-click on the name RectData.cpp. The file is displayed in the editor. (You may display any of the files in the editor by double-clicking its name.)

9. You may compile and execute the project by following the steps listed under the section Com-piling and Executing.

Creating a New Multi-File ProjectIf you are creating a new multi-file project (not from existing files), follow steps 1 through 12under the section Starting a New Project. Type the code for the main source file into the editor.When you are ready to create another source file (such as a header file for a class declaration, or a.cpp file to contain class member function definitions), follow these steps.

1. Click Project on the menu bar, click Add to Project, then click New.

2. In the New dialog box, click C++ Source File if you are creating a new .cpp file, or C/C++ Header File if you are creating a new header file.

3. In the File Name text box, enter the name of the file. Be sure to include the proper extension.

4. Click the OK button. You will return to the text editor. Enter the code for the new file.

5. Repeat the steps above for each new file you wish to add to the project.

Removing a File from a ProjectTo remove a file from a project, simply select the file’s name in the project browser window andpress the Delete key. This operation removes the file from the project, but does not delete it fromthe disk.

Figure K-15

GaddA4.book Page 1202 Monday, July 21, 2003 11:53 AM

Appendix K: Introduction to Microsoft Visual C++ 6.0 1203

Project DirectoriesWhen you create a project, Visual C++ allows you to specify a directory as a location for savingyour project files. Within the directory that you specify, Visual C++ will create a folder with thesame name as your project, and will save your files there. This folder, which we call the projectdirectory, will hold the source files for your project, along with other files that Visual C++ createsto help it keep track of your project files. For example, if you specify the location cscprogs andthe name of your project is project1, then the project directory created by Visual C++ will be

cscprogs\project1

Within this project directory, Visual C++ will create yet another folder, named Debug, and willstore your executable code in there. The executable code has the same name as the project, but hasa .exe extension.

When you execute your program from within the development environment, the programwill look for input files in the project directory unless a full pathname is given. Similarly, outputfiles created by the program will be stored in the project directory unless a full pathname is speci-fied. To avoid having to specify full pathnames of files, you should store input files in the projectdirectory before you run your program.

For example, to have your program open a file named myfile.dat, you simply write

fstream inFile("myfile.dat", ios::in);

if the file is stored in the project directory. If the file is in a directory A:\mydata on the floppydrive A:, however, you must write

fstream inFile("A:\\mydata\\myfile.dat", ios::in);

Doubling up on the backspace character \ is only necessary if the file name is being hard-codedinto your program. If the file name is being entered in at the keyboard at the program’s request,just type in

A:\mydata\myfile.dat

in response to the program prompt. Once the project executable has been created, it is possible to exit the Visual C++ environ-

ment, change directory to the Debug folder, and execute the program from the MSDOS commandline. When you execute the program this way, the program expects files whose full pathnames arenot given to be in the current directory. The current directory is the directory from which you givethe command to run the program at the DOS command line: It is usually the directory contain-ing the executable code. If you plan to execute program this way, you should store your input filesin the same directory as the program executable.

GaddA4.book Page 1203 Monday, July 21, 2003 11:53 AM

1204 Appendix K: Introduction to Microsoft Visual C++ 6.0

Correcting the getline bugThe getline function in Microsoft Visual C++ 6.0 does not work correctly. The source coderesponsible for the error is in the <string> include file, and can be corrected after you haveinstalled Visual C++ on your system. You only need to apply the correction once each time youinstall or reinstall Visual C++.

To apply the fix, carefully follow these steps:

1. Start up Visual C++, select File from the menu, then New…, and then from the resulting New dialog box, select the Files tab.

2. Select C++ Source Files and then click OK. You should now be in an edit window editing an empty file.

3. At the top of the edit window, type the include directive

#include <string>

and then using the mouse, right click on the word string in that directive. A pop up menu appears: select the option Open Document <string>.

4. You now need to find the line of code that has to be fixed. This is best done using the Find command in the Edit menu. Select Edit on the main menu, then Find. In the resulting dialog box, carefully type in the phrase

_Tr::eq((

in the Find What text box and then click on Find Next.

5. You should see the block of code

else if (_Tr::eq((_E)_C, _D)){_Chg = true;_I.rdbuf()->snextc();break; }

Modify it to

else if (_Tr::eq((_E)_C, _D)) {_Chg = true; // Comment out the bad code. // _I.rdbuf()->snextc(); // Add the following line of replacement code.

_I.rdbuf()->sbumpc(); break; }

then save and close the <string> header file. Close the other file that you were editing that con-tains the #include <string> directive.

The getline function should now work correctly.

GaddA4.book Page 1204 Monday, July 21, 2003 11:53 AM

1205

Appendix LIntroduction to Borland C++ Builder 5.0

This appendix serves as a quick reference for performing the following operations using theBorland C++ Builder integrated development environment (IDE):

� Starting a new project and entering code

� Saving a project to disk

� Compiling and executing a project

� Opening an existing project

� Creating multi-file projects

Starting a New ProjectThe first step in creating a program with Borland C++ Builder is to start a project. A project is agroup of one or more files that make up a software application. (Even if your program consists ofno more than a single source code file, it still must belong to a project.)

To start a project:

1. Launch Borland C++ Builder. The IDE windows open on the desktop, similar to what is shown in Figure L-1.

GaddA4.book Page 1205 Monday, July 21, 2003 11:53 AM

1206 Appendix L: Introduction to Borland C++ Builder 5.0

2. When C++ Builder starts, it automatically begins an empty project. This project is usually named Project1. This project is not set up properly for the programs in this book, however, so you will begin a new project. Click File on the menu bar. On the File menu, click New. You see the dialog box shown in Figure L-2. (Make sure the New tab is selected.)

Figure L-1

Figure L-2

GaddA4.book Page 1206 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1207

3. All of the programs in this book are console programs, so click Console Wizard, then click the OK button. The dialog box shown in Figure L-3 is displayed.

4. Make sure C++ and Console Application are selected. No other options should be selected. Click the OK button. A dialog box appears asking “Save changes to Project1?” (The name you see may be different from Project1.) Because the default project is empty, click the No button. Your screen now looks similar to Figure L-4.

Figure L-3

Figure L-4

GaddA4.book Page 1207 Monday, July 21, 2003 11:53 AM

1208 Appendix L: Introduction to Borland C++ Builder 5.0

5. The right-most pane in the window shown above is the text editor. C++ Builder automati-cally creates a program “skeleton” for you. The skeleton contains some preprocessor direc-tives and an empty function main. You can modify the code skeleton, or erase it and write your own program from scratch. For example, Figure L-5 shows a simple program that has been written in the editor after the default program skeleton has been erased.

Saving Your Project to DiskIt is important to periodically save your work. To save your project for the first time, click File onthe menu bar, and then click Save Project As… on the File menu. A Save As dialog box appears forthe C++ source file. The source file’s default name is Unit1.cpp. Click the OK button if you wantto keep this name. If you wish to save the source file under a different name, enter the new name,and click the OK button. Next, a Save As dialog box appears for the project file. A default name,such as Project2.bpr, will appear as the project file’s name. Click the OK button if you want tokeep this name. If you wish to save the project file under a different name, enter the new name,and click the OK button.

After you have saved the project the first time, you may save it subsequent times by clickingFile on the menu bar, then clicking Save All.

Opening an Existing ProjectTo open an existing project, click File on the menu bar, then click on Open Project… Use theresulting dialog box to browse to the location of your project file. When you have located yourproject file, double-click it.

Figure L-5

GaddA4.book Page 1208 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1209

Compiling and ExecutingOnce you have entered a program’s source code, you may compile and execute it by any of the fol-lowing methods:

� by clicking the button

� by pressing F9

� by clicking Run on the menu bar, and then clicking Run.

A window at the bottom of the editor pane appears if errors are found in your program. Double-click an error message in the window, and the editor will highlight the line of code where the errorwas encountered.

For example, look at the program in Figure L-6. The cout statement is missing a semicolon.By double-clicking the error message, the text cursor is positioned on the line with the error.(Actually, in this case the cursor appears on the line after the statement with the missing semico-lon. The compiler did not detect that the semicolon was missing until it encountered the begin-ning of the next line. Finding errors is not always straightforward.)

If the program compiles successfully, an MS-DOS window appears and the program runs. This isillustrated in Figure L-7.

> Note: The program shown in the example above has a cin.get() statement as the last statement in the program. The statement causes the program to pause until the user presses the Enter key. The statement is in the program because the MS-DOS window automatically closes as soon as the program is finished. If the program above did not have the cin.get() statement, it would quickly flash the message "This is a simple program" on the screen, and the MS-DOS window would suddenly close.

Figure L-6

GaddA4.book Page 1209 Monday, July 21, 2003 11:53 AM

1210 Appendix L: Introduction to Borland C++ Builder 5.0

Sometimes a single cin.get() statement will not pause the screen. (This is because a prevouscin statement has left a newline character in the keyboard buffer.) A better way of pausing thescreen is to include the conio.h header file, and use the getch() function at the end of the pro-gram. This is demonstrated in the next example.

Creating a Multi-File ProjectMany of your programs consist of more than one file. For example, consider the followingprogram:

// This program demostrates a simple class#include <conio.h> // For the getch() function#include <iostream>#include "rectang.h" // Contains Rectangle class declarationusing namespace std;

// Don't forget to link this program with rectang.cpp!

int main(){

Rectangle box;float wide, long;

cout << "This program will calculate the area of a\n";cout << "rectangle. What is the width? ";cin >> wide;cout << "What is the length? ";cin >> long;

Figure L-7

GaddA4.book Page 1210 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1211

box.setData(wide, long);box.calcArea();cout << "Here rectangle's data:\n";cout << "Width: " << box.getWidth() << endl;cout << "Length: " << box.getLength() << endl;cout << "Area: " << box.getArea() << endl;getch();return 0;

}

This program relies on two other files: Rectang.h and Rectang.cpp. Before compiling this pro-gram, rectang.h and rectang.cpp must be added to the project. The steps listed below showyou how to set the project up with all three files as members.

1. Start a new project by following steps 1 through 5 under the section Starting a New Project, at the beginning of this appendix.

2. Enter the main C++ source code (shown above) into the text editor. Your editor window will look similar to Figure L-8.

3. Now insert the Rectang.cpp source file into the project. Click Project on the menu bar. On the Project menu, then click Add To Project… The Add to Project dialog box. Use the dialog box to find the file Rectang.cpp in the Appendix L folder on the student disk. When you locate the file, click it and then click the OK button. The file Rectang.cpp is now a member of the project. Your editor window now looks similar to Figure L-9.

Figure L-8

GaddA4.book Page 1211 Monday, July 21, 2003 11:53 AM

1212 Appendix L: Introduction to Borland C++ Builder 5.0

5. At this point, the main source file and Rectang.cpp are members of the project. At the top of the editor window are tabs for the two files. Click on either tab to bring the file’s contents into view.

The left pane of the editor window, which is called the Class Explorer, is used to bring class decla-rations into the editor window. In the figure shown above, a folder titled Project2 – Classesappears. (Your screen will look similar, but the project name may be different.) Click the small +sign to expand the view. The window looks similar to Figure L-10.

6. Click the small + sign next to Rectangle. The view expands further to show entries for all the members of the Rectangle class. Your window should be similar to Figure L-11.

Figure L-9

Figure L-10

GaddA4.book Page 1212 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1213

7. By double-clicking any of the Rectangle class’s member names in the Class Explorer window, you bring the source file containing the member’s declaration into the editor. For example, by double-clicking the area member, the Rectang.h file is brought into the editor, as shown in Figure L-12.

8. You may compile and execute the project by following the steps listed under the section Com-piling and Executing.

Figure L-11

Figure L-12

GaddA4.book Page 1213 Monday, July 21, 2003 11:53 AM

1214 Appendix L: Introduction to Borland C++ Builder 5.0

Removing a File from a ProjectTo remove a file from a project, click Project on the menu bar, then click Remove from Project…The Remove from Project dialog box appears, as shown in Figure L-13.

Select the name of the file you wish to remove from the project and click the OK button. The filewill be removed from the project. (It will not be erased from the disk, however.)

Opening and Running an Existing Program1. Launch Borland C++ Builder. The IDE windows open on the desktop, similar to what is

shown in Figure L-14.

Figure L-13

Figure L-14

GaddA4.book Page 1214 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1215

2. When C++ Builder starts, it automatically begins an empty project. This project is usually named Project1. This project is not set up properly for the programs in this book, however, so you will begin a new project. Click File on the menu bar. On the File menu, click New. You see the dialog box shown in Figure L-15. (Make sure the New tab is selected.)

3. All of the programs in this book are console programs, so click Console Wizard, then click the OK button. The dialog box shown in Figure L-16 is displayed.

4. Make sure C++ and Console Application are selected. Then, click the Specify project source checkbox. At this point, you may either type the name and location of the file in the textbox, or click the button to browse for the file. Figure L-17 shows an example of the dialog box where the file C:\Programs\Chap2\pr2-1.cpp has been selected.

Figure L-15

Figure L-16

GaddA4.book Page 1215 Monday, July 21, 2003 11:53 AM

1216 Appendix L: Introduction to Borland C++ Builder 5.0

5. Click the OK button. Your screen now looks similar to Figure L-18. The program you selected is loaded into the text editor.

6. You may compile and execute the program by any of the following methods:

� by clicking the button

� by pressing F9

� by clicking Run on the menu bar, and then clicking Run.

Figure L-17

Figure L-18

GaddA4.book Page 1216 Monday, July 21, 2003 11:53 AM

Appendix L: Introduction to Borland C++ Builder 5.0 1217

A window at the bottom of the editor pane appears if errors are found in your program. Double-click an error message in the window, and the editor will highlight the line of code where the errorwas encountered.

If the program compiles successfully, an MS-DOS window appears and the program runs.

Where Files are CreatedWhen you save a new project, you normally save all of the files associated with that project in thesame folder. (See the Saving Your Project to Disk section.) This folder is known as the project folder.

For example, suppose we’ve created a project named Lab5, and saved it in the folderC:\MyProjects\Lab5. All of the C++ source files that you have created for this project, as well asthe project file that ends with the extension .bpr, will be stored in that folder.

It’s important to know the location of the project folder when writing code that opens filesfor input or output. When running a program from the C++ Builder IDE, the project folder is thedefault location for all data files. For example, suppose our Lab5 project creates a file with the fol-lowing code:

ofstream outputFile("names.txt");

Because we have not specified a path with the file name, the file will be created in theC:\MyProjects\Lab5 project folder. Similarly, if our program attempts to open an existing filefor reading, it will look in the project folder by default. For example, suppose our Lab5 programattempts to open a file with the following statement:

ifstream inputFile("names.txt");

Because we have not specified a path, the program will look for the file in the project folder,C:\MyProjects\Lab5.

If we want to open a file in a location other than the project folder, we must provide a path aswell as a file name. For example, the following statement opens a file named data.txt in theC:\Data folder.

ofstream outputFile("C:\\Data\\Data.txt");

Notice that we’ve used two backslashes in the path where you normally use only one. Remember,in a literal string, the compiler interprets the backslash character as the beginning of an escapesequence. In order to represent a backslash as a character in a literal string, you must use twobackslashes.

Here’s another example:

ifstream inputFile("A:\\names.txt");

This statement attempts to open the names.txt file in the root folder of drive A.

GaddA4.book Page 1217 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1218 Monday, July 21, 2003 11:53 AM

1219

Appendix MIntroduction to Microsoft Visual C++ .NET

This appendix serves as a quick reference for performing the following operations using theMicrosoft Visual C++ .NET integrated development environment (IDE):

� Starting a new project and entering code

� Saving a project to disk

� Compiling and executing a project

� Opening an existing project

� Creating multi-file projects

Starting a New projectThe first step in creating a program with Visual C++ .NET is to start a project. A project is a groupof one or more files that make up a software application. (Even if your program consists of nomore than a single source code file, it still must belong to a project.)

To start a project:1. Launch Microsoft .NET. The IDE window opens and allows for a number of options, which

are shown in Figure M-1. Click the New Project button in the main window as shown in Fig-ure M-1. (If you do not see the New Project button, click File on the menu bar, then click New, then click Project.)

GaddA4.book Page 1219 Monday, July 21, 2003 11:53 AM

1220 Appendix M: Introduction to Microsoft Visual C++ .NET

2. The New Projects dialog box appears, as shown in Figure M-2. Under Project Types (the leftpane) select Visual C++ Projects. Under Templates (the right pane), scroll down to andselect WIN 32 Project.

Figure M-1

Figure M-2

Menu bar

New Project Button

GaddA4.book Page 1220 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1221

3. When you create a project, Visual C++ .NET creates a folder where all the project files are normally stored. The folder is called the project folder and it has the same name as the project. The Location text box lets you type in or browse to a location on your system where the project folder will be created. If you do not want to keep the default location, click the Browse... button to select a different one. Once you have selected a folder the dialog box should appear similar to Figure K-3.

4. Enter the name of the project (such as Lab6, or Program5) in the Name text box. (Do not enter an extension for the filename.) Figure M-3 shows an example. Click the OK button if you are satisfied with the name and directory for the project. The Win32 Application Wizard starts and you should see the dialog box shown in Figure M-4.

Figure M-3

Figure M-4

Application Settings option

GaddA4.book Page 1221 Monday, July 21, 2003 11:53 AM

1222 Appendix M: Introduction to Microsoft Visual C++ .NET

5. Click the Application Settings options, which is shown in Figure M-4. The dialog box should now appear as shown in Figure M-5.

6. Click the Console Application button and click the Empty Project check box. The dialog box should now appear as shown in Figure M-6.

7. Click the Finish button to build the project. This will take you to the main screen with an empty project as shown in Figure M-7.

Figure M-5

Figure M-6

GaddA4.book Page 1222 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1223

8. Now you should insert a new C++ source file into the project. Click Project on the menu bar and then choose Add New Item. You should see the Add New Item dialog box shown in Fig-ure M-8. Click the C++ File icon in the templates pane. In the name box, enter the name of the source file. (This can be the same as the project name, if you wish.) Figure M-9 shows an example of the dialog box with this step completed.

Figure M-7

Figure M-8

GaddA4.book Page 1223 Monday, July 21, 2003 11:53 AM

1224 Appendix M: Introduction to Microsoft Visual C++ .NET

9. Click the Open button to create the C++ file. This creates an empty source file and adds it to the project. You should see something similar to Figure M-10. Note that above the text editor is a tab showing the name of the file that is currently open. To the right is a window showing the files that are in the project. This is called the Solution Explorer window. Figure M-11 shows the screen after a C++ program has been entered into the editor.

Figure M-9

Figure M-10

Name of file currentlyopen in the editor

Solution Explorer windowshows the files inthis project

GaddA4.book Page 1224 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1225

Saving Your Project to DiskIt is important to periodically save your work. To do so, click File on the menu bar, then click SaveAll on the File menu.

Compiling and ExecutingOnce you have entered a program’s source code, you may compile and execute it by any of the fol-lowing methods:

� Click the Debug menu item and choosing Start without Debugging as shown in Figure M-12.

� by pressing Ctrl+F5

Figure M-11

GaddA4.book Page 1225 Monday, July 21, 2003 11:53 AM

1226 Appendix M: Introduction to Microsoft Visual C++ .NET

After performing one of these steps, if you see the dialog box in Figure M-13, click the Yes button.

The Output window shown in Figure M-14 appears at the bottom of the screen. This window showsstatus messages as the program is compiled. Error messages are also displayed in this same area.

When compiling a program you will see the dialog box in Figure M-15 if the program hassyntax errors. Click the No button. Next you will see one or more error messages displayed at thebottom of the screen, as shown in Figure M-16.

Figure M-12

Figure M-13

Figure M-14

Figure M-15

GaddA4.book Page 1226 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1227

If you see an error message, double-click it and the editor will move the text cursor to theline of code where the error was encountered. For example, look at the program in Figure M-17.The first cout statement is missing a semi-colon. By double-clicking the error message, the textcursor is positioned on the line with the error. (Actually, in this case the cursor appears on theline after the statement with the missing semicolon. The compiler did not detect that the semi-colon was missing until it encountered the beginning of the next line. Finding errors is notalways straightforward.)

Figure M-16

Figure M-17

Double-click this error message

GaddA4.book Page 1227 Monday, July 21, 2003 11:53 AM

1228 Appendix M: Introduction to Microsoft Visual C++ .NET

If the program compiles successfully, an MS DOS window appears and the program runs.This is illustrated in Figure M-18.

Opening an Existing ProjectTo open an existing project, click File on the menu bar, then click Open Solution. Use the result-ing dialog box to browse to the folder containing your project. In that folder you should see asolution file. This file has the same name that you gave the project, and the .sln extension. Dou-ble-click this file to open the project.

> Note: If the source file does not open in the editor, double-click the name of the file in the Solutions Explorer window.

Creating a Multi-File ProjectMany of your programs consist of more than one file. For example, consider the followingprogram, which is stored in the Appendix M folder on the student disk, under the nameRectangleData.cpp:

// This program uses the Rectangle class's specification// and implementation files.#include <iostream>#include "Rectangle.h" // Contains the class declaration.using namespace std;

int main(){

Rectangle box; // Define an instance of the class.float rectWidth, // Local variable for width.

rectLength; // Local variable for length.

Figure M-18

GaddA4.book Page 1228 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1229

// Get the rectangle's width and length from the user.cout << "This program will calculate the area of a\n";cout << "rectangle. What is the width? ";cin >> rectWidth;cout << "What is the length? ";cin >> rectLength;

if (!box.setWidth(rectWidth)) // Store the width.cout << "Invalid value for width.\n";

else if (!box.setLength(rectLength)) // Store the length.cout << "Invalid value for length.\n";

else{

// Display the rectangle's data.cout << "Here is the rectangle's data:\n";cout << "Width: " << box.getWidth() << endl;cout << "Length: " << box.getLength() << endl;cout << "Area: " << box.getArea() << endl;

}return 0;

}

This program relies on two other files: Rectangle.h and Rectang.cpp. Before compiling thisprogram, Rectangle.h and Rectangle.cpp must be added to the project. The following stepsshow you how to set the project up with all three of the existing files as members.

1. Start a new project by following steps 1–9 under the section Starting a New Project, at the beginning of this appendix. Name the project RectangleData.

2. Now you will insert the main C++ source file into the project. Click Project on the menu bar. On the Project menu, click Add Existing Item. Then insert the student disk and use the browse feature to locate the file RectangleData.cpp in the Appendix M folder on the disk. When you locate the file, click it and click the open button (or just double click it.)

3. Now you will insert the Rectangle.cpp source file into the project. Click Project on the menu bar. On the Project menu, click Add Existing Item. Then use the browse feature to locate the file Rectangle.cpp in the Appendix M folder on the student disk. When you locate the file, click it and click the Open button. The file Rectangle.cpp is now a member of your project.

4. Now you will insert the Rectangle.h header file into the project. Repeat the process in step 3 to locate and insert the Rectangle.h file. The Rectangle.h file is now a member of the project.

5. At this point, RectangleData.cpp, Rectangle.cpp, and Rectangle.h are members of the project. You can use the Solution Explorer window to navigate among all the files in the project. Notice the two tabs at the bottom of the Solution Explorer window, as shown in Figure M-19. One is the Solution Explorer tab and the other is the Class View tab. These tabs allow you to switch between a file-oriented view of your project (the Solution Explorer tab) and a class-oriented view of your projected (the Class View tab). Make sure the Solution Explorer tab is selected.

GaddA4.book Page 1229 Monday, July 21, 2003 11:53 AM

1230 Appendix M: Introduction to Microsoft Visual C++ .NET

6. You can expand or contract items in the view by clicking the – (minus) sign that appears beside the file folders (a plus sign if the folders are closed). You should see the three files you added to the project shown by default. Double-click on the name RectangleData.cpp. The file is dis-played in the editor. (You may display any of these files in the editor by double-clicking their names.)

Notice that in Figure M-20 there are tabs with the names of each file in the project just above the editor. You may click any of these tabs to rapidly switch between files in a multi-file project.

Figure M-19

Figure M-20

Solution Explorer tab Class View tab

File tabs

GaddA4.book Page 1230 Monday, July 21, 2003 11:53 AM

Appendix M: Introduction to Microsoft Visual C++ .NET 1231

Creating a New Multi-File ProjectIf you are creating a new multi-file project (not from existing files), follow steps 1 through 9under the section Starting a New Project. Type the code for the main source file into the editor.When you are ready to create another source file (such as the header file for a class declaration, ora .cpp file to contain class member function definitions), follow these steps.

1. Click Project on the menu bar, click Add New Item.

2. In the Add New Item box, click the C++ File (.cpp) icon if you are creating a new .cpp file or Header File (.h) if you are creating a new header file.

3. In the File Name text box, enter the name of the file. Extensions are automatically included for the various types.

4. Click the Open button. You will return to the text editor. Enter the code for the new file.

Repeat these steps for each new file you wish to add to the project.

Removing a File from a ProjectTo remove a file from a project, simply select the file’s name in the solution explorer window andpress the Delete key. This operation removes the file from the project, but does not delete it fromthe disk.

Where Files are CreatedWhen you create a new project, Visual C++ .NET creates a project folder with the same name asthe project. This is where all of the files associated with the project are normally stored. You canspecify the location of the folder when you create the project. (See step 3 of the Starting a NewProject section.)

For example, suppose we’ve created a project named Lab5, and its project folder is atC:\MyProjects\Lab5. All of the C++ source files that you have created for this project will bestored in that folder. In addition, Visual C++ .NET will create another folder named Debug,under the C:\MyProjects\Lab5 folder. The Debug folder will contain the project’s executable fileand its object file(s).

It’s important to know the location of the project folder when writing code that opens filesfor input or output. When running a program from the Visual C++ IDE, the project folder is thedefault location for all data files. For example, suppose our Lab5 project creates a file with the fol-lowing code:

ofstream outputFile("names.txt");

Because we have not specified a path with the file name, the file will be created in theC:\MyProjects\Lab5 project folder. Similarly, if our program attempts to open an existing file

GaddA4.book Page 1231 Monday, July 21, 2003 11:53 AM

1232 Appendix M: Introduction to Microsoft Visual C++ .NET

for reading, it will look in the project folder by default. For example, suppose our Lab5 programattempts to open a file with the following statement:

ifstream inputFile("names.txt");

Because we have not specified a path, the program will look for the file in the project folder,C:\MyProjects\Lab5.

If we want to open a file in a location other than the project folder, we must provide a path aswell as a file name. For example, the following statement opens a file named data.txt in theC:\Data folder.

ofstream outputFile("C:\\Data\\Data.txt");

Notice that we’ve used two backslashes in the path where you normally use only one. Remember,in a literal string, the compiler interprets the backslash character as the beginning of an escapesequence. In order to represent a backslash as a character in a literal string, you must use twobackslashes.

Here’s another example:

ifstream inputFile("A:\\names.txt");

This statement attempts to open the names.txt file in the root folder of drive A.

GaddA4.book Page 1232 Monday, July 21, 2003 11:53 AM

1233

Appendix NAn Object-Oriented System Development Primer

Before discussing specific object-oriented development activities, we must understand the basicobject-oriented concepts. In addition, we must be able to differentiate the object-orientedapproach from the procedural approach.

Procedural Programming vs. Object-Oriented ProgrammingThere are primarily two methods of programming in use today: procedural, and object-oriented.The earliest programming languages were procedural. This means that a program is made of oneor more procedures. A procedure is a set of programming language statements that are executed bythe computer, one after the other. The statements might gather input from the user, manipulatedata stored in the computer’s memory, and perform calculations or any other operation necessaryto complete its task. For example, suppose we want the computer to calculate someone’s grosspay. Here is a list of things the computer should do:

1. Display a message on the screen asking “How many hours did you work?”

2. Allow the user to enter the number of hours worked. Once the user enters a number, store it in memory.

3. Display a message on the screen asking “How much do you get paid per hour?”

4. Allow the user to enter their hourly pay rate. Once the user enters a number, store it in memory.

5. Once both the number of hours worked, and the hourly pay rate are entered, multiply the two numbers and store the result in memory.

6. Display a message on the screen that tells the amount of money earned. The messagemust include the result of the calculation performed in step 5.

If the algorithm’s six steps are performed in order, one after the other, it will succeed in calculat-ing and displaying the user’s gross pay.

GaddA4.book Page 1233 Monday, July 21, 2003 11:53 AM

1234 Appendix N: An Object-Oriented System Development Primer

Procedural programming was the standard when users were interacting with text-based com-puter terminals. For example, Figure N-1 illustrates the screen of an older MS-DOS computerrunning a program that performs the pay-calculating algorithm. The user has entered the num-bers shown in bold.

In text-based environments using procedural programs, the user responds to the program. Mod-ern operating systems, however, such as Windows 2000 and Windows XP use a graphical userinterface, or GUI (pronounced “gooey”). Although GUIs have made programs friendlier and eas-ier to interact with, they have not simplified the task of programming. GUIs make it necessary forthe programmer to create a variety of on-screen elements such as windows, dialog boxes, buttons,menus, and other items. Furthermore, the programmer must write statements that handle theuser’s interactions with these on-screen elements, in any order they might occur. No longer doesthe user respond to the program, but the program responds to the user.

This has helped influence the shift from procedural programming to object-oriented pro-gramming. Whereas procedural programming is centered on creating procedures, object-orientedprogramming is centered on creating objects. An object is a programming entity that contains dataand actions. The data contained in an object is known as the object’s attributes. The actions, orbehaviors, that an object performs are known as the object’s methods. The object is, conceptually, aself-contained unit consisting of data (attributes) and actions (methods).

Object-oriented programming (OOP) has revolutionized GUI software development. Forinstance, in a GUI environment, the pay-calculating program might appear as the window shownin Figure N-2.

How many hours did you work? 10How much are you paid per hour? 15You have earned $150.00C>_

Figure N-1

Figure N-2

GaddA4.book Page 1234 Monday, July 21, 2003 11:53 AM

Appendix N: An Object-Oriented System Development Primer 1235

This window can be thought of as an object. It contains other objects as well, such as text inputboxes, and command buttons. Each object has attributes that determine the object’s appearance.For example, look at the command buttons. One has the caption “Calculate Gross Pay” and theother reads “Close”. These captions, as well as the buttons’ sizes and positions, are attributes of thecommand button objects. Objects can also hold data that has been entered by the user. For exam-ple, one of the text input boxes allows the user to enter the number of hours worked. When thisdata is entered, it is stored as an attribute of the text input box.

The objects also have actions, or methods. For example, when the user clicks the “CalculateGross Pay” button with the mouse, one would expect the program to display the amount of grosspay. The “Calculate Gross Pay” button performs this action.

The Benefits of OOP in Non-GUI EnvironmentsThe complexity of GUI software development was not the first difficult challenge that proceduralprogrammers faced. Long before Windows and other GUIs, programmers were wrestling with theproblems of code/data separation. In procedural programming, there is a distinct separationbetween data and program code. Data is kept in variables of specific data types, as well as program-mer-defined data structures. The program code passes the data to modules that are designed toreceive and manipulate it. But, what happens if the format of the data is altered? Quite often, a pro-gram’s specifications change, resulting in redesigned data structures, changed data types, and addi-tional variables being added to the program. When the structure of the data changes, the modulesthat operate on the data must also be changed to accept the new format. This results in added workfor programmers and a greater opportunity for bugs to appear in the code.

OOP addresses the problem of code/data separation through encapsulation and data hiding.Encapsulation refers to the combining of data and procedures into a single object. Data hidingrefers to an object’s ability to hide its data from code that is outside the object. When an object’sdata is hidden, it can only be accessed through the object’s procedures, so an object’s proceduresprovide an interface for programming statements outside the object to access the object’s data.This means that programming statements outside the object do not need to know about the typeor internal structure of an object’s data. They only need to know how to interact with the object’sprocedures. When a programmer changes the type or structure of an object’s internal data, he orshe also modifies the object’s procedures that provide the interface to the data.

Component ReusabilityAnother trend in software development that has encouraged the use of OOP is component reus-ability. A component is a software object that performs a specific, well-defined operation or thatprovides a particular service. The component is not a stand-alone program, but can be used byprograms that need the component’s service. For example, Sharon is a programmer who hasdeveloped a component for rendering 3D images. She is a math whiz and knows a lot about com-puter graphics, so her component is coded to perform all the necessary 3D mathematical opera-tions and handle the computer’s video hardware. Tom, who is writing a program for anarchitectural firm, needs his application to display 3D images of buildings. Because he is working

GaddA4.book Page 1235 Monday, July 21, 2003 11:53 AM

1236 Appendix N: An Object-Oriented System Development Primer

under a tight deadline, and does not possess a great deal of knowledge about computer graphics,he can use Sharon’s component to perform the 3D rendering (for a small fee, of course!).

Component reusability and object-oriented programming technology set the stage for large-scale computer applications to become systems of unique collaborating entities (components).

An Everyday Example of an ObjectThink of your alarm clock as an object. It has the following attributes:

� The current second (a value in the range of 0–59)

� The current minute (a value in the range of 0–59)

� The current hour (a value in the range of 1–12)

� The time the alarm is set for (a valid hour and minute)

� Whether the alarm is on or off (“on” or “off”)

As you can see, the attributes are merely data values that define the alarm clock’s “state.” Thealarm clock also has the following methods:

� Increment the current second

� Increment the current minute

� Increment the current hour

� Sound alarm

� Set time

� Set alarm time

� Turn alarm on

� Turn alarm off

The methods are all actions that the clock performs. Each method manipulates one or more ofthe attributes. For example, every second the “Increment the current second” method executes.This changes the value of the current second attribute. If the current second attribute is set to 59when this method executes, the method is programmed to reset the current second to 0, and thencause the “Increment current minute” method to execute. This method adds 1 to the currentminute, unless it is set to 59. In that case, it resets the current minute to 0 and causes the “Incre-ment current hour” method to execute. (It might also be noted that the “Increment currentminute” method compares the new time to the alarm time. If the two times match, and the alarmis turned on, the “Sound alarm” method is executed.)

The methods described in the previous paragraph are part of the alarm clock object’s private,internal workings. External entities (such as yourself) do not have direct access to the alarmclock’s attributes, but these methods do. The object is designed to execute these methods auto-matically and hide the details from you, the user. These methods, along with the object’sattributes, are part of the alarm clock’s private persona.

GaddA4.book Page 1236 Monday, July 21, 2003 11:53 AM

Appendix N: An Object-Oriented System Development Primer 1237

Some of the alarm clock’s methods are publicly available to you, however. For example, the“Set time” method allows you to set the alarm clock’s time. You activate the method by pressing aset of buttons on top of the clock. By using another set of buttons, you can activate the “Set alarmtime” method. In addition, another button allows you to execute the “Turn alarm on” and “Turnalarm off” methods. These methods are part of the alarm clock’s public persona. They define aninterface that external entities may use to interact with the object.

Classes and ObjectsIn general terms, a class is a type, or category of object. A class specifies the attributes and meth-ods that objects of that class posses. A class is not an object, however. An object is a specificinstance of a class.

For example, Jessica is an entomologist (someone who studies insects) and enjoys writingcomputer programs. She designs a program to catalog different types of insects. In the program,she creates a class named Insect, which specifies variables and methods for holding and manip-ulating data common to all types of insects. The Insect class is not an object, but a data type thatspecific objects may be created from. Next, she defines a housefly object, which is an instance ofthe Insect class. The housefly object is an entity that occupies computer memory and storesdata about houseflies. It contains the attributes and methods specified by the Insect class.

Object RelationshipsSpecial relationships may exist between objects. The possible relationships may be formally stated as

� Access

� Ownership

� Inheritance

Informally, these three relationships may be described as

� Knows

� Has a

� Is a

The access relationshipThe first relationship, access, allows an object to modify the attributes of another object. Nor-mally, an object has private attributes, which are not accessible to parts of the program outsidethe object. An access relationship between two objects means that one object has access to theother object’s private attributes. When this relationship exists, it can be said that one object knowsthe other.

The ownership relationshipThe second relationship, ownership, means that one object is an attribute of another object. Forexample, a human resources system might have an object that represents an employee. That

GaddA4.book Page 1237 Monday, July 21, 2003 11:53 AM

1238 Appendix N: An Object-Oriented System Development Primer

object might have, as an attribute, another object that holds the employee’s name. It can be saidthat the employee object has a name object. In OOP terminology, this type of relationship isknown as a whole-part hierarchy, or composition.

The inheritance relationshipThe third type of relationship is inheritance. Sometimes an object class is based on another class.This means that one class is a specialized case of the other. For example, consider a program thatuses classes representing cars, trucks, and jet planes. Although those three types of objects in thereal world are very different, they have some common characteristics: They are all modes of trans-portation, and they all carry some number of passengers. So, each of the three classes could bebased on a Vehicle class that has the attributes and behaviors common to all of the classes. This isillustrated in Figure N-3.

In OOP terminology, the Vehicle class is the base class. The Car, Truck, and Jet Plane classes arederived classes. All of the attributes and behaviors of the Vehicle class are inherited by the Car,Truck, and Jet Plane classes. The relationship implies that a Car is a Vehicle, a Truck is a Vehicle,and a Jet Plane is a Vehicle. Inheritance is discussed in detail in Chapter 15.

In addition to inheriting the attributes and behaviors of the base class, derived classes addtheir own. For example, the Car class might have attributes and behaviors that set and indicatewhether it is a sedan or coupe, and the type of engine it has. The Truck class might have attributesand behaviors that set and indicate the maximum amount of weight it can carry, and the numberof miles it can travel between refueling. The Jet Plane class might have attributes and behaviorsthat set and indicate the plane’s altitude and heading. These added components make the derivedclasses more specialized than the base class. For that reason, this type of relationship is oftencalled a generalization/specialization hierarchy.

MessagesWe have established the fact that objects have methods, which are behaviors. But how do we makean object perform a behavior? Quite simply, we send the object a message, requesting that it exe-cute a particular named method. In C++, messages are actually member function calls. For exam-ple, suppose a program has a class named Shape, which has a public member function namedcalcArea. The program defines an instance of the Shape class named square, and contains thefollowing statement:

Figure N-3

Vehicle

TruckCar Jet Plane

GaddA4.book Page 1238 Monday, July 21, 2003 11:53 AM

Appendix N: An Object-Oriented System Development Primer 1239

square.calcArea();

This statement sends the calcArea message to the square object.

Developing an Object-Oriented SystemObject-oriented systems development generally consists of two phases: object-oriented analysis,and object-oriented design. A systems analyst usually conducts these phases. This section brieflydiscusses the analyst’s activities in each phase.

Object-Oriented AnalysisDuring object-oriented analysis, the analyst creates a logical design of the system. The logicaldesign specifies what the system is to do, but does not specify how the system should do it. In gen-eral, the object-oriented analysis phase consists of the following steps:

1. Examine the problem domain and model the system from within the context of that perspective.First, you should understand the nature of the problem you are trying to solve. This involvesexamining the following parameters:

� The significant events that are part of the problem.

� The internal parties that will interact with the system.

� The external parties that will interact with the system.

� The inputs and outputs required by the system.

Once you have identified the system’s major events, internal and external parties, inputs, and out-puts, you can create a model. The Unified Modeling Language (UML) is a tool that is widely usedto graphically depict and document system designs. UML specifies a number of diagrams formodeling the various parts of a system. One such diagram is the use case diagram. A use case dia-gram shows the sequence of steps that take place in performing a task and identifies the parties(actors) involved in the task.

2. Identify objects (entities) that exist within the boundaries of the system.In order to determine which classes will appear in a program, the analyst should think of the real-world objects and data elements that are present in the problem. One popular method of discov-ering the objects within a problem is to write a description of the problem with its major eventsand parties, then identify all the nouns in the description. Each noun is candidate to become aclass. Here are examples of items that may be candidates for classes:

� The result of a business event, such as a customer order

� Physical objects, such as vehicles, machines, or manufactured products

� Record keeping items, such as customer histories and payroll records

� Any role played by a human (employee, client, teacher, student, and so forth)

GaddA4.book Page 1239 Monday, July 21, 2003 11:53 AM

1240 Appendix N: An Object-Oriented System Development Primer

In object-oriented analysis, classes are first modeled with a class diagram. The class diagram,which is another UML tool, shows all the classes involved in a use case.

3. Identify the necessary object relationships and interactions for the system.The next step is to identify the relationships that exist between and among the classes. You iden-tify these relationships by looking for the natural associations that exist between the objects. Onceidentified, you can add the appropriate relationship to the class diagram.

4. Understand that there is no “right” solution to these tasks.For each problem, there may be many solutions. The role of the analyst is to understand the prob-lem and design a system that efficiently solves it or improves the existing process.

Object-Oriented DesignDuring object-oriented design, the analyst determines how the objects and system requirementsidentified in the analysis phase will be implemented. It usually involves the following activities:

1. Determine the correct hierarchical relationship between objects in the system.In this step, the analyst determines how to implement the object relationships identified in theanalysis phase, and verifies that those relationships are correct. If the relationships are not correct,the models produced during the analysis phase are modified.

2. Determine the correct ownership of the attributes and behaviors in the individual object-to-object interactions.When relationships exist between classes, especially the inheritance relationship, a “spectrum” ofclasses emerges. The analyst must carefully consider which class in the spectrum is the appropri-ate owner of each attribute and method.

3. Implement and test the object/system interaction.Finally, the analyst (or a programmer/developer) implements the design using an object-orientedprogramming language. The language must support the features specified in the object-orienteddesign. In addition, the system’s interactions with the operating system and the user interface areimplemented. The system is then tested and further refined.

Design IssuesThe analyst must address many reusability and design issues that impact the complexity and effi-ciency of an object-oriented system. Among them are the following:

� Are the classes too specific in design to be used generically, or too general in design to be used without modification or extension?

GaddA4.book Page 1240 Monday, July 21, 2003 11:53 AM

Appendix N: An Object-Oriented System Development Primer 1241

� To change a class’s capabilities, should the class be modified, or should a child class be designed as a specialization? If the class is to be modified, will the changes create unwanted side effects because of other relationships that exist?

� Is the definition of a class such that objects of the class can stand on their own in multiple scenarios?

� Is there an overuse of inheritance or specialization? Inheritance can be taken to an extreme, where one class is the child of another class, which is the child of another class, and so on. Excessive generalization/specialization relationships might be necessary in some cases, but they can result in overly complex systems.

� Does it make sense to implement an entity as an object? Are there other data structures that make more sense?

GaddA4.book Page 1241 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1242 Monday, July 21, 2003 11:53 AM

1243

Appendix OAnswers to Checkpoints

Chapter 11.1 Because the computer can be programmed to do so many different tasks

1.2 The central processing unit (CPU), main memory (RAM), secondary storage devices, input devices, and output devices

1.3 Arithmetic and logic unit (ALU) and control unit

1.4 Fetch: The CPU’s control unit fetches the program’s next instruction from main memory.

Decode: The control unit decodes the instruction, which is encoded in the form of a number. An electrical signal is generated.

Execute: The signal is routed to the appropriate component of the computer, which causes a device to perform an operation.

1.5 A unique number assigned to each memory storage location

1.6 Program instructions and data are stored in main memory while the program is operating. Main memory is volatile and loses its contents when power is removed from the computer. Secondary storage holds data for long periods of time—even when there is no power to the computer.

1.7 Operating systems and application software

1.8 A single tasking operating system is capable of running only one program at a time. All the com-puter’s resources are devoted to the program that is running. A multitasking operating system is capable of running multiple programs at once. A multitasking system divides the allocation of the hardware resources among the running programs using a technique known as time sharing.

1.9 A single user system allows only one user to operate the computer at a time. A multiuser system allows several users to operate the computer at once.

1.10 A set of well-defined steps for performing a task or solving a problem

1.11 To ease the task of programming. Programs may be written in a programming language, then converted to machine language.

1.12 A low-level language is close to the level of the computer and resembles the system’s numeric machine language. A high-level language is closer to the level of human readability and resembles natural languages.

1.13 That a program may be written on one type of computer and run on another type

1.14 The preprocessor reads the source file, searching for commands that begin with the # symbol. These are commands that cause the preprocessor to modify the source file in some way. The com-piler translates each source code instruction into the appropriate machine language instruction, and creates an object file. The linker combines the object file with necessary library routines to create an executable file.

GaddA4.book Page 1243 Monday, July 21, 2003 11:53 AM

1244 Appendix O: Answers to Checkpoints

1.15 Source file: Contains program statements written by the programmer.

Object file: Contains machine language instructions generated by the compiler.

Executable file: Contains code ready to run on the computer. Includes the machine language from an object file and the necessary code from library routines.

1.16 A programming environment that includes a text editor, compiler, debugger, and other utilities, integrated into one package

1.17 A key word has a special purpose and is defined as part of a programming language. A programmer-defined symbol is a word or name defined by the programmer.

1.18 Operators perform operations on one or more operands. Punctuation symbols mark the begin-ning or ending of a statement, or separate items in a list.

1.19 A line is a single line as it appears in the body of a program. A statement is a complete instruction that causes the computer to perform an action. It may be written on 1 or more lines.

1.20 Because their contents may be changed while the program is running.

1.21 The original value is overwritten.

1.22 The variable must be defined in a declaration.

1.23 Input, processing, and output

1.24 The program’s purpose, the information to be input, the processing to take place, and the desired output.

1.25 To imagine what the computer screen looks like while the program is running. This helps define input and output.

1.26 A chart that depicts each logical step of the program in a hierarchical fashion

1.27 a “language” that is a cross between human language and programming languages that is used to express algorithms.

1.28 High-level psuedocode just lists the steps a program must carry out. Detailed psuedocode shows the variables, logic, and computations needed to create the program.

1.29 It translates each source code statement into the appropriate machine language statements.

1.30 An error that occurs while the program is running when the system is asked to perform an action it cannot carry out.

1.31 The programmer steps through each statement in the program from beginning to end. The con-tents of variables are recorded, and screen output is sketched.

1.32 To determine if a logical error is present in the program

1.33 Procedural programs are made of procedures or functions. Object-oriented programs are cen-tered on objects, which contain both data and the procedures that operate on the data.

Chapter 22.1 // A crazy mixed up program

#include <iostream>using namespace std;

int main(){

cout << "In 1492 Columbus sailed the ocean blue.";return 0;

}

GaddA4.book Page 1244 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1245

2.2 // Today's Date: March 29, 2004#include <iostream>using namespace std;

int main(){

cout << "Teresa Jones";return 0;

}2.3 B

2.4 A

2.5 // It's a mad, mad program#include <iostream>using namespace std;

int main(){

cout << "Success\n";cout << "Success";cout << " Success\n\n";cout << "Success\n";return 0;

}

2.6 The works of Wolfganginclude the following:The Turkish Marchand Symphony No. 40 in G minor.

2.7 // Today's Date: March 29, 2004#include <iostream>using namespace std;

int main(){

cout << "Teresa Jones\n";cout << "127 West 423rd Street\n";cout << "San Antonio, TX 78204\n";cout << "555-475-1212\n";return 0;

}2.8 Variables: little and big

Constants: 2, 2000, "The little number is ", "The big number is", 02.9 The value is number2.10 99bottles: Variable names cannot begin with a number.

r&d: Variable names may only use alphabetic letters, digits, and underscores.

2.11 No. Variable names are case sensitive.

GaddA4.book Page 1245 Monday, July 21, 2003 11:53 AM

1246 Appendix O: Answers to Checkpoints

2.12 A) short or unsigned shortB) intC) They both use the same amount of memory.

2.13 unsigned short, unsigned int, and unsigned long

2.14 int apples = 20;2.15 67, 70, 87

2.16 ‘B’

2.17 1 byte, 2 bytes, 6 bytes, 1 byte

2.18 The string literal “Z” is being stored in the character variable letter.

2.19 string2.20 // Substitute your name, address, and phone

// number for those shown in this program.#include <iostream>#include <string>using namespace std;

int main(){

string name, address, phone;name = "George Davis";address = "179 Ravenwood Lane";phone = "555-6767";cout << name << endl;cout << address << endl;cout << phone << endl;return 0;

}2.21 6.31E17

2.22 3

2.23 #include <iostream>using namespace std;

int main(){

int age;float weight;

age = 26;weight = 180;cout << "My age is " << age << "and my weight is " << weight; << weight << " pounds.\n";return 0;

}

GaddA4.book Page 1246 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1247

2.24 Invalid. The value on the left of the = operator must be an lvalue.

2.25 The variable critter is assigned a value before it is declared. Correct the program by moving the statement critter = 62.7; to the point after the variable definition.

2.26 11, 5, 24, 2

2.27 Integer division. The value 5 will be stored in portion.

Chapter 33.1 iostream3.2 The stream extraction operator

3.3 The console (or keyboard)

3.4 True

3.5 3

3.6 cin >> miles >> feet >> inches;3.7 Include one or more cout statements explaining what values the user should enter.

3.8 #include <iostream>using namespace std;

int main(){

float pounds, kilograms;

cout << "Enter your weight in pounds: ";cin >> pounds;// The following line does the conversion.kilograms = pounds / 2.21;cout << "Your weight in kilograms is ";cout << kilograms << endl;return 0;

}3.9 A) *

B) same

C) same

3.10 Value21 231 524 269 030

GaddA4.book Page 1247 Monday, July 21, 2003 11:53 AM

1248 Appendix O: Answers to Checkpoints

3.11 y = 6 * x;a = 2 * b + 4 * c;y = pow(x, 3);g = (x + 2) / (z * z); or g = (x + 2) / pow(z, 2);y = (x * x) / (z * z); or y = pow(x, 2) / pow (z, 2);

3.12 If the user enters… The program displays…2 65 274.3 20.496 38

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

int main(){

double volume, radius, height;cout << "This program will tell you the volume of\n";cout << "a cylinder-shaped fuel tank.\n";cout << "How tall is the tank? ";cin >> height;cout << "What is the radius of the tank? ";cin >> radius;volume = 3.14159 * pow(radius, 2.0) * height;cout << "The volume of the tank is " << volume << endl;return 0;

}3.14 A) 2

B) 17.0

C) 2.0

D) 2.4

E) 2.4

F) 2.4

G) 4

H) 27

I) 30

J) 27.0

3.15 #include <iostream>using namespace std;

int main(){

char letter;

GaddA4.book Page 1248 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1249

cout << "Enter a character: ":cin >> letter;cout << "The ASCII code for " << letter;cout << " is " << static_cast<int>(letter) << endl;return 0;

}3.16 9

9.59

3.17 const float e = 2.71828;const float yearSecs = 5.26e5;const float gravAcc_ftPerSec = 32.2;const float gravAcc_mPerSec = 9.8;const int metersPerMile = 1609;

3.18 #define E 2.71828#define YEARSECS 5.26e5#define GRAVACC_FTPERSEC 32.2#define GRAVACC_MPERSEC 9.8#define METERSPERMILE 1609

3.19 This program calculates the number of candy pieces sold.How many jars of candy have you sold? 6[Enter]The number of pieces sold: 11160Candy pieces you get for commission: 2232

3.20 #include <iostream>using namespace std;

int main(){

const float conversion = 1.467;float milesPerHour, feetPerSecond;

cout << "This program converts miles-per-hour to\n";cout << "feet-per-second.\n";cout << "Enter a speed in MPH: ";cin >> milesPerHour;feetPerSecond = milesPerHour * conversion;cout << "That is " << feetPerSecond << " feet-per-second.\n";return 0;

}3.21 total = subtotal = tax = shipping = 0;3.22 A) x += 6;

B) amount -= 4;C) y *= 4;D) total /= 27;E) x %= 7;

GaddA4.book Page 1249 Monday, July 21, 2003 11:53 AM

1250 Appendix O: Answers to Checkpoints

F) x += (y * 5);G) total -= (discount * 4);H) increase *= (salesRep * 5);I) profit /= (shares – 1000);

3.23 3111

3.24 A) cout << fixed << setprecision(2);cout << setw(9) << 34.789;

B) cout << fixed << showpoint << setprecision(3);cout << setw(5) << 7.0;

C) cout << fixed << 5.789e12; D) cout << left << setw(7) << 67;

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

int main(){

const float pi = 3.14159;float degrees, radians;cout << "Enter an angle in degrees and I will convert it\n";cout << "to radians for you: ";cin >> degrees;radians = degrees * pi / 180;cout << degrees << " degrees is equal to ";cout << fixed << showpoint << setprecision(4);cout << left << setw(7) << radians << " radians.\n ";return 0;

}3.26 No. Space is needed for a fifth character, to hold the null terminator.

3.27 A) Legal (Though no embedded blanks can be input)

B) Illegal (This works for C-strings only)

C) Legal

D) Legal

3.28 A) Legal (Though no embedded blanks can be input)

B) Legal

C) Legal

D) Illegal (Arrays cannot be assigned to variables like this. Use strcpy().)

3.29 x = sin(angle1) + cos(angle2);3.30 y = pow(x, 0.2); // 0.2 is equal to 1/53.31 y = 1 / sin(a);

GaddA4.book Page 1250 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1251

3.32 fstream3.33 ifstream objects can only be used to read from a file into memory, whereas ofstream objects

can only be used to write from memory to a file.

3.34 The open statement

3.35 C

Chapter 44.1 T, T, T, T, T, T, T

4.2 A) Incorrect

B) Incorrect

C) Correct

4.3 A) Yes

B) No

C) No

4.4 0010

4.5 True

4.6 False

4.7 A) The if statement is terminated with a semicolon.

B) The = operator is used instead of the == operator.

C) Only the first statement after the if statement is conditionally executed. The first two statements after the if statement should be enclosed in a set of braces.

4.8 if (y == 20) x = 0;

4.9 if (hours > 40) payRate *= 1.5;

4.10 if (sales >= 10000.00) commission = .20;

4.11 if (max) fees = 50;

4.12 False

4.13 if (y == 100) x = 1;else x = 0;

4.14 if (sales >= 50000.00) commission = 0.20;else commission = 0.10;

GaddA4.book Page 1251 Monday, July 21, 2003 11:53 AM

1252 Appendix O: Answers to Checkpoints

4.15 #include <iostream>using namespace std;

int main(){

float taxRate, saleAmount;char residence;

cout << "Enter the amount of the sale: ";cin >> saleAmount;cout << "Enter I for in-state residence or O for out-of-\n";cout "state: ";cin.get(residence);if (residence == 'O')

taxRate = 0;else

taxRate = 0.05;saleAmount += saleAmount * taxRate;cout << "The total is " << saleAmount;return 0;

}4.16 No. When x equals y the if/else statement causes a 2 to display and the two separate if

statments don’t display anything.

4.17 #include <iostream>using namespace std;

int main(){

int testScore;char grade;bool goodScore = true;

cout << "Enter your numeric test score and I will\n"; cout << "tell you the letter grade you earned: "; cin >> testScore;

if (testScore < 0)goodScore = false;

else if (testScore < 60)grade = 'F';

else if (testScore < 70)grade = 'D';

else if (testScore < 80)grade = 'C';

else if (testScore < 90)grade = 'B';

else if (testScore <= 100)grade = 'A';

elsegoodScore = false;

GaddA4.book Page 1252 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1253

if (goodScore) cout << "Your grade is " << grade << ".\n";

else{ cout << testScore << " is an invalid score.\n"; cout << "Please enter a score between 0 and 100.\n";}return 0;

}4.18 114.19 If the customer purchases this many coupons are

this many books... given.-----------------------------------------------------

1 12 13 24 25 310 3

4.20 if (amount1 > 10){ if (amount2 < 100)

{ if (amount1 > amount2)cout << amount1;

else} cout << amount2;

}4.21

4.22 T, F, T, T, T

4.23 True (&& is done before ||)

4.24 if (!activeEmployee)4.25 if (speed < 0 || speed > 200)

cout << "The number is not valid.";

Logical Expression Result (True or False)

true && false falsetrue && true truefalse && true falsefalse && false falsetrue || false truetrue || true truefalse || true truefalse || false false!true false!false true

GaddA4.book Page 1253 Monday, July 21, 2003 11:53 AM

1254 Appendix O: Answers to Checkpoints

4.26 #include <iostream>using namespace std;

int main(){

int first, second, result;

cout << "Enter a negative integer: ";cin >> first;cout << "Now enter a positive integer: ";cin >> second;if (first >= 0 || second < 0){

cout << "The first number should be negative\n";cout << "and the second number should be\n";cout << "positive. Run the program again and\n";cout << "enter the correct values.\n";

}else{

result = first * second;cout << first << " times " << second << " is " << result << endl;

}return 0;

}4.27 The variables length, width, and area should be defined before they are used.

4.28 Enter your first test score: 40Enter your second test score: 30Test 1: 50Test 2: 40Sum : 70

4.29 A) True

B) False

C) True

D) False

E) False

F) True

4.30 A) False

B) False

C) True

D) False

E) False

F) True

G) False

GaddA4.book Page 1254 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1255

4.31 A) z = x > y ? 1 : 20;B) population = temp > 45 ? base * 10 : base * 2;C) wages *= hours > 40 ? 1.5 : 1;D) cout << (result >= 0 ? "The result is positive\n" :

"The result is negative.\n");4.32 A) if (k > 90)

j = 57;else j = 12;

B) if (x >= 10) factor = y * 22;else factor = y * 35;

C) if (count == 1) total += sales;else total += count * sales;

D) if (num % 2) cout << "Even\n";else cout << "Odd\n";

4.33 2 24.34 Because the if /else statement tests several different conditions, consisting of different variables

and becasuse it tests values with relational operators other than equal-to.

4.35 The case statements must be followed by an integer constant, not a relational expression.

4.36 That is serious.4.37 switch (userNum)

{case 1 : cout << "One"; break;case 2 : cout << "Two"; break;case 3 : cout << "Three"; break;default: cout << "Enter 1, 2, or 3 please.\n";

}4.38 switch (selection)

{case 1 : cout << "Pi times radius squared\n"; break;case 2 : cout << "length times width\n"; break;case 3 : cout << "Pi times radius squared times height\n"; break;

GaddA4.book Page 1255 Monday, July 21, 2003 11:53 AM

1256 Appendix O: Answers to Checkpoints

case 4 : cout << "Well okay then, good bye!\n"; break;default : cout << "Not good with numbers, eh?\n";

}4.39 enum must be lowercase.

There should be no = sign.

The symbolic names in the enumeration list should not be in quotes.

It should end with a semicolon.

4.40 if (color <= yellow)cout "primary color \n";

elsecout "mixed color \n";

Chapter 55.1 A) 32

B) 33C) 23D) 34E) It is true!F) It is true!

5.2 None

5.3 Once

5.4 x is the counter, y is the accumulator.

5.5 #include <iostream>using namespace std;

int main(){

int num = 10;

cout << "number number Squared\n";cout << "--------------------------------------\n";while (num > 0){

cout << num << "\t\t" << (num * num) << endl;num--;

}return 0;

}5.6 One solution is to replace the while statement of Program 5-8 with

while (points >= 0)Here is another solution:

GaddA4.book Page 1256 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1257

// This program calculates the total number of points a// soccer team has earned over a series of games. The user// enters a series of point values, then a negative number// when finished.

#include <iostream>using namespace std;

int main(){

int game = 0, points = 0, total = 0;

cout << "Enter the number of points your team has earned\n";cout << "so far in the season, then enter a negative number\n";cout << "when finished.\n";while (points >= 0){

cout << "Enter the points for game " << ++game << ": ";cin >> points;if (points > 0)

total += points;}cout << "The total points are " << total << endl;return 0;

}5.7 Use the eof() function, which returns true when the previous read encountered the end of file

or test the return value of the stream extraction operator (>>), which returns false when a read attempt fails.

5.8 A) Hello WorldB) 01234C) 6 10 5

5.9 int number, total = 0;do{

cout << "Enter a number: ";cin >> number;total += number;

} while (total <= 300);5.10 The initialization, the test, and the update

5.11 A) 0246810B) -5-4-3-2-1C) 5

8111417

5.12 for (count = 0; count <= 100; count += 5)cout << count << endl;

GaddA4.book Page 1257 Monday, July 21, 2003 11:53 AM

1258 Appendix O: Answers to Checkpoints

5.13 int count, number, total = 0;for (count = 0; count < 7; count++){

cout << "Enter a number: ";cin >> number;total += number;

}cout << "The total is " << total << endl;

5.14 float x, y, quotient, total = 0;for (x = 1, y = 30; x <= 30; x++, y--){

quotient = x / y;total += quotient;

}cout << "The total is " << total << endl;

5.15 A) forB) do-whileC) whileD) whileE) for

5.16 A) 600 times (20 times 30)

B) 220 times (20 times 11)

5.17 13712

5.18 do{ cout << "Enter a number in the range 10 - 25: ";

cin >> number;if (number < 10 || number > 25)

cout << "That value is out of range. Try again.\n";} while (number < 10 || number > 25);

5.19 char letter;do{ cout << "Enter y, y, N, or n: ";

cin >> letter;if (letter != 'Y' && letter != 'y' && letter != 'N' && letter != 'n')

cout << "That is not a valid choice. Try again.\n";} while (letter != 'Y' && letter != 'y' && letter != 'N' && letter != 'n');

GaddA4.book Page 1258 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1259

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

int main(){

int choice, months;float charges;

do{ // Display menu cout << "\n\tHealth Club Membership Menu\n\n"; cout << "1. Standard Adult Membership\n"; cout << "2. Child Membership\n"; cout << "3. Senior Citizen Membership\n"; cout << "4. Quit the Program\n\n"; cout << "Enter your choice: ";

// Input and validate user’s menu choice cin >> choice; while(choice < 1 || choice > 4) { cout << "The valid choices are 1 through 4.\n";

cout << “Please reenter menu choice: ";cin >> choice;

} // If choice is not to quit, carry out the choice if (choice != 4) { cout << "For how many months? ";

cin >> months;

// Set charges based on user input switch (choice) {

case 1: charges = months * 40.0;break;

case 2: charges = months * 20.0; break; case 3: charges = months * 30.0;

} // Display the monthly charges

cout << fixed << showpoint << setprecision(2);cout << "The total charges are $" << charges << endl;

}} while (choice != 4);return 0;

}

GaddA4.book Page 1259 Monday, July 21, 2003 11:53 AM

1260 Appendix O: Answers to Checkpoints

Chapter 66.1 Function call

6.2 Function header

6.3 I saw ElbaAble was I

6.4 void qualify(){

cout << "Congratulations, you qualify for\n";cout << "the loan. The annual interest rate\n";cout << "is 12%\n";

}

void noQualify(){

cout << "You do not qualify. In order to\n";cout << "qualify you must have worked on\n";cout << "your current job for at least two\n";cout << "years and you must earn at least\n";cout << "$17,000 per year.\n";

}6.5 Header

PrototypeFunction call

6.6 void timesTen(int number){

cout << (number * 10);}

6.7 void timesTen(int);6.8 0 0

1 22 43 64 85 106 127 148 169 18

6.9 0 1.51.5 00 100 1.5

6.10 void showDollars(float amount){

cout << fixed << showpoint << setprecision(2);cout << "Your wages are $" << amount << endl;

}

GaddA4.book Page 1260 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1261

6.11 One

6.12 float distance(float rate, float time)6.13 int days(int years, int months, int weeks)6.14 char getKey()6.15 long lightYears(long miles)6.16 A static local variable’s scope is limited to the function in which it is defined. A global variable’s

scope is the portion of the program from its definition to the end of the program.

6.17 10050100

6.18 10111213141516171819

6.19 Literals and constants

6.20 Prototype:void compute(float, int = 5, long = 65536);Header:void compute(float x, int y, long z)

6.21 Prototype:void calculate(long, &float, int = 47);Header:void calculate(long x, float &y, int z)

6.22 5 10 159 10 156 15 154 11 16

6.23 0 00Enter two numbers: 12 1412 14014 15-114 15-1

6.24 Different parameter lists

6.25 1.26.26 226.27 30

GaddA4.book Page 1261 Monday, July 21, 2003 11:53 AM

1262 Appendix O: Answers to Checkpoints

6.28 Function prototype:float calcArea(float, float);

Definition of the function:float calcArea(float len, float wide){

return len * wide;}

Chapter 77.1 struct Student

{ int id, entryYear;float gpa;

};Student s1(1234, 2002, 3.41);Student s2(5678, 2003);

7.2 struct Account{ string acctNum; double acctBal, intRate, avgBal;

Account(string num, double bal, double rate, double avg) { acctNum = num; acctBal = bal; intRate = rate; avgBal = avg; }};Account savings(“ACZ42137”, 4512.59, .04, 4217.07);

7.3 #include <iostream>#include <string>using namespace std;

struct MovieInfo{

string name, director;int year;

};

int main(){

MovieInfo movie;

cout << "Enter the following information about your ” << " favorite movie.\n" << “Name: ”;getline(cin, movie.name);

GaddA4.book Page 1262 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1263

cout << "Director: "; getline(cin, movie.director); cout << "Year of Release: "; cin >> movie.year; cout << "\nHere is information on your favorite movie:\n"; cout << "Name: " << movie.name << endl; cout << "Director: " << movie.director << endl; cout << "Year of Release: " << movie.year << endl; return 0;}

7.4 struct Measurement{

int miles;long meters;

}7.5 struct Destination

{string city;Measurement distance;

};Destination place;

7.6 place.city = "Tupelo";place.distance.miles = 375;place.distance.meters = 603375;

7.7 void showRect(Rectangle r){

cout << r.length << endl;cout << r.width << endl;

}7.8 void getRect(Rectangle &r)

{cout << "Width: ";cin >> r.width;cout << "Length: ";cin >> r.length;

}7.9 Rectangle getRect() // Function return type is a Rectangle structure

{Rectangle r;cout << "Width: ";cin >> r.width;cout << "Length: ";cin >> r.length;return r;

}

GaddA4.book Page 1263 Monday, July 21, 2003 11:53 AM

1264 Appendix O: Answers to Checkpoints

7.10 union ThreeTypes{

char letter;int whole;float real;

};ThreeTypes sampleUnion;

7.11 4 bytes

7.12 B

7.13 A

7.14 C

7.15 class Date{private:

int month;int day;int year;

public:void setDate(int m, int d, int y)

{ month = m; day = d; year = y; }int getMonth()

{ return month; }int getDay()

{ return day; }int getYear()

{ return year; }}Alternately there could be separate setMonth, setDay, and setYear member functions to validate and set each component of the date separately.

7.16 The BasePay class declaration would reside in basepay.hThe BasePay member function definitions would reside in basepay.cppThe Overtime class declaration would reside in overtime.hThe Overtime member function declarations would reside in overtime.cpp

7.17 basepay.h and overtime.h7.18 A constructor is automatically called when the class object is created. It is useful for initializing

member variables or performing setup operations.

7.19 A

7.20 A

7.21 ClassAct sally(25);7.22 True

7.23 False

7.24 B

7.25 False

GaddA4.book Page 1264 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1265

7.26 505020

7.27 47goodbyegoodbye

Chapter 88.1 A) int empNum[100];

B) float payRate[25];C) long miles[14];D) char letter[26];E) double lightYears[1000];

8.2 int readings[-1]; // Size declarator cannot be negativefloat measurements[4.5]; // Size declarator must be an integerint size; // This is not an arraychar name[size]; // Size declarator must be a constant

8.3 0 through 3

8.4 The size declarator is used in the array definition statement. It specifies the number of elements in the array. A subscript is used to access an individual element in an array.

8.5 Array bounds checking is a safeguard provided by some languages. It prevents a program from using a subscript that is beyond the boundaries of an array. C++ does not perform array bounds checking.

8.6 12345

8.7 #include <iostream>using namespace std;

int main(){

int fish[10], count;

cout << "Enter the number of fish caught\n"; cout << "by each fisherman.\n";

for (count = 0; count < 10; count++){

cout << "fisherman " << (count+1) << ": "; cin >> fish[count]; }

return 0;}

GaddA4.book Page 1265 Monday, July 21, 2003 11:53 AM

1266 Appendix O: Answers to Checkpoints

8.8 A) int ages[10] = {5, 7, 9, 14, 15, 17, 18, 19, 21, 23};B) float temps[7] = {14.7, 16.3, 18.43, 21.09, 17.9, 18.76, 26.7};C) char alpha[8] = {'J', 'B', 'L', 'A', '*', '$', 'H', 'M'};

8.9 A) int numbers[10] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 1};The definition is valid.

B) int matrix[5] = {1, 2, 3, 4, 5, 6, 7};The definition is invalid because there are too many values in the initialization list.

C) float radii[10] = {3.2, 4.7};The definition is valid. Elements 2-9 wll be initialized to 0.0.

D) int table[7] = {2, , , 27, , 45, 39};The definition is invalid. Values cannot be skipped in an initialization list.

E) char codes[] = {'A', 'X', '1', '2', 's'};The definition is valid. The codes array will be allocated space for five characters.

F) int blanks[];The definition is invalid. An initialization list must be provided when an array isimplicitly sized.

G) string suit[4] = {"Clubs", "Diamonds", "Hearts", "Spades"};The definition is valid.

8.10 No. An entire array cannot be copied in a single statement with the = operator. The array must be copied element by element.

8.11 A) 10B) 3C) 6D) 14

8.12 08.13 10.00

25.0032.5050.00110.00

8.14 1 18 182 4 83 27 814 52 2085 100 500

8.15 typedef int TenInts[10];8.16 The starting address of the array

8.17 ABCDEFGH8.18 (The entire program is shown here.)

#include <iostream>using namespace std;

// Function prototypefloat avgArray(int [], int);

GaddA4.book Page 1266 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1267

int main(){

int userNums[10];

cout << "Enter 10 numbers: ";for (int count = 0; count < 10; count++){

cout << "#" << (count + 1) << " ";cin >> userNums[count];

}cout << "The average of those numbers is ";cout << avgArray(userNums, 10) << endl;return 0;

}

// Function avgArrayfloat avgArray(int array[], size){

float total = 0.0, average;for (int count = 0; count < size; count++)

total += array[count];average = total / size;return average;

}8.19 int grades[30][10];8.20 24

8.21 sales[0][0] = 56893.12;8.22 cout << sales[5][3];8.23 int settings[3][5] = {{12, 24, 32, 21, 42},

{14, 67, 87, 65, 90}, {19, 1, 24, 12, 8}};

8.24

8.25 void displayArray7(int array[][7], int numRows){

for (int row = 0; row < numRows; row ++){

for (int col = 0; col < 7; col ++){ cout << array[row][col] << " ";}cout << endl;

}}

2 3 0 0

7 9 2 0

1 0 0 0

GaddA4.book Page 1267 Monday, July 21, 2003 11:53 AM

1268 Appendix O: Answers to Checkpoints

8.26 int vidNum[50][10][25];8.27 vector8.28 vector <int> frogs;

vector <float> lizards(20);vector <char> toads(100, 'Z');

8.29 vector <int> gators;vector <double> snakes(10);gators.push_back(27);snakes[4] = 12.897;

8.30 Product() // Default constructor{ description = "";

partNum = cost = 0;}Product(string d, int p, float c) // Constructor{ description = d;

partNum = p;cost = c;

8.31 Product items[100];8.32 items[0].description = "Claw Hammer";

items[0].partNum = 547;items[0].cost = 8.29;

8.33 for (int x = 0; x < 100; x++){

cout << items[x].description << endl;cout << items[x].partNum << endl;cout << items[x].cost << endl << endl;

}8.34 Product items[5] = { Product("Screw driver", 621, 1.72),

Product("Socket set", 892, 19.97), Product("Claw hammer", 547, 8.29) };

8.35 struct Measurement{

int miles;long meters;

};8.36 struct Destination

{string city;Measurement distance;

};8.37 Destination places [20];

places[4].city = "Tupelo";places[4].distance.miles = 375;places[4].distance.meters = 603375;

8.38 False

8.39 False

GaddA4.book Page 1268 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1269

8.40 102050

8.41 #include <iostream>using namespace std;

class Yard{private:

int length, width;public:

Yard(){ length = 0; width = 0; }

void setLength(int len){ length = len; }

void setWidth(int wide){ width = wide; }

int getLength() {return length;}int getWidth() {return width;}

};

int main(){

Yard lawns[10];cout << "Enter the length and width of " << "each yard.\n";

for (int count = 0; count < 10; count++){

int input;cout << "Yard " << (count + 1) << ":\n";cout << "length: ";cin >> input;lawns[count].setLength(input);cout << "width: ";cin >> input;lawns[count].setWidth(input);

}cout << "Here are the yard dimensions.\n";for (int yard = 0; yard < 10; yard++){ cout << "Yard " << (yard+1) << " " << lawns[yard].getLength() << " X " << lawns[yard].getWidth() << endl;}return 0;

}

GaddA4.book Page 1269 Monday, July 21, 2003 11:53 AM

1270 Appendix O: Answers to Checkpoints

Chapter 9 9.1 The linear search algorithm simply uses a loop to step through each element of an array, compar-

ing each element’s value with the value being searched for. The binary search algorithm, which requires the values in the array to be sorted in order, starts searching at the element in the middle of the array. If the middle element’s value is greater than the value being searched for, the algo-rithm next tests the element in the middle of the first half of the array. If the middle element’s value is less than the value being searched for, the algorithm next tests the element in the middle of the last half of the array. Each time the array tests an array element and does not find the value being searched for, it eliminates half of the remaining portion of the array. This method continues until the value is found, or there are no more elements to test. The binary search is more efficient than the linear search.

9.2 10,000

9.3 15

9.4 The items frequently searched for can be stored near the beginning of the array.

9.5 True

9.6 Change the > sign in the if statement to a < sign. The line would now read

If (array[count] < array[count + 1])9.7 The last value is now in order.

9.8 The first value, in position 0, is now in order.

9.9 selection sort

Chapter 1010.1 cout << &count;10.2 float *fltPtr;10.3 Multiplication operator, pointer declaration, indirection operator

10.4 50 60 70500 300 140

10.5 for (int x = 0; x < 100; x++) cout << *(array + x) << endl;

10.6 12040

10.7 A) ValidB) ValidC) Invalid. Only addition and subtraction are valid arithmetic operations with pointers.D) Invalid. Only addition and subtraction are valid arithmetic operations with pointers.E) Valid

10.8 A) ValidB) ValidC) Invalid. fvar is a float and iptr is a pointer to an int.D) ValidE) Invalid. ivar must be defined before it is used.

GaddA4.book Page 1270 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1271

10.9 A) TrueB) FalseC) TrueD) False

10.10 makeNegative (&num);10.11 void convert(float *val)

{*val *= 2.54;

}10.12 ip = new int;

delete ip;10.13 ip = new int[500];

delete [] ip;10.14 A pointer whose value is the address 0

10.15 char *getname(char *name){

cout << "Enter your name: ";cin.getline(name, 81);return name;

}10.16 char *getname()

{char name[81];cout << "Enter your name: ";cin.getline(name, 81);return name;

}10.17 Rectangle *rptr;10.18 cout << rptr->length << endl << rptr->width << endl;10.19 B

Chapter 1111.1 Each class object (an instance of a class) has its own copy of the class’s instance member variables.

If a class’s member variable is static, however, only one copy of the variable exists in memory. All objects of that class have access to that one variable.

11.2 Outside the class declaration

11.3 Before

11.4 Static member functions can not access instance members unless they explicitly specify an object of the class.

11.5 You can call a static member function before any instances of the class have been created.

11.6 No, but it has access to all of class X’s members, just as if it were a member.

11.7 Class X

11.8 Each member of one object is copied to its counterpart in another object of the same class.

GaddA4.book Page 1271 Monday, July 21, 2003 11:53 AM

1272 Appendix O: Answers to Checkpoints

11.9 When one object is copied to another with the = operator, and when one object is initialized with another object’s data

11.10 When an object contains a pointer to dynamically allocated memory

11.11 When an object is initialized with another object’s data, and when an object is passed by value as the argument to a function

11.12 It has a reference parameter of the same class type as the constructor’s class, and has the same name as the class.

11.13 It performs memberwise assignment.

11.14 Pet Pet :: operator=(const Pet&);11.15 dog.operator=(cat);11.16 It cannot be used in multiple assignment statements or other expressions.

11.17 It’s a built-in pointer, available to a class’s instance member functions, that always points to the instance of the class making the function call.

11.18 Instance member functions

11.19 cat is calling the operator+ function. tiger is passed as an argument.

11.20 The operator is used in postfix mode.

11.21 They should always return boolean values.

11.22 The object may be directly used with input stream such as cin and output streams such as cout.

11.23 An ostream object should be returned by reference.

11.24 An istream object should be returned by reference.

11.25 The operator function must be declared as a friend.

11.26 list1.operator[](25); 11.27 The object whose name appears on the right of the operator in the expression

11.28 So statements using the overloaded operators may be used in other expressions

11.29 The postfix version has a dummy parameter.

11.30 (Overloaded operator functions)

// Overloaded prefix -- operatorFeetInches FeetInches::operator—-(){

--inches;simplify();return *this;

}

// Overloaded postfix -- operatorFeetInches FeetInches::operator—-(int){

FeetInches temp(feet, inches);inches--;simplify();return temp;

}

GaddA4.book Page 1272 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1273

(Demonstration program)

// This program demonstrates the prefix and postfix –// operators, overloaded to work with the FeetInches class.

#include <iostream>#include "feetinc5.h"using namespace std;

int main(){

FeetInches distance;

cout << "Enter a distance in feet and inches: ";cin >> distance;cout << "Demonstrating the prefix – operator: \n";cout << "Here is the value: " << --distance << endl;cout << "Demonstrating the postfix – operator: \n";cout << "Here is the value: " << distance-- << endl;cout << "Here is the final value: " << distance << endl;return 0;

}11.31 Objects are automatically converted to other types. This ensures that an object’s data is properly

converted.

11.32 They always return a value of the data type they are converting to.

11.33 BlackBox::operator int()11.34 The Big class “has a” Small class as its member.

11.35 The is-a relation

11.36 Because derived class objects can be considered as forming a subset of the set of base class objects. Hence we can think of the base class as a “uperset” or superclass of the derived class.

11.37 The base class access specification determines how members inherited from the base class will be accessed in the derived class.

11.38 A typist is a special case of an employee.

class Employee{

int yearsOfService;};class Typist : public Employee{

int wordsPerMinute;};

11.39 Other than to friend functions, private members are only accessible to member functions of the same class. Protected members are accessible to member functions of the class as well as member functions of all derived classes.

11.40 Member access specification determines how a class member is accessible to code outside of the class. Base class access specification determines how members inherited from a base class will be accessed through the derived class.

GaddA4.book Page 1273 Monday, July 21, 2003 11:53 AM

1274 Appendix O: Answers to Checkpoints

11.41 A) a is inaccessible; the rest are private.

B) a is inaccessible; the rest are protected.

C) a is inaccessible; b, c, and setA are protected; setB and setC are public.

D) Private

11.42 Derived class constructors can assume members of the base class object have already been initial-ized.

11.43 Declarations are for typechecking, definitions are for code generation. The compiler needs the arguments to the base class constructor when it is generating code.

11.44 The same situation arises with composition when an outer class object needs to pass arguments to a constructor of an inner class object. The same syntax is used.

11.45 Entering the base.Entering the camp.Leaving the camp.Leaving the base.

11.46 This base is secure.The camp is secluded.Leaving the camp.Leaving the base.

Chapter 1212.1

strlen Accepts a C-string as an argument. Returns the length of the string (not including the null terminator).

strcat Accepts two C-strings as arguments. The function appends the contents of the second string to the first string. (The first string is altered, the second string is left unchanged.)

strcpy Accepts two C-strings as arguments. The function copies the second string to the first string. The second string is left unchanged.

strncpy

Accepts two C-strings and an integer argument. The third argument, an integer, indicates how many characters to copy from the second string to the first string. If the string2 has fewer than n characters, string1 is padded with ‘\0’ characters.

strcmp Accepts two C-string arguments. If string1 and string2 are the same, this function returns 0. If string2 is alphabetically greater than string1, it returns a negative number. If string2 is alphabetically less than string1, it returns a positive number.

strstr Searches for the first occurrence of string2 in string1. If an occurrence of string2 is found, the function returns a pointer to it. Otherwise, it returns a NULL pointer (address 0).

GaddA4.book Page 1274 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1275

12.2 412.3 Have a nice day

nice day

12.4 strcpy(composer, "Beethoven");12.5 #include <iostream>

#include <cstring>using namespace std;

int main(){

char place[] = "The Windy City";if (strstr(place, "Windy"))

cout << "Windy found.\n";else

cout << "Windy not found.\n";return 0;

}12.6 A) negative

B) negativeC) negativeD) positive

12.7 if (strcmp(iceCream, "Chocolate") == 0)cout << "Chocolate: 9 fat grams.\n";

else if (strcmp(iceCream, "Vanilla") == 0)cout << "Vanilla: 10 fat grams.\n";

else if (strcmp(iceCream, "Pralines and Pecan") == 0)cout << "Pralines and Pecan: 14 fat grams.\n";

elsecout << "That's not one of our flavors!\n";

12.8

12.9 num = atoi("10");12.10 num = atol("10000");

atoi Accepts a C-string as an argument. The function converts the string to an integer and returns that value.

atol Accepts a C-string as an argument. The function converts the string to a long integer and returns that value.

atof Accepts a C-string as an argument. The function converts the string to a float and returns that value.

itoa Converts an integer to a C-string. The first argument is the integer. The result will be stored at the location pointed to by the second argument. The third argument is an integer. It specifies the numbering system that the converted integer should be expressed in. (8 = octal, 10 = decimal, 16 = hexadecimal, etc.)

GaddA4.book Page 1275 Monday, July 21, 2003 11:53 AM

1276 Appendix O: Answers to Checkpoints

12.11 num = atof("7.2389");12.12 itoa(127, strValue, 10);12.13

12.14 little = tolower(big);12.15 if (isdigit(ch))

cout << "digit";else

cout << "Not a digit.";12.16 A

isalpha Returns true (a nonzero number) if the argument is a letter of the alphabet. Returns false if the argument is not a letter.

isalnum Returns true (a nonzero number) if the argument is a letter of the alphabet or a digit. Otherwise it returns false.

isdigit Returns true (a nonzero number) if the argument is a digit 0–9. Otherwise it returns false.

islower Returns true (a nonzero number) if the argument is a lowercase letter. Otherwise, it returns false.

isprint Returns true (a nonzero number) if the argument is a printable character (including a space). Returns false otherwise.

ispunct Returns true (a nonzero number) if the argument is a printable character other than a digit, letter, or space. Returns false otherwise.

isupper Returns true (a nonzero number) if the argument is an uppercase letter. Otherwise, it returns false.

isspace Returns true (a nonzero number) if the argument is a whitespace character. Whitespace characters are any of the following:

space................ ' 'newline.............. '\n'tab.................. '\t'vertical tab......... '\v'

Otherwise, it returns false.

toupper Returns the uppercase equivalent of its argument.

tolower Returns the lowercase equivalent of its argument.

GaddA4.book Page 1276 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1277

12.17 char choice;do

{ cout << "Do you want to repeat the program or quit? (R/Q) "; cin >> choice;} while (toupper(choice) != 'Q');

12.18 Tom Talbert Tried TrainsDom Dalbert Dried Drains

Chapter 1313.1 By filenames

13.2 Open, information saved to or read from the file, and close

13.3 fstream13.4 ofstreamOutput file stream. This data type can be used to create files and write information to

them. With the ofstream data type, information may only be copied from variables to the file, but not vice versa.

ifstreamInput file stream. This data type can be used to create files and read information from them into memory. With the ifstream data type, information may only be copied from the file into variables, but not vice versa.

fstreamFile stream. This data type can be used to create files, write information to them, and read information from them. With the fstream data type, information may be copied from vari-ables into a file or from a file into variables.

13.5 The file must be opened.

13.6 diskInfo.open("names.dat", ios::out);13.7 diskInfo.open("customers.dat", ios::out | ios::app);13.8 diskInfo.open("payable.dat", ios::in | ios::out | ios::app);13.9 if (dataBase)

cout << "The file was successfully opened.\n";else

cout << "The file was not opened.\n";13.10 outFile.close();13.11 A) cout.width(6);

B) cout.precision(4);C) cout.setf(ios::fixed);D) cout.setf(ios::left | ios::scientific);E) cout.unsetf(ios::scientific);

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

GaddA4.book Page 1277 Monday, July 21, 2003 11:53 AM

1278 Appendix O: Answers to Checkpoints

int main(){

char person[15] = "Wolfgang Smith";cout.setf(ios::right);cout.width(20);cout << person << endl;cout.setf(ios::left);cout << person << endl;return 0;

}13.13 #include<iostream>

#include <fstream>using namespace std;

int main(){

fstream outFile;outFile.open("output.txt", ios::out);outFile << "Today is the first day\n";outFile << "of the rest of your life.\n";return 0;

}13.14 It reports when the end of a file has been encountered.

13.15 RunSpotrunSeeSpotrun

13.16 The >> operator considers whitespace characters as delimiters and does not read them. The get-line() member function does read whitespace characters.

13.17 The getline function reads a line of text; the get function reads a single character.

13.18 Writes a single character to a file.

13.19 1e+002 1.7 8.6 7.8 5.113.20 #include <iostream>

#include <fstream>#include <cctype> // Needed for toupperusing namespace std;

int main(){

fstream namesFile;namesFile.open("phones.dat", ios::app);char name[81], phone[26];

cout << "This program allows you to add names and phone\n";cout << "numbers to phones.dat.\n";

GaddA4.book Page 1278 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1279

do{

char add;cout << "Do you wish to add an entry? ";cin >> add;if (toupper(add) == 'Y'){

// Write code here that asks the user for a name// and phone number, then stores it in the file.cout << "name: ";cin.getlin(name, 81);cout << "phone number: ";cin.getline(phone, 26);namesFile << name << endl;namesFile << phone << endl;

}} while (toupper(add) == 'Y');namesFile.close();return 0;

}13.21 You define multiple file stream objects, one for each file you wish to work with.

13.22 Character representation: “479”

ASCII codes: 52 55 57

13.23 The << operator writes text to a file. The write member function writes binary data to a file.

13.24 The first argument is the starting address of the section of memory, which is to be written to the file. The second argument is the size, in bytes, of the item being written.

13.25 The first argument is the starting address of the section of memory where information read from the file is to be stored. The second argument is the size, in bytes, of the item being read.

13.26 A filed is an individual piece of information pertaining to a single item. A record is made up of fields and is a complete set of information about a single item.

13.27 file.write(reinterpret_cast<char> (&cust), sizeof(cust));13.28 seekg moves the file’s read position (for input) and seekp moves the file’s write position (for

output).

13.29 tellg reports the file’s read position and tellp reports the files write position.

13.30 ios::beg The offset is calculated from the beginning of the file

ios::end The offset is calculated from the end of the file

ios::curr The offset is calculated from the current position

13.31 0

13.32 file.seekp(100L, ios::beg);Moves the write position to the one hundred first byte (byte 100) from the beginning of the file.

file.seekp(-10L, ios::end);Moves the write position to 10 bytes before the end of the file.

file.seekp(-25L, ios::cur);Moves the write position 25 bytes backward from the current position.

GaddA4.book Page 1279 Monday, July 21, 2003 11:53 AM

1280 Appendix O: Answers to Checkpoints

file.seekp(30L, ios::cur);Moves the write position 30 bytes forward from the current position.

13.33 file.open("info.dat", ios::in | ios::out);Input and output

file.open("info.dat", ios::in | ios::app);Input and output. Output will be appended to the end of the file.

file.open("info.dat", ios::in | ios::out | ios::ate);Input and output. If the file already exists, the program goes immediately to the end of the file.

file.open("info.dat", ios::in | ios::out | ios::binary);Input and output, binary mode

Chapter 1414.1 A simple case of the problem that can be solved without recursion.

14.2 The function calls itself with no way of stopping. It creates an infinite recursion.

18.3 1018.4 In direct recursion, a recursive function calls itself. In indirect recursion, function A calls function

B, which in turn calls function A.

Chapter 1515.1 Static binding means the compiler binds member function calls with the version of the function

that resides in the same class as the call itself. Dynamic binding means that function calls are bound at runtime with member functions that reside in the class responsible for the call.

15.2 Dynamically

15.3 15

15.4 22

15.5 21

15.6 215.7 Chain of inheritance

15.8 Multiple inheritance

15.9 A) InaccessibleB) ProtectedC) ProtectedD) InaccessibleE) ProtectedF) PublicG) PrivateH) ProtectedI) Public

GaddA4.book Page 1280 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1281

15.10 class SportUtility : public Van, public FourByFour{};

Chapter 1616.1 The try block contains one or more statements that may directly or indirectly throw an exception.

The catch block contains code that handles, or responds to an exception.

16.2 The entire program will abort execution.

16.3 Each exception must be of a different type. The catch block whose parameter matches the data type of the exception handles the exception.

16.4 With the first statement after the try/catch construct

16.5 By giving the exception class a member variable, and storing the desired information in the vari-able. The throw statement creates an instance of the exception class, which must be caught by a catch statement. The catch block can then examine the contents of the member variable.

16.6 When it encounters a call to the function

16.7 template <class T>int minPosition(T arr[], int size){

int minPos = 0;for (int k = 1; k < size; k++){

if (arr[k] < arr[minPos])minPos = k;

}return minPos;

} 16.8 That the operator has been overloaded by the class object

16.9 First write a regular, nontemplated version of the function. Then, after testing the function, convert it to a template.

16.10 List<int> myList;16.11 template <class T>

class Rectangle{

private:T width;T length;T area;

public:void setData(T W, T L)

{ width = W; length = L;}void calcArea()

{ area = width * length; }T getWidth()

{ return width; }

GaddA4.book Page 1281 Monday, July 21, 2003 11:53 AM

1282 Appendix O: Answers to Checkpoints

T getLength(){ return length; }

T getArea(){ return area; }

};

Chapter 1717.1 A data member contains the data stored in the node. A successor pointer points to the next node

in the list.

17.2 A pointer to the first node in the tree

17.3 The successor pointer in the last node willhave a value of NULL.

17.4 A data structure that contains a pointer to an object of the same data structure type

17.5 Appending a node is adding a new node to the end of the list. Inserting a node is adding a new node in a position between two other nodes.

17.6 Appending

17.7 We need a pointer to the previous node so we can set its successor pointer to the new node.

17.8 A) Remove the node from the list without breaking the links created by the next pointers.B) Delete the node from memory.

17.9 Because there is probably a node pointing to the node being deleted. Additionally, the node being deleted probably points to another node. These links in the list must be preserved.

17.10 The unused memory is never freed, so it could eventually be used up.

Chapter 1818.1 Last-in-first-out. The last item stored in a LIFO data structure is the first item extracted.

18.2 A static stack has a fixed size, and is implemented as an array. A dynamic stack grows in size as needed, and is implemented as a linked list. Advantages of a dynamic stack: There is no need to specify the starting size of the stack. The stack automatically grows each time an item is pushed, and shrinks each time an item is popped. Also, a dynamic stack is never full (as long as the system has free memory).

18.3 Push: An item is pushed onto, or stored in, the stack.

Pop: An item is retrieved (and hence, removed) from the stack.

18.4 Vector, linked list, or deque

Chapter 1919.1 A standard linked list is a linear data structure in which each node has at most one successor.

A binary tree is nonlinear, because each node can have up to two successors.

19.2 The first node in the tree

19.3 A node pointed to by another node in the tree

19.4 A node that points to no other nodes

19.5 An entire branch of the binary tree, from one particular node down

GaddA4.book Page 1282 Monday, July 21, 2003 11:53 AM

Appendix O: Answers to Checkpoints 1283

19.6 Information can be stored in a binary tree in a way that makes a binary search simple.

19.7 1. The node’s left subtree is traversed.2. The node’s data is processed.3. The node’s right subtree is traversed.

19.8 1. The node’s data is processed.2. The node’s left subtree is traversed.3. The node’s right subtree is traversed.

19.9 1. The node’s left subtree is traversed.2. The node’s right subtree is traversed.3. The node’s data is processed.

19.10 The node to be deleted is node D.1. Find node D’s parent and set the child pointer that links the parent to node D, to NULL. 2. Free node D’s memory.

19.11 The node to be deleted is node D.1. Find node D’s parent.2. Link the parent node’s child pointer (that points to node D) to node D’s child.3. Free node D’s memory.

19.12 1. Attach the node’s right subtree to the parent, and then find a position in the right subtree to attach the left subtree.

2. Free the node’s memory.

GaddA4.book Page 1283 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1284 Monday, July 21, 2003 11:53 AM

1285

Appendix PAnswers to Odd-Numbered Review Questions

Chapter 11. programmed

3. arithmetic logic unit (ALU) and control unit

5. operating systems and application software

7. programming language

9. High-level

11. portability

13. programmer-defined symbols

15. Punctuation

17. variable

19. input, processing, output

21. Output

23. Main memory, or RAM, is volatile, which means its contents are erased when power is removed from the computer. Secondary memory, such as a disk or CD, does not lose its contents when power is removed from the computer.

25. A syntax error is the misuse of a key word, operator, punctuation, or other part of the program-ming language. A logical error is a mistake that tells the computer to carry out a task incorrectly or to carry out tasks in the wrong order. It causes the program to produce the wrong results.

27. Account Balance High Level PseudocodeHave user input starting balanceHave user input total deposits Have user input total withdrawalsCalculate current balanceDisplay current balance

Account Balance Detailed PseudocodeInput startBalance // with promptInput totalDeposits // with prompt Input totalWithdrawals // with promptcurrentBalance = startBalance + totalDeposits - totalWithdrawalsDisplay currentBalance

GaddA4.book Page 1285 Monday, July 21, 2003 11:53 AM

1286 Appendix P: Answers to Odd-Numbered Review Questions

29. 45

31. 28

33. The error is that the program performs its math operation before the user has entered values for the variables width and length.

Chapter 21. semicolon

3. main5. braces {}7. 9.7865E14

9. B

11. B (C is valid, but prints the contents of variable Hello, rather than the string “Hello”.)

13. A) 11 B) 14 C) 3 (An integer divide takes place.)15. float temp,

weight, age;

17. A) d2 = d1 + 2; B) d1 = d2 * 4; C) c = ‘K’;D) i = ‘K’;E) i = i – 1;

19. cout << "Two mandolins like creatures in the\n\n\n";cout << "dark\n\n\n";cout << "Creating the agony of ecstasy.\n\n\n";cout << " - George Barker\n\n\n";

21. Input weeks // with promptdays = weeks * 7Display days

23. Input speed // with promptInput time // with promptdistance = speed * timeDisplay distance

25. A) 0100

B) 82

C) I am the incrediblecomputingmachineand I willamazeyou.

GaddA4.book Page 1286 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1287

27. The C-style comments symbols are backwards.

iostream should be enclosed in angle brackets.

There shouldn’t be a semicolon after int main().

The opening and closing braces of function main are reversed.

There should be a semicolon after int a, b, c.

The comment \\ Three integers should read // Three integers.

There should be a semicolon at the end of each of the following lines:a = 3b = 4c = a + b

cout begins with a capital letter.

The stream insertion operator (that appears twice in the cout statement) should read << instead of <.

The cout statement uses the variable C instead of c.

Chapter 31. A) cin >> description;

B) getline(cin, description);3. A) cin >> setw(25) >> name;

B) cin.getline(name, 25);5. iostream and iomanip7. A) price = 12 * unitCost;

B) cout << setw(12) << 98.7;C) cout << 12;

9. A) a = 12 * x;B) z = 5 * x + 14 * y + 6 * k;C) y = pow(x, 4);D) g = (h + 12) / (4 * k);E) c = pow(a, 3) / (pow(b, 2) * pow(k, 4));

11. 8

13. const int rate = 12;15. east = west = north = south = 1;17. No, a named constant must be initialized at the time it is defined. It cannot be assigned a value at

a later time.19. cout << fixed << showpoint << setprecision(4);

cout << setw(12) << totalAge;Note: Now that you understand that inputs from the keyboard should always be preceded by prompts, the // with prompt comment can be omitted from the pseudocode. Beginning with Chapter 3, we have begun omitting it.

GaddA4.book Page 1287 Monday, July 21, 2003 11:53 AM

1288 Appendix P: Answers to Odd-Numbered Review Questions

21. Input score1 Input score2 Input score3 average = (score1 + score2 + score3) / 3.0Display average

23. Input maxCredit Input creditUsed availableCredit = maxCredit – creditUsed Display availableCredit

25. A) Your monthly wages are 3225.000000B) 6 3 12C) In 1492 Columbus sailed the ocean blue.

27. A) #include <iostream> is missing.

Each cin and cout statement starts with capital C.

The << operator is mistakenly used with cin.

The assignment statement should read:

sum = number1 + number2;The last cout statement should have << after cout.

The last cout statement is missing a semicolon.

The body of the main function should be indented within the braces.

B) The cin statement should read:

cin >> number1 >> number2;The assignment statement should read:

quotient = static_cast<float>(number1) / number2;The last cout statement is missing a semicolon.

There is no return 0;

29. A) There shouldn’t be a semicolon after the #include directive.

The function header for main should read:

int main()The variable number is defined, but it is called number1 in the cin statement.

The combined assignment operator is improperly used. The statement should read:

half /= 2;There is a logical error. The value divided by 2 should be number1, not half.

The results are never output.

There is no return 0;

GaddA4.book Page 1288 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1289

B) There shouldn’t be a semicolon after the #include directive.

name should be declared as a string or a char array. If declared as string, a

#include <string> directive is needed.The statement cin.getline >> name; should read

cin >> name;The statement cin >> go; should read

cin.get(go);

Chapter 41. relational

3. false, true

5. true, false

7. false

9. !11. &&13. block (or local)

15. break17. if (y == 0)

x = 100;19. if (score >= 90)

cout << “Excellent”;else if (score >= 80)

cout << “Good”;else

cout << “Try Harder”;21. if(x < y)

q = a + b;else

q = x * 2;23. T, F, T

25. if (grade >= 0 && grade <= 100)cout << "The number is valid.";

27. if (hours < 0 || hours > 80)cout << "The number is not valid.";

29. if(sales < 10000)commission = .10;

else if (sales <= 15000)commission = .15;

elsecommission = .20;

GaddA4.book Page 1289 Monday, July 21, 2003 11:53 AM

1290 Appendix P: Answers to Odd-Numbered Review Questions

31. It should readif (!(x > 20))

33. It should use || instead of &&.

35. A) The first cout statement is terminated by a semicolon too early.

The definition of score1, score2, and score3 should end with a semicolon.

The following statement:

if (average = 100)should read:

if (average == 100)perfectScore is used before it is declared.

The following if statement should not be terminated with a semicolon:

if (perfectScore);The conditionally-executed block in the if statement shown above should end with a closing brace.

B) The conditionally-executed blocks in the if/else construct should be enclosed in braces.

The following statement:

cout << “The quotient of “ << num1 <<should read:

cout << “quotient of “ << num1;C) The trailing else statement should come at the end of the if/else construct.

D) A switch case construct cannot be used to test relational expressions.

An if/else if statement should be used instead.

Chapter 51. increment

3. prefix

5. body

7. pretest

9. infinite (or endless)

11. running total

13. sentinel

15. do-while17. initialization, test, update

19. break21. int num;

cin >> num;num *=2;while (num < 50){ cout << num << endl;

num *=2;}

GaddA4.book Page 1290 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1291

23. for (int x = 0; x <= 1000; x += 10)cout << x;

25. for (int row = 1; row <= 3; row++){ for (int star = 1; star <= 5; star++)

cout << ‘*’;cout << endl;

}27. char doAgain;

int sum = 0;

cout << "This code will increment sum 1 or more times.\n";do{ sum++;

cout << "Sum has been incremented. “ << “Increment it again(y/n)? "; cin >> doAgain;

} while (doAgain == 'y' || doAgain == 'Y');

cout << "Sum was incremented " << sum << " times.\n";29. for (int count = 0; count < 50; count++)

cout << "count is " << count << endl;31. Nothing will print. The erroneous semicolon after the while condition causes the while loop to

end there. Because x will continue to remain 1, x < 10 will remain true and the infinite loop can never be exited.

33. 2 4 6 8 10

35. A) The statement result = ++(num1 + num2); is invalid.

B) The while loop tests the variable again before any values are stored in it.

The while loop is missing its opening and closing braces.

37. A) The expression tested by the do-while loop should be choice == 1 instead of choice = 1.

B) The variable total is not initialized to 0.

The while loop does not change the value of count, so it iterates an infinite number of times.

Chapter 61. header

3. showValue(5);5. arguments

7. value

9. local

11. Global

13. local

15. return17. last

GaddA4.book Page 1291 Monday, July 21, 2003 11:53 AM

1292 Appendix P: Answers to Odd-Numbered Review Questions

19. reference

21. reference

23. parameter lists

25. Arguments appear in the parentheses of a function call. They are the actual values passed to a function. Parameters appear in the parentheses of a function heading. They are the variables that receive the arguments.

27. Function overloading means including more than one function in the same program that has the same name. C++ allows this providing the overloaded functions can be distinguished by having different parameter lists.

29. You want the function to change the value of a variable that is defined in the calling function.

31. Yes, but within that function only the local variable can be “seen” and accessed.

33. double half(double value){

return value / 2;}

35. void timesTen(int num){

cout << num * 10;}

37. void getNumber(int &number){

cout << “Enter an integer between 1 and 100): ”;cin >> number;while (number < 1 || number > 100){

cout << “This value is out of the allowed range.\n” << “Enter an integer between 1 and 100): ”;

}}

39. A) The data type of value2 and value3 must be declared.

The function is declared void but returns a value.

B) The assignment statement should read:

average = (value1 + value2 + value3) / 3.0;The function is declared as a float but returns no value.

C) width should have a default argument value.

The function is declared void but returns a value.

D) The parameter should be declared as:

int &valueThe cin statement should read:

cin >> value;E) The functions must have different parameter lists.

GaddA4.book Page 1292 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1293

Chapter 71. declared

3. members

5. structure tag

7. Inventory trivet = {555, 110};9. struct TempScale

{ float fahrenheit; float centigrade;};struct Reading{ int windSpeed; float humidity; TempScale temperature;};Reading today;today.windSpeed = 37;today.humidity = .32;today.temperature.fahrenheit = 32;today.temperature.centigrade = 0;

11. void inputReading(Reading &r){

cout << “Enter the wind speed: “;cin >> r.windSpeed;cout << “Enter the humidity: “;cin >> r.humidity;cout << “Enter the fahrenheit temperature: “;cin >> r.temperature.fahrenheit;cout << “Enter the centigrade temperature: “;cin >> r.temperature.centigrade;

}13. union Items

{char alpha;int num;long bigNum;float real;

};Items x;

15. num = 452;17. Procedural

19. Encapsulation

21. structure

23. private

25. instantiation

27. canine.cpp

GaddA4.book Page 1293 Monday, July 21, 2003 11:53 AM

1294 Appendix P: Answers to Odd-Numbered Review Questions

29. class (or structure)

31. return

33. destroyed

35. default

37. constructor, destructor

39. public

41. Inventory(string id = 0, string descrip = “new”, int qty = 0){ prodID = id; prodDescription = descrip; qtyInStock = qty; }

43. A) The structure declaration has no tag.

B) The semicolon is missing after the closing brace.

45. A) The Names structure needs a constructor that accepts 2 strings.

B) Structure members cannot be initialized in the structure declaration.

47. A) The semicolon should not appear after the word DumbBell in the class declaration.

Even though the weight member variable is private by default, it should be preceded with the private access specifier.

Because the setWeight member function is defined outside the class declaration, its function header must appear as:

void DumbBell::setWeight(int w)The line that reads: DumbBell.setWeight(200);should read: bar.setWeight(200);Because the weight member variable is private, it cannot be accessed outside the class, so the cout statement cannot legally output bar.weight. There needs to be a public getWeight() function that the main program can call.

B) Constructors must be public, not private.

Both constructors are considered the default constructor. This is illegal since there can be only one default constructor.

All the parameters in the Change function header should have a data type.

Chapter 81. size declarator

3. subscript

5. size declarator, subscript

7. initialization

9. initialization list

11. subscript

13. value

15. multidimensional

17. two

19. columns

GaddA4.book Page 1294 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1295

21. A) 10 B) 0 C) 9 D) 40

23. A) 3 B) 0

25. the starting address of the array

27. A) 8 B) 10 C) 80 D) sales[7][9] = 3.52;29. Car forSale[35] = { Car(“Ford”, “Taurus”, 2002, 21000),

Car(“Honda”,“Accord”, 2001, 11000), Car(“Jeep”, “Wrangler”,2004, 24000) };

31. for (int index = 0; index < 25; index++)array2[index] = array1[index]

33. int id[10];float grossPay[10];for (int emp = 0; emp < 10; emp++)

cout << id[emp] << “ ” << grossPay[emp] << endl;35. struct PopStruct

{ string name; long population;};PopStruct country[12];ifstream dataIn;dataIn.open(“pop.dat”);for (int index = 0; index < 12; index++){ getline(dataIn, country[index].name);

dataIn >> country[index].population;dataIn.ignore();

}dataIn.close();

37. A) The size declarator cannot be a variable.

B) The size declarator cannot be negative.

C) The initialization list must be enclosed in braces.

39. A) The parameter should be declared as int nums[].

B) The parameter must specify the number of columns, not the number of rows.

Chapter 91. linear

3. linear

5. N/2

7. first

9. 1/8

11. ascending

13. one

15. there were no number exchanges on the previous pass

GaddA4.book Page 1295 Monday, July 21, 2003 11:53 AM

1296 Appendix P: Answers to Odd-Numbered Review Questions

17. Bubble sort normally has to make many data exchanges to place a value in its correct position. Selection sort determines which value belongs in the position currently being filled with the cor-rectly ordered next value and then places that value directly there.

19.

20. Simply swap the corresponding two empName elements whenever two empID elements are swapped. Here is the pseudocode:

doSet swap flag to falsefor count = 0 to numEmp-1

if empID[count] > empID[count+1]Swap empID[count] with empID[count+1]Swap empName[count] with empName[count+1]

Set swap flag to trueend if

end forwhile swap flag is true // while there was a swap on the previous pass

21. A) Map directly from the desired ID to the array location as follows:

index = desiredID –101B) Do a linear search starting from the last array element and working backwards until the item

is found or until a smaller ID is encountered, which means the desired ID is not in the array. Here is the pseudocode:

index = 299 // start at the last elementposition = -1found = falseWhile index >= 0 and array[index].customerID >= desiredID and not found If array[index].customerID = desiredID

found = true position = index

End If Decrement indexEnd WhileReturn position

Array Size →50Elements

500Elements

10,000 Elements

100,000 Elements

10,000,000 Elements

Linear Search(Average Comparisons)

25 250 5,000 50,000 5,000,000

Linear Search(Maximum Comparisons)

50 500 10,000 100,000 10,000,000

Binary Search(Maximum Comparisons)

6 9 14 17 24

GaddA4.book Page 1296 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1297

Chapter 101. address

3. pointer

5. pointers

7. new

9. null

11. new

13. modify(i);15. Taking advantage of the exchange function of the previous question:

void switchEnds(int *array, int size){

exchange(array, array + size - 1);}

17. A) The variable should be declared as int *ptr;B) The assignment statement should read ptr = &x;C) The assignment statement should read ptr = &x;D) The assignment statement should read *ptr = 100;E) The last line should read

cout << *(numbers + 3) << endl;F) Multiplication cannot be performed on pointers.

G) Second statement should be float *fptr = &level;H) Order of the two statements should be reversed.

I) The * operator is used on the parameter, but it is not a pointer.

J) The second statement should read pint = new int;K) The last statement should be *pint = 100;L) The last line should read delete [] pint;M) The function returns the address of a variable that no longer exists.

Chapter 111. static

3. static

5. friend

7. Memberwise assignment

9. this

11. postfix increment (or decrement)

13. has-a

GaddA4.book Page 1297 Monday, July 21, 2003 11:53 AM

1298 Appendix P: Answers to Odd-Numbered Review Questions

15. copy constructoroverloaded = operatoroverloaded = operatorcopy constructor

17. Place the static keyword in the function’s prototype. Calls to the function are performed by con-necting the function name to the class name with the scope resolution operator.

19. In object composition, one object is a nested inside another object, which creates a has-a relation-ship. When a class is a friend of another class, there is no nesting. If a class A is a friend of a class B, member functions of A have access to all of B’s members, including the private ones.

21. If a pointer member is used to reference dynamically allocated memory, a memberwise assign-ment operation will only copy the contents of the pointer, not the section of memory referenced by the pointer. This means that two objects will exist with pointers to the same address in mem-ory. If either object manipulates this area of memory, the changes will show up for both objects. Also, if either object frees the memory, it will no longer contain valid information for either object.

23. If an object were passed to the copy constructor by value, a copy of the argument would have to be created before it can be passed to the copy constructor. But then the creation of the copy would require a call to the copy constructor with the original argument being passed by value. This pro-cess will continue indefinitely.

25. Dollars Dollars::operator++(); // PrefixDollars Dollars::operator++(int); // Postfix

27. ostream &operator<<(ostream &strm, Length obj);29. The overloaded operators offer a more intuitive way of manipulating objects, similar to the way

primitive data types are manipulated.31. members

33. Pet35. private

37. inaccessible, private, private

39. inaccessible, protected, public

41. last

43. A) The first line of the class declaration should read

class Car : public VehicleAlso, the class declaration should end in a semicolon.

B) The first line of the class declaration should read

class Truck : public VehicleC) The constructor function header should read

SnowMobile(int h, float w) : Vehicle(h)Also, the constructor parameter w is not used.

D) n should be passed to the base class constructor instead of numSeats.

GaddA4.book Page 1298 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1299

Chapter 121. isupper3. isdigit5. toupper7. cctype9. concatenate

11. strcpy13. strcmp15. atoi17. atof19. char lastChar(char *str)

{ //go to null terminator at endwhile (*str != 0)

str++;//back up to last characterstr--;return *str;

} 21. h

23. 9

25. Most compilers will print “not equal”. Some compilers store only one copy of each literal string: such compilers will print “equal” because all copies of “a” will be stored at the same address.

27. abrasion

29. A) This is probably a logic error because C-strings should not be compared with the == operator

B) atoi converts a string to an integer, not an integer to a string.

C) The compiler will not allocate enough space in string1 to accommodate both strings.

D) strcmp compares C-strings, not characters./

Chapter 131. file name

3. close

5. ifstream, ofstream, fstream7. ifstream9. ofstream people(“people.dat”);

11. fstream places(“places.dat”);13. pets.open(“pets.dat”, ios::in);

fstream pets(“pets.dat”, ios::in);15. null or 0

GaddA4.book Page 1299 Monday, July 21, 2003 11:53 AM

1300 Appendix P: Answers to Odd-Numbered Review Questions

17. cout19. getline21. put23. text, ASCII text

25. structures

27. read29. sequential

31. seekg33. tellg35. ios::beg37. ios::cur39. Open the file in binary mode, seek to the end, and then call tellg to determine the position of the

last byte:

ifstream inFile(fileName, ios::binary);inFile.seekg(0L, ios::end);long len = inFile.tellg();

41. Open the two files in binary mode, the first file for input and the second file for output. Seek to the end of the first file, and then keep backing up in the first file while writing to the second.

fstream inFile(file1name, ios::in | ios::binary);fstream outFile(file2name, ios::out | ios::binary);char ch;// seek to end of source file// and then position just before that last// characterinFile.seekg(0L, ios::end);inFile.seekg(-1, ios::cur); while (true){

// we are positioned before a character we need to readinFile.get(ch);

outFile.put(ch); // back up two characters to skip the character just read // and go to the character before it. inFile.seekg(-2, ios::cur); if (inFile.fail()) break; }

43. A) File should be opened as

fstream file(“info.dat”, ios::in | ios::out);or

fstream file;file.open(“info.dat”, ios::in | ios::out);

B) Should not specify ios::in with an ofstream object. Also, the if statement should read

if (!File)

GaddA4.book Page 1300 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1301

C) File access flags must be specified with fstream objects.

D) Should not write to a file opened for input. Also, the << operator should not be used on binary files.

E) The while statement should read

while(!dataFile.eof())F) The file access flag should be ios::in. Also, the last line should be

dataFile.getline(line, 81, ‘\n’);G) The get member function that takes a single parameter cannot be used to read a string: it can

only read single characters.

H) The file access flag should be ios::in. Also, the put member function cannot be used to write a string.

I) The file access flag should be ios::out. Also, the last line should read

dataFile.write(&dt, sizeof(date));J) The seekp member function should not be used since the file is opened for input.

Chapter 141. Indirect recursion. There are more function calls to keep up with.

3. When the problem is more easily solved with recursion, and a better program design is possible.

5. direct

7. A) 55

B) *******************************************************

C) evE dna madA

Chapter 151. abstract class

3. abstract

5. compile

7. polymorphism

9. cast

11. multiple

13. yes

GaddA4.book Page 1301 Monday, July 21, 2003 11:53 AM

1302 Appendix P: Answers to Odd-Numbered Review Questions

15. yes

17. pAnimal = new Dog; pDog = static_cast<Dog *>(pAnimal);19. A) A pure virtual function cannot have a body

B) The derived class needs to invoke the base class constructors

C) The BaseC class is the most derived class, so it needs to invoke the BaseA constructor because BaseA is a virtual base class.

Chapter 161. throw point

3. catch

5. template prefix

7. algorithms

9. associative

11. This solution uses recursion to perform the reversal. It needs the inclusion of the STL algorithm header file to allow use of swap.

template<class T>void reverse(T arr[ ], int size){ if (size >= 2)

{ swap(arr[0], arr[size-1]);reverse(arr+1, size-2);

}}

13. The two string objects will be concatenated. This works because the string class overloads the + operator.

15. A) The try block must appear before the catch block.

B) The cout statement should not appear between the try and catch blocks.

C) The return statement should read return number * number;D) The type parameter, T, is not used.

E) The type parameter T2 is not used.

F) The declaration should read SimpleVector<int> array(25);G) The statement should read cout << valueSet[2] << endl;

Chapter 17 1. head pointer

3. NULL

5. Inserting

7. circular

GaddA4.book Page 1302 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1303

9. void printFirst(ListNode *ptr){

if (!ptr) { cout << “Error”; exit(1);}cout << ptr->value;

}11. float lastValue(ListNode *ptr)

{if (!ptr) { cout << “Error”; exit(1);}if (ptr->next == NULL)

return ptr->value;else

return lastValue(ptr->next);}

13. ListNode *ListConcat(ListNode *list1, ListNode *list2){

if (list1 == NULL) return list2;

// Concatenate list2 to end of list1ListNode *ptr = list1;while (ptr->next != NULL)

ptr = ptr->next;ptr->next = list2;return list1;

}15. 56.4

17. A) The printList function should have a return type of void. Also, the use of the head pointer to walk down the list destroys the list: use an auxiliary pointer initialized to head instead.

B) Eventually the pointer p becomes NULL, at which time the attempt to access p->NULL will result in an error. Replace the test p->next in the while loop with p. Also, the function fails to declare a return type of void.

C) The function should declare a return type of void. Also, the function uses p++ erroneously in place of p=p->next when attempting to move to the next node in the list.

Chapter 181. Last In First Out

3. A static stack has all its storage allocated at once, when the stack is created. A dynamic stack allo-cates storage for each element as it is added. Normally, static stacks use array-based implementa-tions, whereas dynamic stacks use linked lists.

5. It takes an existing container and implements a new interface on top of it to adapt it to a different use.

7. First In First Out

GaddA4.book Page 1303 Monday, July 21, 2003 11:53 AM

1304 Appendix P: Answers to Odd-Numbered Review Questions

9. the front of the queue

11. lists and deques

13.

15. Assuming a circular array buffer:

17. Use two stacks, a main stack and an auxiliary stack. The main stack will store all items that are currently enqueued.� To enqueue a new item, push it onto the main stack.

� To dequeue an item, keep popping items from the main stack and pushing them onto the auxiliary stack until the main stack is empty, then pop and store the top element from the auxiliary stack into some variable X. Now keep popping items from the auxiliary stack and pushing them back onto the main stack till the auxiliary stack is empty. Return the stored item X.

� To check if the queue is empty, see if the main stack is empty.

Chapter 191. root node

3. leaf node

5. inorder, preorder, and postorder

7. struct TreeNode{

int value; TreeNode *left, *middle, *right;

};

Top of Stack

19

8 Bottom of Stack

10 9 12

rear front

GaddA4.book Page 1304 Monday, July 21, 2003 11:53 AM

Appendix P: Answers to Odd-Numbered Review Questions 1305

9. To traverse a ternary tree in preorder, visit the root, then traverse the left, middle, and right sub-trees.

preorder(ternarytree)If (ternarytree != NULL)

visit the rootpreorder left subtree of ternarytreepreorder middle subtree of ternarytreepreorder right subtree of ternarytree

End IfEnd preorder

11. We must decide whether to visit the root right after the traversal of the left subtree or right after the traversal of the middle subtree.

13. int largest(TreeNode *tree) Set a pointer p to the root node of treeWhile node at p has a right child Do

Set p to the right child of the node at pEnd Whilereturn value in the node at p

End largest15. int smallest(TreeNode *tree)

Set a pointer p to the root node of treeWhile node at p has a left child Do

Set p to the left child of the node at pEnd Whilereturn value in the node at p

End smallest17. 3 7 9 10 12 14 18 20 22 24 30

19. 3 10 9 7 14 20 18 30 24 22 12

GaddA4.book Page 1305 Monday, July 21, 2003 11:53 AM

GaddA4.book Page 1306 Monday, July 21, 2003 11:53 AM