Download presentation
Presentation is loading. Please wait.
Published byMelissa Flowers Modified over 6 years ago
1
Chapter 1. Introduction to Computers and Programming
2
1.1 Why Program? Computers can do many different jobs because they are programmable.
3
1.2 Computer Systems: Hardware and Software
All computer systems consist of similar hardware devices and software components. This section provides an overview of standard computer hardware and software organization.
4
Hardware The CPU Main Memory Secondary Storage Input Devices
Output Devices
5
Figure 1.1 Central Processing Input Unit Device Output Device Main
Memory Output Device
6
Arithmetic and Logic Unit
Figure 1.2 Instruction (Input) Arithmetic and Logic Unit Result (Output) Control Unit
7
Software Operating Systems Application Software Single tasking
Multi-tasking Application Software
8
1.3 Programs and Programming Languages
What is a program? A set of instructions a computer follows in order to perform a task. A programming language is a special language used to write computer programs.
9
Program 1-1 // This program calculates the user’s pay.
#include <iostream.h> void main(void) { float hours, rate, pay; cout << “How many hours did you work? ”; cin >> hours; cout << “How much do you get paid per hour? ”; cin >> rate; pay = hours * rate; cout << “You have earned $” << pay << endl; }
10
Program Output How many hours did you work? 10
How much do you get paid per hour? 15 You have earned $150
11
Programming Languages
Figure 1-4 High level (Close to Human Language) Low level (Machine Language)
12
Table 1-1
13
1.4 What is a Program Made of?
There are certain elements that are common to all programming languages. Key Words Programmer-Defined Symbols Operators Punctuation
14
Language Elements, Table 1-2
15
Lines and Statements cout << “How many hours did you work?”;
16
Variables A storage location in the computer’s memory for holding a piece of information. Symbolic names that represent locations in the computer’s random-access memory.
17
Variable Declarations
Two types of information: numbers and characters Numbers may be integers or floating-point numbers The statement below creates three variables in memory named hours, rate, and pay that each can store a floating point number float hours, rate, pay;
18
1.5 Input, Processing, and Output
cin >> hours; Processing: pay = hours * rate; Output cout<<“You have earned $”<<pay;
19
1.6 The Programming Process
The programming process consists of several steps, which include design, creation, testing and debugging activities.
20
Designing and Creating a Program
1. Clearly define what the program is to do 2. Visualize the program running on the computer. 3. Design a flowchart or hierarchy chart 4. Check the flowchart or hierarchy chart for logical errors.
21
5. Write a pseudocode version of the program.
6. Check the pseudocode for errors. 7. Write the actual program on paper. 8. Desk-check the program for errors. 9. Enter the code and compile it. 10. Correct any errors found during compilation. Repeat steps 9 and 10 as many times as necessary.
22
11. Run the program with test data for input.
Correct any errors found while running the program. Repeat steps 9 through 12 as many times as necessary. Validate the results of the program.
23
1.7 Procedural and Object-Oriented Programming
Procedural programming and object-oriented programming are two ways of thinking about software development and program design.
24
Chapter 2. Introduction to C++
25
2.1 The Parts of a C++ Program
C++ programs have parts and components that serve specific purposes.
26
Program 2-1 Program Output: Programming is great fun!
//A simple C++ program #include <iostream.h> void main (void) { cout<< “Programming is great fun!”; } Program Output: Programming is great fun!
27
Table 2-1
28
2.2 The cout Object Use the cout object to display information on the computer’s screen. The cout object is referred to as the standard output object. Its job is to output information using the standard output device
29
Programming is great fun!
// A simple C++ program #include <iostream.h> void main (void) { cout<< “Programming is “ << “great fun!”; } Output: Programming is great fun!
30
Programming is great fun!
// A simple C++ program #include <iostream.h> void main (void) { cout<< “Programming is “; cout << “ great fun!”; } Output: Programming is great fun!
31
Program 2-4 Program Output
// An unruly printing program #include <iostream.h> void main(void) { cout << "The following items were top sellers"; cout << "during the month of June:"; cout << "Computer games"; cout << "Coffee"; cout << "Aspirin"; } Program Output The following items were top sellersduring the month of June:Computer gamesCoffeeAspirin
32
New lines cout does not produce a newline at the end of a statement
To produce a newline, use either the stream manipulator endl or the escape sequence \n
33
Program 2-5 // A well-adjusted printing program
#include <iostream.h> void main(void) { cout << "The following items were top sellers" << endl; cout << "during the month of June:" << endl; cout << "Computer games" << endl; cout << "Coffee" << endl; cout << "Aspirin" << endl; }
34
Program Output The following items were top sellers
during the month of June: Computer games Coffee Aspirin
35
Program 2-6 // Another well-adjusted printing program
#include <iostream.h> void main(void) { cout << "The following items were top sellers" << endl; cout << "during the month of June:" << endl; cout << "Computer games" << endl << "Coffee"; cout << endl << "Aspirin" << endl; }
36
Program Output The following items were top sellers
during the month of June: Computer games Coffee Aspirin
37
Program 2-7 // Yet another well-adjusted printing program
#include <iostream.h> using namespace std; void main(void) { cout << "The following items were top sellers\n"; cout << "during the month of June:\n"; cout << "Computer games\nCoffee"; cout << "\nAspirin\n"; }
38
Program Output The following items were top sellers
during the month of June: Computer games Coffee Aspirin
39
Table 2-2
40
2.3 The #include Directive
The #include directive causes the contents of another file to be inserted into the program Preprocessor directives are not C++ statements and do not require semicolons at the end
41
2.5 Variables and Constants
Variables represent storage locations in the computer’s memory. Constants are data items whose values do not change while the program is running. Every variable must have a declaration.
42
Program Output: The value is 5 Program 2-8 #include <iostream.h>
void main(void) { int value; value = 5; cout << “The value is “ << value << endl; } Program Output: The value is 5
43
Assignment statements:
Value = 5; //This line is an assignment statement. The assignment statement evaluates the expression on the right of the equal sign then stores it into the variable named on the left of the equal sign The data type of the variable was in integer, so the data type of the expression on the right should evaluate to an integer as well.
44
Constants A variable is called a “variable” because its value may be changed. A constant, on the other hand, is a data item whose value does not change during the program’s execution.
45
Program 2-10 #include <iostream.h> void main (void) {
int apples; apples = 20; cout<< “Today we sold “ << apples << “ bushels\n”; cout << “of apples.\n”; }
46
Where are the constants in program 2-10?
Program Output Today we sold 20 bushels of apples. Where are the constants in program 2-10?
47
Constants from Program 2-10
48
2.6 Focus on Software Engineering: Identifiers
Must not be a key word Should be mnemonic (give an indication of what the variable is used for) The first character must be a letter or an underscore The remaining may be letters, digits, or underscores Upper and lower case letters are distinct
49
Table 2-3 The C++ Key Words
50
Table 2-4 Some Variable Names
Legal or Illegal? dayOfWeek Legal 3dGraph Illegal. Cannot begin with a digit. _employee_num june1997 Mixture#3 Illegal. Cannot use # symbol.
51
2.7 Integer Data Types There are many different types of data. Variables are classified according to their data type, which determines the kind of information that may be stored in them. Integer variables only hold whole numbers.
52
Table 2-5
53
Program 2-11 // This program has variables of several of the integer types. #include <iostream.h> void main(void) { int checking; unsigned int miles; long days; checking = -20; miles = 4276; days = ; cout << "We have made a long journey of " << miles; cout << " miles.\n"; cout << "Our checking account balance is " << checking; cout << "\nExactly " << days << " days ago Columbus "; cout << "stood on this spot.\n"; }
54
Program Output We have made a long journey of 4276 miles.
Our checking account balance is -20 Exactly days ago Columbus stood on this spot.
55
Program 2-12 // This program shows three variables declared on the same // line. #include <iostream.h> void main(void) { int floors,rooms,suites; floors = 15; rooms = 300; suites = 30; cout << "The Grande Hotel has " << floors << " floors\n"; cout << "with " << rooms << " rooms and " << suites; cout << " suites.\n"; }
56
Program Output The Grande Hotel has 15 floors
with 300 rooms and 30 suites.
57
Hexadecimal and Octal Constants
Hexadecimal numbers are preceded by 0x Hexadecimal F4 would be expressed in C++ as 0xF4 Octal numbers are preceded by a 0 Octal 31 would be written as 031
58
2.8 The char Data Type Usually 1 byte long
Internally stored as an integer ASCII character set shows integer representation for each character ‘A’ == 65, ‘B’ == 66, ‘C’ == 67, etc. Single quotes denote a character, double quotes denote a string
59
Program 2-13 // This program demonstrates the close relationship between // characters and integers. #include <iostream.h> void main(void) { char letter; letter = 65; cout << letter << endl; letter = 66; }
60
Program Output A B
61
Program 2-14 // This program uses character constants
#include <iostream.h> void main(void) { char letter; letter = 'A'; cout << letter << endl; letter = 'B'; }
62
Program Output A B
63
C-Strings C-Strings are consecutive sequences of characters and can occupy several bytes of memory. C-Strings always have a null terminator at the end. This marks the end of the string. Escape sequences are always stored internally as a single character.
64
Program 2-15 // This program uses character constants
#include <iostream.h> void main(void) { char letter; letter = 'A'; cout << letter << '\n'; letter = 'B'; }
65
Program Output A B
66
Review key points regarding characters, strings, and C-strings:
Printable characters are internally represented by numeric codes. Most computers use ASCII codes for this purpose. Characters occupy a single byte of memory. C-Strings are consecutive sequences of characters and can occupy several bytes of memory. C-Strings always have a null terminator at the end. This marks the end of the C-string. Character constants are always enclosed in single quotation marks. String constants are always enclosed in double quotation marks. Escape sequences are always stored internally as a single character.
67
2.9 The C++ string Class The string class is an abstract data type.
It provides capabilities that make working with strings easy and intuitive. You must us the #include <string> statement.
68
2.10 Floating Point Data Types
Floating point data types are used to declare variables that can hold real numbers
69
Table 2-7
70
Program 2-17 // This program uses floating point data types
#include <iostream.h> void main(void) { float distance; double mass; distance = E11; mass = 1.989E30; cout << "The Sun is " << distance << " kilometers away.\n"; cout << "The Sun\'s mass is " << mass << " kilograms.\n"; }
71
Program Output The Sun is 1.4959e+11 kilometers away.
The Sun's mass is 1.989e+30 kilograms.
72
Floating Point Constants
May be expressed in a variety of ways E notation decimal notation (no commas)
73
2.11 The bool Data Type Boolean variables are set to either true or false
74
Program 2-18 #include <iostream.h> void main (void) {
bool boolValue; boolValue = true; cout << boolValue << endl; boolValue = false; }
75
Program Output 1 Internally, true is represented as the number 1 and false is represented by the number 0.
76
2.12 Focus on Software Engineering: Determining the Size of a Data Type
The sizeof operator may be used to determine the size of a data type on any system. cout << “The size of an integer is “ << sizeof(int);
77
Program 2-19 #include <iostream.h> void main (void) {
long double apple; cout << “The size of an integer is “ << sizeof(int); cout << “ bytes.\n”; cout << “The size of a long integer is “ << sizeof(long); cout << “An apple can be eaten in “ << sizeof(apple); cout << “ bytes!\n”; }
78
Program Output The size of an integer is 4 bytes.
The size of a long integer is 4 bytes. An apple can be eaten in 8 bytes!
79
2.13 Focus on Software Engineering: Variable Assignment and Initialization
An assignment operation assigns, or copies, a value into a variable. When a value is assigned to a variable as part of the variable’s declaration, it is called an initialization.
80
Program output: Month 2 has 28 days. Program 2-20
#include <iostream.h> void main (void) { int month = 2, days = 28; cout << “Month “ << month << “ has “ << days << “ days.\n”; } Program output: Month 2 has 28 days.
81
2.14 Focus on Software Engineering: Scope
A variable’s scope is the part of the program that has access to the variable. A variable must be declared before it is used.
82
Program 2-21 // This program can't find its variable
#include <iostream.h> void main(void) { cout << Value; int Value = 100; }
83
2.15 Arithmetic Operators There are many operators for manipulating numeric values and performing arithmetic operations. Generally, there are 3 types of operators: unary, binary, and ternary. Unary operators operate on one operand Binary operators require two operands Ternary operators need three operands
84
Table 2-8
85
Program 2-22 // This program calculates hourly wages
// The variables in function main are used as follows: // regWages: holds the calculated regular wages. // basePay: holds the base pay rate. // regHours: holds the number of hours worked less overtime. // otWages: holds the calculated overtime wages. // otPay: holds the payrate for overtime hours. // otHours: holds the number of overtime hours worked. // totalWages: holds the total wages. #include <iostream.h> void main(void) { float regWages, basePay = 18.25, regHours = 40.0; float otWages, otPay = 27.78, otHours = 10; float totalWages; regWages = basePay * regHours; otWages = otPay * otHours; totalWages = regWages + otWages; cout << "Wages for this week are $" << totalWages << endl; }
86
2.16 Comments Comments are notes of explanation that document lines or sections of a program. Comments are part of a program, but the compiler ignores them. They are intended for people who may be reading the source code. Commenting the C++ Way // Commenting the C Way /* */
87
Program 2-23 (The remainder of this program is left out.)
// PROGRAM: PAYROLL.CPP // Written by Herbert Dorfmann // This program calculates company payroll // Last modification: 3/30/96 #include <iostream.h> void main(void) { float payRate; // holds the hourly pay rate float hours; // holds the hours worked int empNum; // holds the employee number (The remainder of this program is left out.)
88
Program 2-24 (The remainder of this program is left out.)
// PROGRAM: PAYROLL.CPP // Written by Herbert Dorfmann // Also known as "The Dorfmiester" // Last modification: 3/30/96 // This program calculates company payroll. // Payroll should be done every Friday no later than // 12:00 pm. To start the program type PAYROLL and // press the enter key. #include <iostream.h> // Need the iostream file because // the program uses cout. void main(void) // This is the start of function main. { // This is the opening brace for main. float payRate; // payRate is a float variable. // It holds the hourly pay rate. float hours; // hours is a float variable too. // It holds the hours worked. int empNum; // empNum is an integer. // It holds the employee number. (The remainder of this program is left out.)
89
Program 2-25 (The remainder of this program is left out.) /*
PROGRAM: PAYROLL.CPP Written by Herbert Dorfmann This program calculates company payroll Last modification: 3/30/96 */ #include <iostream.h> void main(void) { float payRate; /* payRate holds hourly pay rate */ float hours; /* hours holds hours worked */ int empNum; /* empNum holds employee number */ (The remainder of this program is left out.)
90
Program 2-26 (The remainder of this program is left out.) /*
PROGRAM: PAYROLL.CPP Written by Herbert Dorfmann This program calculates company payroll Last modification: 3/30/96 */ #include <iostream.h> void main(void) { float payRate; // payRate holds the hourly pay rate float hours; // hours holds the hours worked int empNum; // empNum holds the employee number (The remainder of this program is left out.)
91
2.17 Focus on Software Engineering: Programming Style
Program style refers to the way a programmer uses identifiers, spaces, tabs, blank lines, and punctuation characters to visually arrange a program’s source code. Generally, C++ ignores white space. Indent inside a set of braces. Include a blank line after variable declarations.
92
Program 2-27 Program Output
#include <iostream.h> void main(void){float shares=220.0;float avgPrice=14.67;cout <<"There were "<<shares<<" shares sold at $"<<avgPrice<<" per share.\n";} Program Output There were 220 shares sold at $14.67 per share.
93
Program 2-28 Program Output
// This example is much more readable than Program 2-26. #include <iostream.h> void main(void) { float shares = 220.0; float avgPrice = 14.67; cout << "There were " << shares << " shares sold at $"; cout << avgPrice << " per share.\n"; } Program Output There were shares sold at $14.67 per share.
94
Chapter 3. Expressions and Interactivity
95
3.1 The cin Object The cin object reads information types at the keyboard. cin is the standard input object Notice the >> and << operators appear to point in the direction information is flowing.
96
Program 3-1 #include <iostream.h> void main(void) {
int length, width, area; cout <<"This program calculates the area of a rectangle.\n"; cout <<"What is the length of the rectangle? "; cin>>length; cout <<"What is the width of the rectangle? "; cin>>width; area = length * width; cout <<"The area of the rectangle is " << area << ".\n"; }
97
Program Output This program calculates the area of a rectangle. What is the length of the rectangle? 10 [Enter] What is the width of the rectangle? 20 [Enter] The area of the rectangle is 200.
98
Program 3-2 // This program reads the length and width of a rectangle.
// It calculates the rectangle's area and displays // the value on the screen. #include <iostream.h> void main(void) { int length, width, area; cin >> length; cin >> width; area = length * width; cout << "The area of the rectangle is " << area << endl; }
99
Entering Multiple Values
The cin object may be used to gather multiple values at once.
100
Program 3-3 #include <iostream.h> void main(void) {
int length, width, area; cout <<"This program calculates the area of a rectangle.\n"; cout <<"Enter the length and width of the rectangle separated by a space. \n"; cin >> length>> width; area = length * width; cout <<"The area of the rectangle is " << area << endl; }
101
This program calculates the area of a rectangle.
Program Output This program calculates the area of a rectangle. Enter the length and width of the rectangle separated by a space. 10 20 [Enter] The area of the rectangle is 200
102
Program 3-4 // This program demonstrates how cin can read multiple values // of different data types. #include <iostream.h> void main(void) { int whole; float fractional; char letter; cout << "Enter an integer, a float, and a character: "; cin >> whole >> fractional >> letter; cout << "whole: " << whole << endl; cout << "fractional: " << fractional << endl; cout << "letter: " << letter << endl; }
103
Program Output Enter an integer, a float, and a character: b [Enter] whole: 4 fractional: 5.7 letter: b
104
Reading Strings cin can read strings as well as numbers.
Strings are stored in character arrays. char Company[12];
105
Program 3-5 #include <iostream.h> #include<string>
void main(void) { string name; cout << "What is your name? "; cin >> name; cout << "Good morning " << name << endl; }
106
What is your name? Charlie [Enter] Good morning Charlie
Program Output What is your name? Charlie [Enter] Good morning Charlie
107
Program 3-6 // This program demonstrates how cin can read a
// string into a character array #include <iostream.h> void main(void) { char name[21] ; cout << "What is your name? "; cin >> name; cout << "Good morning " << name << endl; }
108
What is your name? Charlie [Enter] Good morning Charlie
Program Output What is your name? Charlie [Enter] Good morning Charlie
109
Program 3-7 // This program reads two strings into two character arrays. #include <iostream.h> void main(void) { char first[16], last[16]; cout << "Enter your first and last names and I will\n"; cout << "reverse them.\n"; cin >> first >> last; cout << last << ", " << first << endl; }
110
Program Output Enter your first and last names and I will reverse them. Johnny Jones [Enter] Jones, Johnny
111
Notes on strings: If a character array is intended to hold strings, it must be at least one character larger than the largest string that will be stored in it. The cin object will let the user enter a string larger than the array can hold. If this happens, the string will overflow the array’s boundaries and destroy other information in memory. If you wish the user to enter a string that has spaces in it, you cannot use this input method.
112
3.2 Focus on Software Engineering: Mathematical Expressions
C++ allows you to construct complex mathematical expressions using multiple operators and grouping symbols.
113
Program 3-7 // This program reads two strings into two character arrays #include <iostream.h> void main(void) { char first[16], last[16]; cout << Enter your first and last names and I will\n"; cout << "reverse them.\n"; cin >> first >> last; cout << last << ", " << first << endl; }
114
Program 3-7 Output with Example Input
Enter your first and last names and I will reverse them. Johnny Jones [Enter] Jones, Johnny
115
Program 3-8 // This program asks the user to enter the numerator
// and denominator of a fraction and it displays the // decimal value #include <iostream.h> void main(void) { float numerator, denominator; cout << "This program shows the decimal value of "; cout << "a fraction.\n"; cout << “Enter the numerator: “; cin >> numerator; cout << “Enter the denominator: “; cin >> denominator; cout << “The decimal value is “; cout << (numerator / denominator); }
116
Program Output for Program 3-8 with Example Input
This program shows the decimal value of a fraction. Enter the numerator: 3 [Enter] Enter the denominator: 6 [Enter] The decimal value is
117
Table 3-1 Precedence of Arithmetic Operators (Highest to Lowest)
(unary negation) - * / % + -
118
Table 3-2 Some Expressions
119
Associativity If two operators sharing an operand have the same precedence, they work according to their associativity, either right to left or left to right
121
Converting Algebraic Expressions to Programming Statements
122
No Exponents Please! C++ does not have an exponent operator.
Use the pow() library function to raise a number to a power. Will need #include <math.h> for pow() function. area = pow(4,2) // will store 42 in area
123
Program 3-9 // This program calculates the area of a circle.
// The formula for the area of a circle is Pi times // the radius squared. Pi is #include <iostream.h> #include <math.h> // needed for the pow function void main(void) { double area, radius; cout << "This program calculates the area of a circle.\n"; cout << "What is the radius of the circle? "; cin >> radius; area = * pow(radius,2); cout << "The area is " << area; }
124
Program 3-9 Output With Example Input
This program calculates the area of a circle. What is the radius of the circle? 10[Enter] The area is
125
3.3 When you Mix Apples and Oranges: Type Coercion
When an operator’s operands are of different data types, C++ will automatically convert them to the same data type.
126
Type Coercion Rules: Rule 1: Chars, shorts, and unsigned shorts are automatically promoted to int. Rule 2: When an operator works with two values of different data types, the lower-ranking value is promoted to the type of the higher-ranking value. Rule 3: When the final value of an expression is assigned to a variable, it will be converted to the data type of the variable.
127
3.4 Overflow and Underflow
When a variable is assigned a value that is too large or too small in range for that variable’s data type, the variable overflows or underflows. Overflow - when a variable is assigned a number that is too large for its data type Underflow - when a variable is assigned a number that is too small for its data type
128
Program 3-10 // This program demonstrates integer underflow and
// overflow #include <iostream.h> void main(void) { short testVar = 32767; cout << testVar << endl; testVar = testVar + 1; testVar = testVar - 1; }
129
Program Output 32767 -32768
130
Program 3-11 // This program can be used to see how your system
// handles floating point overflow and underflow. #include <iostream.h> void main(void) { float test; test = 2.0e38 * 1000; // Should overflow test cout << test << endl; test = 2.0e-38 / 2.0e38; }
131
3.5 The Typecast Operator The typecast operator allows you to perform manual data type conversion. Val = int(number); //If number is a floating //point variable, it will be //truncated to an integer and //stored in the variable Val
132
Program 3-12 #include <iostream.h> void main(void) {
int months, books; float perMonth; cout << "How many books do you plan to read? "; cin >> books; cout << "How many months will it take you to read them? "; cin >> months; perMonth = float(books) / months; cout << "That is " << perMonth << " books per month.\n"; }
133
Program Output How many books do you plan to read? 30 [Enter] How many months will it take you to read them? 7 [Enter] That is books per month.
134
Typecast Warnings In Program 3-11, the following statement would still have resulted in integer division: perMonth = float(books / months); Because the division is performed first and the result is cast to a float.
135
Program 3-13 // This program uses a typecast operator to print
// a character from a number. #include <iostream.h> void main(void) { int number = 65; cout << number << endl; cout << char(number) << endl; }
136
Program Output 65 A
137
The Power of Constants Constants may be given names that symbolically represent them in a program.
138
Program 3-14 // This program calculates the area of a circle.
#include <iostream.h> #include <math.h> void main(void) { const float pi = ; double area, radius; cout << "This program calculates the area of a circle.\n"; cout << "What is the radius of the circle? "; cin >> radius; area = pi * pow(radius,2); cout << "The area is " << area; }
139
The #define Directive The older C-style method of creating named constants is with the #define directive, although it is preferable to use the const modifier. #define PI is roughly the same as const float PI= ;
140
Program 3-15 #include <iostream.h>
#include <math.h> // needed for pow function #define PI void main(void) { double area, radius; cout << "This program calculates the area of a circle.\n"; cout << "What is the radius of the circle? "; cin >> radius; area = PI * pow(radius, 2); cout << "The area is " << area; }
141
3.7 Multiple Assignment and Combined Assignment
Multiple assignment means to assign the same value to several variables with one statement. A = B = C = D = 12; Store1 = Store2 = Store3 = BegInv;
142
Program 3-16 // The program tracks the inventory of three widget stores // that opened at the same time. Each store started with the // same number of widgets in inventory. By subtracting the // number of widgets each store has sold from its inventory, // the current inventory can be calculated. #include <iostream.h> void main(void) { int begInv, sold, store1, store2, store3; cout << “One week ago, 3 new widget stores opened\n"; cout << “at the same time with the same beginning\n"; cout << “inventory. What was the beginning inventory? "; cin >> begInv; store1 = store2 = store3 = begInv;
143
Program 3-16 Continued cin >> sold;
cout << "How many widgets has store 1 sold? "; cin >> sold; store1 = store1 – sold; //Subtract sold from store1 cout << "How many widgets has store 2 sold? "; store2 = store2 – sold; //Subtract sold from store2 cout << "How many widgets has store 3 sold? "; store3 = store3 – sold; //Subtract sold from store 3 cout << "Store1: " << store1 << endl; cout << "Store2: " << store2 << endl; cout << "Store3: " << store3 << endl; }
144
Program 3-16 Output with Example Input
One week ago, 3 new widget stores opened at the same time with the same beginning inventory. What was the beginning inventory? 100 [Enter] How many widgets has store 1 sold? 25 [Enter] How many widgets has store 2 sold? 15 [Enter] How many widgets has store 3 sold? 45 [Enter] The current inventory of each store: Store 1: 75 Store 2: 85 Store 3: 55
145
Table 3-8
146
Table 3-9
147
Program 3-17 // The program tracks the inventory of three widget stores // that opened at the same time. Each store started with the // same number of widgets in inventory. By subtracting the // number of widgets each store has sold from its inventory, // the current inventory can be calculated. #include <iostream.h> void main(void) { int begInv, sold, store1, store2, store3; cout << “One week ago, 3 new widget stores opened\n"; cout << “at the same time with the same beginning\n"; cout << “inventory. What was the beginning inventory? "; cin >> begInv; store1 = store2 = store3 = begInv;
148
Program 3-17 Continued cin >> sold;
cout << "How many widgets has store 1 sold? "; cin >> sold; store1 -= sold; //Subtract sold from store1 cout << "How many widgets has store 2 sold? "; store2 -= sold; //Subtract sold from store2 cout << "How many widgets has store 3 sold? "; store3 -= sold; //Subtract sold from store 3 cout << "Store1: " << store1 << endl; cout << "Store2: " << store2 << endl; cout << "Store3: " << store3 << endl; }
149
Program 3-17 Output with Example Input
One week ago, 3 new widget stores opened at the same time with the same beginning inventory. What was the beginning inventory? 100 [Enter] How many widgets has store 1 sold? 25 [Enter] How many widgets has store 2 sold? 15 [Enter] How many widgets has store 3 sold? 45 [Enter] The current inventory of each store: Store 1: 75 Store 2: 85 Store 3: 55
150
3.8 Formatting Output The cout object provides ways to format data as it is being displayed. This affects the way data appears on the screen.
151
Program 3-18 #include<iostream.h> void main(void) {
int num1 = 2897, num2 = 5,num3 = 837, num4 = 34, num5 = 7, num6 = 1623, num7 = 390, num8 = 3456, num9 = 12; // Display the first row of numbers cout << num1 << " "; cout << num2 << " "; cout << num3 << endl; // Display the second row of numbers cout << num4 << " "; cout << num5 << " "; cout << num6 << endl; // Display the third row of numbers cout << num7 << " "; cout << num8 << " "; cout << num9 << endl; }
152
Program Output
153
Program 3-19 // This program displays three rows of numbers.
#include <iostream.h> #include <iomanip.h> // for setw function void main(void) { int num1 = 2897, num2 = 5, num3 = 837, num4 = 34, num5 = 7, num6 = 1623, num7 = 390, num8 = 3456, num9 = 12; // Display the first row of numbers cout << setw(4) << num1 << " "; cout << setw(4) << num2 << " "; cout << setw(4) << num3 << endl;
154
Program continues // Display the second row of numbers
cout << setw(4) << num4 << " "; cout << setw(4) << num5 << " "; cout << setw(4) << num6 << endl; // Display the third row of numbers cout << setw(4) << num7 << " "; cout << setw(4) << num8 << " "; cout << setw(4) << num9 << endl; }
155
Program Output
156
Program 3-20 // This program demonstrates the setw manipulator being
// used with values of various data types. #include <iostream.h> #include <iomanip.h> void main(void) { int intValue = 3928; float floatValue = 91.5; char cStringValue[] = "John J. Smith"; cout << "(" << setw(5) << intValue << ")" << endl; cout << "(" << setw(8) << floatValue << ")" << endl; cout << "(" << setw(16) << cStringValue << ")" << endl; }
157
Program Output ( 3928) ( ) ( John J. Smith)
158
Precision Floating point values may be rounded to a number of significant digits, or precision, which is the total number of digits that appear before and after the decimal point.
159
Program 3-21 // This program demonstrates how setprecision rounds a
// floating point value #include <iostream.h> #include <iomanip.h> void main(void) { float quotient, number1 = , number2 = 26.91; quotient = number1 / number2; cout << quotient << endl; cout << setprecision(5) << quotient << endl; cout << setprecision(4) << quotient << endl; cout << setprecision(3) << quotient << endl; cout << setprecision(2) << quotient << endl; cout << setprecision(1) << quotient << endl; }
160
Program Output 4.9188 4.919 4.92 4.9 5
161
Table 3-11
162
Program 3-22 // This program asks for sales figures for 3 days. The
// total sales is calculated and displayed in a table #include <iostream.h> #include <iomanip.h> void main(void) { float day1, day2, day3, total; cout << "Enter the sales for day 1: "; cin >> day1; cout << "Enter the sales for day 2: "; cin >> day2;
163
cout << "Enter the sales for day 3: ";
Program Continues cout << "Enter the sales for day 3: "; cin >> day3; total = day1 + day2 + day3; cout << "\nSales Figures\n"; cout << " \n"; cout << setprecision(5); cout << “Day 1: " << setw(8) << day1 << endl; cout << “Day 2: " << setw(8) << day2 << endl; cout << “Day 3: " << setw(8) << day3 << endl; cout << “Total: " << setw(8) << total << endl; }
164
Program Output Enter the sales for day 1: [Enter] Enter the sales for day 2: [Enter] Enter the sales for day 3: [Enter] Sales Figures Day 1: Day 2: Day 3: Total:
165
Program 3-23 //This program asks for sales figures for 3 days. The
// total sales is calculated and displayed in a table. #include <iostream.h> #include <iomanip.h> void main(void) { float day1, day2, day3, total; cout << "Enter the sales for day 1: "; cin >> day1; cout << "Enter the sales for day 2: "; cin >> day2; cout << "Enter the sales for day 3: "; cin >> day3; total = day1 + day2 + day3;
166
cout << "\nSales Figures\n";
Program Continues cout << "\nSales Figures\n"; cout << "------\n"; cout << setprecision(2) << setiosflags(ios::fixed); cout << “Day 1: " << setw(8) << day1 << endl; cout << “Day 2: " << setw(8) << day2 << endl; cout << “Day 3: " << setw(8) << day3 << endl; cout << "Total: " << setw(8) << total << endl; }
167
Program Output Enter the sales for day 1: 1321.87 [Enter]
Sales Figures Day 1: Day 2: Day 3: Total:
168
IOS Flags setiosflags manipulator can be used to format output in a variety of ways, depending on which flag is specified. setiosflags(ios::fixed) will cause all subsequent numbers to be printed in fixed point notation
169
Program 3-24 // This program asks for sales figures for 3 days. The
// total sales is calculated and displayed in a table. #include <iostream.h> #include <iomanip.h> void main(void) { float day1, day2, day3, total; cout << "Enter the sales for day 1: "; cin >> day1; cout << "Enter the sales for day 2: "; cin >> day2;
170
cout << "Enter the sales for day 3: ";
Program continues cout << "Enter the sales for day 3: "; cin >> day3; total = day1 + day2 + day3; cout << "\nSales Figures\n"; cout << " \n"; cout << setprecision(2) << setiosflags(ios::fixed | ios::showpoint); cout << “Day 1: " << setw(8) << day1 << endl; cout << “Day 2: " << setw(8) << day2 << endl; cout << “Day 3: " << setw(8) << day3 << endl; cout << "Total: " << setw(8) << total << endl; }
171
Program Output Enter the sales for day 1: 2642.00 [Enter]
Sales Figures Day 1: Day 2: Day 3: Total:
172
Table 3-12
173
Formatting Output With Member Functions
cout.width(5); //calls the width member // function, same as // setw(5) cout.precision(2); //sets precision to // 2 significant // digits // The next statement works like // setiosflags(ios::fixed) cout.setf(ios::fixed);
174
Program 3-25 // This program asks for sales figures for 3 days. The
// total sales is calculated and displayed in a table. #include <iostream.h> #include <iomanip.h> void main(void) { float day1, day2, day3, total; cout << "Enter the sales for day 1: "; cin >> day1; cout << "Enter the sales for day 2: "; cin >> day2; cout << "Enter the sales for day 3: "; cin >> day3;
175
Program continues total = day1 + day2 + day3; cout.precision(2);
cout.setf(ios::fixed | ios::showpoint); cout << "\nSales Figures\n"; cout << " \n"; cout << “Day 1: "; cout.width(8); cout << day1 << endl; cout << “Day 2: "; cout << day2 << endl;
176
Program continues cout << “Day 3: "; cout.width(8);
cout << day3 << endl; cout << "Total: "; cout << total << endl; }
177
Program Output Enter the sales for day 1: 2642.00 [Enter]
Sales Figures Day 1: Day 2: Day 3: Total:
178
Program 3-26 // This program asks for sales figures for 3 days. The
// total sales is calculated and displayed in a table. #include <iostream.h> #include <iomanip.h> void main(void) { float day1, day2, day3, total; cout << "Enter the sales for day 1: "; cin >> day1; cout << "Enter the sales for day 2: "; cin >> day2; cout << "Enter the sales for day 3: "; cin >> day3;
179
total = day1 + day2 + day3; Program continues cout.precision(2);
cout.setf(ios::fixed | ios::showpoint); cout << "\nSales Figures\n"; cout << " \n"; cout << “Day 1: " << setw(8) << day1 << endl; cout << “Day 2: " << setw(8) << day2 << endl; cout << “Day 3: " << setw(8) << day3 << endl; cout << "Total: " << setw(8) << total << endl; return 0; }
180
Program Output Enter the sales for day 1: 2642.00 [Enter]
Sales Figures Day 1: Day 2: Day 3: Total:
181
Table 3-13
182
3.9 Formatted Input The cin object provides ways of controlling string and character input.
183
Program 3-27 // This program uses setw with the cin object.
#include <iostream.h> #include <iomanip.h> void main(void) { char word[5]; cout << "Enter a word: "; cin >> setw(5) >> word; cout << "You entered " << word << endl; }
184
Program 3-28 // This program uses cin's width member function.
#include <iostream.h> #include <iomanip.h> void main(void) { char word[5]; cout << "Enter a word: "; cin.width(5); cin >> word; cout << "You entered " << word << endl; }
185
Program Output for Programs 3-27 and 3-28
Enter a word: Eureka [Enter] You entered Eure
186
Important points about the way cin handles field widths:
The field width only pertains to the very next item entered by the user. cin stops reading input when it encounters a whitespace character. Whitespace characters include the [Enter] key, space, and tab.
187
Reading a “Line” of Input
cin.getline(line, 20);
188
Program 3-29 // This program demonstrates cin's getline member function. #include <iostream.h> #include <iomanip.h> void main(void) { char sentence[81]; cout << "Enter a sentence: "; cin.getline(sentence, 81); cout << "You entered " << sentence << endl; }
189
Program Output Enter a sentence: To be, or not to be, that is the question. [Enter] You entered To be, or not to be, that is the question.
190
Program 3-30 #include <iostream.h> void main(void) { char ch;
cout << "Type a character and press Enter: "; cin >> ch; cout << "You entered " << ch << endl; } Program Output with Example Input Type a character and press Enter: A [Enter] You entered A
191
Program 3-31 Program Output
#include <iostream.h> void main(void) { char ch; cout << "This program has paused. Press enter to continue."; cin.get(ch); cout << "Thank you!" << endl; } Program Output This program has paused. Press Enter to continue. [Enter] Thank you!
192
Program 3-32 #include <iostream.h> void main(void) { char ch;
cout << "Type a character and press Enter: "; cin.get(ch); cout << "You entered " << ch << endl; cout << "Its ASCII code is " << int(ch) << endl; }
193
Program Output Type a character and press Enter: [Enter] You entered
Its ASCII code is 10
194
Mixing cin >> and cin.get
Mixing cin.get with cin >> can cause an annoying and hard-to-find problem. Pressing the [Enter] key after inputting a number will cause the newline character to be stored in the keyboard buffer. To avoid this, use cin.ignore. cin.ignore(20,’\n’); will skip the next 20 chars in the input buffer or until a newline is encountered, whichever comes first cin.ignore(); will skip the very next character in the input buffer
195
3. 10 Focus on Object-Oriented
3.10 Focus on Object-Oriented Programming:More About Object Oriented Programming A member function is a procedure, written in C++ code, that is part of an object. A member function causes the object it is a member of to perform an action In this chapter, we have used width, precision, setf, and unsetf for the cout object In this chapter we have used width, getline, get, and ignore for the cin object
196
3.11 More Mathematical Library Functions
The C++ runtime library provides several functions for performing complex mathematical operations. In this chapter we have used width, precision, setf, and unsetf for the cout object In this chapter we have used width, getline, get, and ignore for the cin object
197
Table 3-14
198
Table 3-14 continued
199
Table 3-14 continued
200
Program 3-33 // This program asks for the lengths of the 2 sides of a right // triangle. The length of the hypotenuse is then calculated // and displayed. #include <iostream.h> #include <math.h> // For sqrt and pow void main(void) { float a, b, c; cout << "Enter the length of side A: "; cin >> a; cout << "Enter the length of side B: "; cin >> b; c = sqrt(pow(a, 2.0) + pow(b, 2.0)); cout.precision(2); cout << "The length of the hypotenuse is "; cout << c << endl; }
201
Program Output Enter the length of side A: 5.0 [Enter]
Enter the length of side B: 12.0 [Enter] The length of the hypotenuse is 13
202
Random numbers rand() (from the cstdlib library)
203
Program 3-34 // This program demonstrates random numbers.
#include <iostream.h> #include <stdlib.h> using namespace std; void main(void) { unsigned seed; cout << "Enter a seed value: "; cin >> seed; srand(seed); cout << rand() << endl; }
204
Program Output Enter a seed value: 5 1731 32036 21622 Program Output with Other Example Input Enter a seed value: 16 5540 29663 9920
205
3.13 Optional Section : Introduction to Simple File Input and Output
What is a File? A file is a collection on information, usually stored on a computer’s disk. Information can be saved to files and then later reused.
206
The Process of Using a File
Using a file in a program is a simple three-step process The file must be opened. If the file does not yet exits, opening it means creating it. Information is then saved to the file, read from the file, or both. When the program is finished using the file, the file must be closed.
207
Figure 3-8
208
Figure 3-9
209
Setting Up a Program for File Input/Output
Before file I/O can be performed, a C++ program must be set up properly. File access requires the inclusion of the fstream.h header file.
210
Table 3-16
211
Opening a File Before data can be written to or read from a file, the file must be opened. ifstream inputFile; inputFile.open(“customer.dat”);
212
Closing a File A file should be closed when a program is finished using it. outputFile.close();
213
Writing Information to a File
The stream insertion operator (<<) may be used to write information to a file. outputFile << “I love C++ programming !” outputFile << “Price: “ << price;
214
Program 3-35 // This program uses the << operator to write information to a // file. #include <iostream.h> #include <fstream.h> void main(void) { ofstream outputFile; outputFile.open("demofile.txt"); cout << "Now writing information to the file.\n"; // Write 4 great names to the file outputFile << "Bach\n"; outputFile << "Beethoven\n"; outputFile << "Mozart\n"; outputFile << "Schubert\n";
215
Program 3-35 (continued) Program Screen Output
// Close the file outputFile.close(); cout << "Done.\n"; } Program Screen Output Now writing information to the file. Done. Output to File demofile.txt Bach Beethoven Mozart Schubert
216
Reading Information from a File
The stream extraction operator (>>) may be used to read information from a file. inFile >> name;
217
Program 3-36 // This program uses the >> operator to read information from a // file. #include <iostream.h> #include <fstream.h> void main(void) { ifstream inFile; char name[81]; inFile.open("demofile.txt"); cout << "Reading information from the file.\n\n"; // Now read name 1 from the file inFile >> name; cout << name << endl; // Now read name 2 from the file inFile >> name; cout << name << endl
218
Program 3-36 (continued) Program Screen Output
// Now read name 3 from the file inFile >> name; cout << name << endl; // Now read name 4 from the file inFile >> name; cout << name << endl; // Close the file inFile.close(); cout << "\nDone.\n"; } Program Screen Output Reading information to the file. Bach Beethoven Mozart Schubert Done.
219
Program 3-37 // This program uses the >> operator to read information from a // file. #include <iostream.h> #include <fstream.h> void main(void) { ifstream inFile; int length, width, area; inFile.open("dimensions.txt"); cout << "Reading dimensions of 5 rectangles from the file.\n\n"; // Process rectangle 1 inFile >> length; inFile >> width; area = length * width; cout << "Area of rectangle 1: " << area << endl; // Process rectangle 2 inFile >> length; inFile >> width; area = length * width; cout << "Area of rectangle 2: " << area << endl;
220
Program 3-37 (continued) // Process rectangle 3 inFile >> length; inFile >> width; area = length * width; cout << "Area of rectangle 3: " << area << endl; // Process rectangle 4 inFile >> length; inFile >> width; area = length * width; cout << "Area of rectangle 4: " << area << endl; // Process rectangle 5 inFile >> length; inFile >> width; area = length * width; cout << "Area of rectangle 5: " << area << endl; // Close the file inFile.close(); cout << "\nDone.\n"; }
221
Program 3-37 Before Program 3-37 is executed, the file dimensions.txt must be created with a text editor (such as Windows Notepad). Here is an example of the file's contents:
222
Program 3-37 The program's output is shown below.
Program Output Reading dimensions of 5 rectangles from the file. Area of rectangle 1: 20 Area of rectangle 2: 35 Area of rectangle 3: 162 Area of rectangle 4: 120 Area of rectangle 5: 24 Done.
223
Chapter 4. Making Decisions
224
4.1 Relational Operators Relational operators allow you to compare numeric values and determine if one is greater than, less than, equal to, or not equal to another.
225
Table 4-1
226
Table 4-2
227
The Value of a Relationship
Relational expressions are also know as a Boolean expression Warning! The equality operator is two equal signs together ==
228
Table 4-3
229
Program 4-1 // This program displays the values of true and false
// states. #include <iostream.h> void main(void) { int trueValue, falseValue, x = 5, y = 10; trueValue = X < Y; falseValue = Y == X; cout << "True is " << trueValue << endl; cout << "False is " << falseValue << endl; } Program Output True is 1 False is 0
230
Table 4-4 (Assume x is 10, y is 7, a and b are ints)
231
4.2 The if Statement The if statement can cause other statements to execute only under certain conditions.
232
Program 4-2 // This program averages 3 test scores
#include <iostream.h> void main(void) { int score1, score2, score3; float average; cout << "Enter 3 test scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; cout.precision(1); cout.setf(ios::showpoint | ios::fixed); cout << "Your average is " << average << endl; if (average > 95) cout << "Congratulations! That's a high score!\n"; }
233
Program Output with Example Input
Enter 3 test scores and I will average them: [Enter] Your average is 80.0 Program Output with Other Example Input Enter 3 test scores and I will average them: [Enter] Your average is 100.0 Congratulations! That's a high score!
234
Table 4-5
235
Be Careful With Semicolons
if (expression) statement; Notice that the semicolon comes after the statement that gets executed if the expression is true; the semicolon does NOT follow the expression
236
Program 4-3 Program Output X is 0 and Y is 10 X is greater than Y
// This program demonstrates how a misplaced semicolon // prematurely terminates an if statement. #include <iostream.h> void main(void) { int x = 0, y = 10; cout << “x is " << x << " and y is " << y << endl; if (x > y); // misplaced semicolon! cout << “x is greater than y\n"; // Always executed } Program Output X is 0 and Y is 10 X is greater than Y
237
Programming Style and the if Statement
The conditionally executed statement should appear on the line after the if statement. The conditionally executed statement should be indented one “level” from the if statement. Note: Each time you press the tab key, you are indenting one level.
238
Comparing Floating Point Numbers
Round-off errors can cause problems when comparing floating point numbers with the equality operator (==)
239
Program 4-4 Program Output It's false!
// This program demonstrates how floating point round-off // errors can make equality comparisons unreliable. #include <iostream.h> void main(void) { float result; result = 6.0 * ; // Round-off error if (result == 4.0) cout << "It's true!"; else cout << "It's false!"; } Program Output It's false!
240
And Now Back to Truth When a relational expression is true, it has the value 1. When a relational expression is false it has the value 0. An expression that has the value 0 is considered false by the if statement. An expression that has any value other than 0 is considered true by the if statement.
241
Not All Operators Are “Equal”
Consider the following statement: if (x = 2) // caution here! cout << “It is True!”; This statement does not determine if x is equal to 2, it assigns x the value 2, therefore, this expression will always be true because the value of the expression is 2, a non-zero value
242
Program 4-5 // This program averages 3 test scores. The if statement uses // the = operator, but the == operator was intended. #include <iostream.h> void main(void) { int score1, score2, score3; float average; cout << "Enter 3 test scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; cout.precision(1); cout.setf(ios::showpoint | ios::fixed); cout << "Your average is " << average << endl; if (average = 100) // Wrong cout << "Congratulations! That's a high score!\n"; }
243
Program 4-5 Output With Example Input
Enter your 3 test scores and I will average them: [Enter] Your average is 80.0 Congratulations! That’s a perfect score!
244
4.3 Flags A flag is a variable, usually a boolean or an integer, that signals when a condition exists. If your compiler does not support the bool data type, use int instead.
245
Program 4-6 Program Output with Example Input
// This program averages 3 test scores. It uses the variable highScore as a flag. #include <iostream.h> void main(void) { int score1, score2, score3; float average; bool highScore = false; cout << "Enter your 3 test scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; if (average > 95) highScore = true; // Set the flag variable cout.precision(1); cout.setf(ios::showpoint | ios::fixed); cout << "Your average is " << average << endl; if (highScore) cout << "Congratulations! That's a high score!\n";\ } Program Output with Example Input Enter your 3 test scores and I will average them: [Enter] Your average is 100.0 Congratulations! That's a high score!
246
4.4 Expanding the if Statement
The if statement can conditionally execute a block of statement enclosed in braces. if (expression) { statement; // Place as many statements here as necessary. }
247
Program 4-7 // This program averages 3 test scores.
// It uses the variable highScore as a flag. #include <iostream.h> void main(void) { int score1, score2, score3; float average; bool highScore = false; cout << "Enter 3 test scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; if (average > 95) highScore = true; // Set the flag variable Program continues on next slide…
248
Program continued from previous slide
cout.precision(1); cout.setf(ios::showpoint | ios::fixed); cout << "Your average is " << average << endl; if (highScore) { cout << "Congratulations!\n"; cout << "That's a high score.\n"; cout << "You deserve a pat on the back!\n"; }
249
Program Output with Example Input
Enter your 3 test scores and I will average them: [Enter] Your average is 100.0 Congratulations! That's a high score. You deserve a pat on the back! Program Output with Different Example Input Enter your 3 test scores and I will average them: [Enter] Your average is 80.0
250
Don’t Forget the Braces!
If you intend to execute a block of statements with an if statement, don’t forget the braces. Without the braces, the if statement only executes the very next statement.
251
Program 4-8 // This program averages 3 test scores.
// It uses the variable highScore as a flag. #include <iostream.h> void main(void) { int score1, score2, score3; float average; bool highScore = false; cout << "Enter 3 test scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; if (average > 95) highScore = true; // Set the flag variable Program continues on next slide…
252
Program continued from previous slide
cout.precision(1); cout.setf(ios::showpoint | ios::fixed); cout << "Your average is " << average << endl; // The following if statement is // missing its braces! if (highScore) cout << "Congratulations!\n"; cout << "That's a high score.\n"; cout << "You deserve a pat on the back!\n"; }
253
Program Output with Example Input
Enter your 3 test scores and I will average them: [Enter] Your average is 100 Congratulations! That’s a high score. You deserve a pat on the back! Program Output with Different Example Input Enter your 3 test scores and I will average them: [Enter] Your average is 100 Congratulations! That’s a high score. You deserve a pat on the back!
254
4.5 The if/else Statement The if/else statement will execute one group of statements if the expression is true, or another group of statements if the expression is false. if (expression) statement or block of statements; else
255
Program 4-9 // This program uses the modulus operator to determine
// if a number is odd or even. If the number is evenly divided // by 2, it is an even number. A remainder indicates it is odd. #include <iostream.h> void main(void) { int number; cout << "Enter an integer and I will tell you if it\n"; cout << "is odd or even. "; cin >> number; if (number % 2 == 0) cout << number << " is even.\n"; else cout << number << " is odd.\n"; }
256
Program Output with Example Input
Enter an integer and I will tell you if it is odd or even. 17 [Enter] 17 is odd.
257
Program 4-10 // This program asks the user for two numbers, num1 and num2. // num1 is divided by num2 and the result is displayed. // Before the division operation, however, num2 is tested // for the value 0. If it contains 0, the division does not // take place. #include <iostream.h> void main(void) { float num1, num2, quotient; cout << "Enter a number: "; cin >> num1; cout << "Enter another number: "; cin >> num2; Program continues on next slide…
258
Program continued from previous slide.
if (num2 == 0) { cout << "Division by zero is not possible.\n"; cout << "Please run the program again and enter\n"; cout << "a number besides zero.\n"; } else quotient = num1 / num2; cout << "The quotient of " << num1 << " divided by "; cout << num2 << " is " << quotient << ".\n";
259
Program Output (When the user enters 0 for num2) Enter a number: 10 [Enter] Enter another number: 0 [Enter] Division by zero is not possible. Please run the program again and enter a number besides zero.
260
4.6 The if/else if Construct
The if/else if statement is a chain of if statements. The perform their tests, one after the other, until one of them is found to be true. If (expression) statement or block of statements; else if (expression) // put as many else it’s as needed here
261
Program 4-11 // This program uses an if/else if statement to assign a
// letter grade (A, B, C, D, or F) to a numeric test score. #include <iostream.h> void main(void) { int testScore; char grade; cout << "Enter your numeric test score and I will\n"; cout << "tell you the letter grade you earned: "; cin >> testScore; Program continues on next slide…
262
if (testScore < 60) Program continued from previous slide.
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'; cout << "Your grade is " << grade << ".\n"; }
263
Program Output with Example Input
Enter your test score and I will tell you the letter grade you earned: 88 [Enter] Your grade is B.
264
Program 4-12 Program continues on next slide…
// This program uses independent if/else statements to assign a // letter grade (A, B, C, D, or F) to a numeric test score. // Do you think it will work? #include <iostream.h> void main(void) { int testScore; char grade; cout << "Enter your test score and I will tell you\n"; cout << "the letter grade you earned: "; cin >> testScore; Program continues on next slide…
265
if (testScore < 60) Program continued from previous slide.
grade = 'F'; if (testScore < 70) grade = 'D'; if (testScore < 80) grade = 'C'; if (testScore < 90) grade = 'B'; if (testScore <= 100) grade = 'A'; cout << "Your grade is " << grade << ".\n"; }
266
Program Output with Example Input
Enter your test score and I will tell you the letter grade you earned: 40 [Enter] Your grade is A.
267
Program 4-13 Program continues on next slide… if (testScore < 60)
//This program uses an if/else if statement to //assign a letter grade ( A, B, C, D, or F ) //to a numeric test score. #include<iostream.h> void main(void) { int testScore; cout << "Enter your test score and I will tell you\n"; cout << "the letter grade you earned: "; cin >> testScore; if (testScore < 60) cout << "Your grade is F.\n"; cout << "This is a failing grade. Better see your "; cout << "instructor.\n"; } else if (testScore < 70) cout << "Your grade is D.\n"; cout << "This is below average. You should get "; cout << "tutoring.\n"; Program continues on next slide…
268
Program continued from previous slide.
else if (testScore < 80) { cout << "Your grade is C.\n"; cout << "This is average.\n"; } else if(testScore < 90) cout << "Your grade is B.\n"; cout << "This is an above average grade.\n"; else if (testScore <= 100) cout << "Your grade is A.\n"; cout << "This is a superior grade. Good work!\n";
269
Program Output with Example Input
Enter your test score and I will tell you the letter grade you earned: 94 [Enter] Your grade is A. This is a superior grade. Good work!
270
4.7 Using a Trailing else A trailing else, placed at the end of an if/else if statement, provides default action when none of the if’s have true expressions
271
Program 4-14 // This program uses an if/else if statement to assign a
// letter grade (A, B, C, D, or F) to a numeric test score. // A trailing else has been added to catch test scores > 100. #include <iostream.h> void main(void) { int testScore; cout << "Enter your test score and I will tell you\n"; cout << "the letter grade you earned: "; cin >> testScore; Program continues on next slide…
272
Program continued from previous slide.
if (testScore < 60) { cout << "Your grade is F.\n"; cout << "This is a failing grade. Better see your "; cout << "instructor.\n"; } else if (testScore < 70) cout << "Your grade is D.\n"; cout << "This is below average. You should get "; cout << "tutoring.\n";
273
Program continued from previous slide.
else if (testScore < 80) { cout << "Your grade is C.\n"; cout << "This is average.\n"; } else if (testScore < 90) cout << "Your grade is B.\n"; cout << "This is an above average grade.\n";
274
Program continued from previous slide.
else if (testScore <= 100) { cout << "Your grade is A.\n"; cout << "This is a superior grade. Good work!\n"; } else // Default action cout << testScore << " is an invalid score.\n"; cout << "Please enter scores no greater than 100.\n";
275
Program Output with Example Input
Enter your test score and I will tell you the letter grade you earned: 104 [Enter] 104 is an invalid score. Please enter scores no greater than 100.
276
4.8 Focus on Software Engineering: Menus
You can use the if/else if statement to create menu-driven programs. A menu-driven program allows the user to determine the course of action by selecting it from a list of actions.
277
Program 4-15 // This program displays a menu and asks the user to make a // selection. An if/else if statement determines which item // the user has chosen. #include <iostream.h> void main(void) { int choice, months; float charges; cout << "\t\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"; Program continues on next slide…
278
Program continued from previous slide.
cout << "Enter your choice: "; cin >> choice; cout.setf(ios::fixed | ios::showpoint); cout.precision(2); if (choice == 1) { cout << "\nFor how many months? "; cin >> months; charges = months * 40.00; cout << "The total charges are $" << charges << endl; }
279
else if (choice == 2) Program continued from previous slide. {
cout << "\nFor how many months? "; cin >> months; charges = months * 20.00; cout << "The total charges are $" << charges << endl; } else if (choice == 3) charges = months * 30.00;
280
Program continued from previous slide.
else if (choice != 4) { cout << "The valid choices are 1 through 4. Run the\n"; cout << "program again and select one of those.\n"; }
281
Program Output with Example Input
Health Club Membership Menu 1. Standard Adult Membership 2. Child Membership 3. Senior Citizen Membership 4. Quit the Program Enter your choice: 3 [Enter] For how many months? 6 [Enter] The total charges are $180.00
282
4.9 Focus on Software Engineering: Nested if Statements
A nested if statement is an if statement in the conditionally-executed code of another if statement.
283
Program 4-16 // This program demonstrates the nested if statement.
#include <iostream.h> void main(void) { char employed, recentGrad; cout << "Answer the following questions\n"; cout << "with either Y for Yes or "; cout << "N for No.\n"; cout << "Are you employed? "; cin >> employed; cout << "Have you graduated from college "; cout << "in the past two years? "; cin >> recentGrad; Program continues on next slide…
284
Program continued from previous slide.
if (employed == 'Y') { if (recentGrad == 'Y') // Nested if cout << "You qualify for the special "; cout << "interest rate.\n"; }
285
Program Output with Example Input
Answer the following questions with either Y for Yes or N for No. Are you employed? Y[Enter] Have you graduated from college in the past two years? Y[Enter] You qualify for the special interest rate.
286
Program Output with Other Example Input
Answer the following questions with either Y for Yes or N for No. Are you employed? Y[Enter] Have you graduated from college in the past two years? N[Enter]
287
4.10 Logical Operators Logical operators connect two or more relational expressions into one, or reverse the logic of an expression.
288
Table 4-6
289
Table 4-7
290
Program 4-18 // This program demonstrates the && logical operator.
#include <iostream.h> void main(void) { char employed, recentGrad; cout << "Answer the following questions\n"; cout << "with either Y for Yes or "; cout << "N for No.\n"; cout << "Are you employed? "; cin >> employed; Program continues on next slide…
291
Program continued from previous slide.
cout << "Have you graduated from college "; cout << "in the past two years? "; cin >> recentGrad; if (employed == 'Y‘ && recentGrad == 'Y') // && Operator { cout << "You qualify for the special "; cout << "interest rate.\n"; } else cout << "You must be employed and have \n"; cout << "graduated from college in the\n"; cout << "past two years to qualify.\n";
292
Program Output with Example Input
Answer the following questions with either Y for Yes or N for No. Are you employed? Y[Enter] Have you graduated from college in the past two years? N[Enter] You must be employed and have graduated from college in the past two years to qualify.
293
Table 4-8
294
Program 4-19 Program continues on next slide…
// This program asks the user for their annual income and // the number of years they have been employed at their current // job. The || operator is used in a if statement that // determines if the income is at least $35,000 or their time // on the job is more than 5 years. #include <iostream.h> void main(void) { float income; int years; Program continues on next slide…
295
Program continues cout << "What is your annual income? ";
cin >> income; cout << "How many years have you worked at " << "your current job? "; cin >> years; if (income >= || years > 5) // Use || logical operator cout << "You qualify.\n"; else { cout << "You must earn at least $35,000 or have\n"; cout << "been employed for more than 5 years.\n"; }
296
Program Output with Example Input
What is your annual income? [Enter] How many years have you worked at your current job? 2 [Enter] You qualify. Program Output with Example Input What is your annual income? [Enter] How many years have you worked at your current job? 7 [Enter]
297
Table 4-9
298
Program 4-20 //This program asks the user for his annual income and
//the number of years he has been employed at his current job. //The ! operator reverses the logic of the expression in the if/else statement. #include <iostream.h> void main(void) { float income; int years; cout << "What is your annual income? "; cin >> income; cout << "How many years have you worked at " << "your current job? "; cin >> years; if (!(income >= || years > 5)) // Uses the ! Logical operator cout << "You must earn at least $35,000 or have\n"; cout << "been employed for more than 5 years.\n"; } else cout << "You qualify.\n";
299
Precedence of Logical Operators
! && ||
300
4.11 Checking Numeric Ranges With Logical Operators
Logical operators are effective for determining if a number is in or out of a range.
301
4.12 Focus on Software Engineering: Validating User Input
As long as the user of a program enters bad input, the program will produce bad output. Program should be written to filter out bad input.
302
Examples of validation:
Numbers are check to ensure they are within a range of possible values. Values are check for their “reasonableness”. Items selected from a menu or other set of choices are check to ensure they are available options. Variables are check for values that might cause problems, such as division by zero.
303
4.13 More About Variable Declarations and Scope
The scope of a variable is limited to the block in which is is declared. Variables declared inside a set of braces have local scope or block scope.
304
Program 4-22A //This program demonstrates late variable declaration
#include <iostream.h> void main(void) { cout << "What is your annual income? "; float income; // variable declaration cin >> income; cout << "How many years have you worked at " << "your current job? "; int years; // variable declaration cin >> years; if (income >= || years > 5) cout << "You qualify.\n"; else cout << "You must earn at least $35,000 or have\n"; cout << "been employed for more than 5 years.\n"; }
305
Program 4-22B //This program demonstrates late variable declaration
#include <iostream.h> void main(void) { cout << "What is your annual income? "; float income; // variable declaration cin >> income; cout << "How many years have you worked at " << "your current job? "; int years; // variable declaration cin >> years; if (income >= || years > 5) cout << "You qualify.\n"; else cout << "You must earn at least $35,000 or have\n"; cout << "been employed for more than 5 years.\n"; }
306
Program 4-22C //This program demonstrates late variable declaration
#include <iostream.h> void main(void) { cout << "What is your annual income? "; float income; cin >> income; int years; cout << "How many years have you worked at " << "your current job? "; cin >> years; if (income >= || years > 5) cout << "You qualify.\n"; else cout << "You must earn at least $35,000 or have\n"; cout << "been employed for more than 5 years.\n"; }
307
Program 4-23 Program continues on next slide…
// This program demonstrates a variable declared in an inner block. #include <iostream.h> void main(void) { cout << "What is your annual income? "; float income; // variable declaration cin >> income; if (income >= 35000) int years; // variable declaration cout << "How many years have you worked at " << "your current job? "; cin >> years; if (years > 5) cout << "You qualify.\n"; Program continues on next slide…
308
Program continued from previous slide.
else { cout << "You must have been employed for\n"; cout << "more than 5 years to qualify.\n"; } cout << "You must earn at least $35,000 to\n"; cout << "qualify.\n";
309
Variables With the Same Name
When a block is nested inside another block, a variable declared in the inner block may have the same name as a variable declared in the outer block. The variable in the inner block takes precedence over the variable in the outer block.
310
Program 4-24 // This program uses two variables with the name Number.
#include <iostream.h> void main(void) { int number; cout << "Enter a number greater than 0: "; cin >> number; if (number > 0) Program continues on next slide…
311
Program continued from previous slide.
cout << "Now enter another number: "; cin >> number; cout << "The second number you entered was "; cout << number << endl; } cout << "Your first number was " << number << endl;
312
Program Output with Example Input
Enter a number greater than 0: 2 [Enter] Now enter another number: 7[Enter] The second number you entered was 7 Your first number was 2
313
4.14 Comparing Strings Use the strcmp library function to compare C-strings.
314
Program 4-25 // This program illustrates that you cannot compare strings // with relational operators. Although it appears to test the // strings for equality, that is NOT what happens. #include <iostream.h> void main(void) { char firstString[40], secondString[40]; cout << "Enter a string: "; cin.getline(firstString, 40); cout << "Enter another string: "; cin.getline(secondString, 40); if (firstString == secondString) cout << "You entered the same string twice.\n"; else cout << "The strings are not the same.\n"; }
315
Program Output with Example Input
Enter a string: Alfonso [Enter] Enter another string: Alfonso [Enter] The strings are not the same.
316
The strcmp Function strcmp(string1, string2); // include cstring to use // this function If the two strings are identical, strcmp returns 0. If string1 < string 2, strcmp returns a negative number. If string1 > string 2, strcmp returns a positive number.
317
Program 4-26 // This program correctly tests two strings for equality, with // the strcmp function #include <iostream.h> #include <string.h> void main(void) { char firstString[40], secondString[40]; cout << "Enter a string: "; cin.getline(firstString, 40); cout << "Enter another string: "; cin.getline(secondString, 40); if (strcmp(firstString, secondString) == 0) cout << "You entered the same string twice.\n"; else cout << "The strings are not the same.\n"; }
318
Program 4-27 // This program uses strcmp to compare the sting entered
// by the user with the valid stereo part numbers. #include <iostream.h> #include <string.h> void main(void) { const float aprice = 249.0, Bprice = 299.0; char partNum[8]; cout << "The stereo part numbers are:\n"; cout << "\tBoom Box, part number S147-29A\n"; Program continues on next slide…
319
Program continued from previous slide
cout << "\tShelf Model, part number S147-29B\n"; cout << "Enter the part number of the stereo you\n"; cout << "wish to purchase: "; cin.width(9); // So they won't enter more than 8 char's cin >> partNum; cout.setf(ios::fixed || ios::showpoint); cout.precision(2); if (strcmp(partNum, "S147-29A") == 0) // use of strcmp cout << "The price is $" << aprice << endl; else if (strcmp(partNum, "S147-29B") == 0) cout << "The price is $" << Bprice << endl; else cout << partNum << " is not a valid part number.\n"; }
320
Program Output with Example Input
The stereo part numbers are: Boom Box, part number S14729A Shelf Model, part number S147-29B Enter the part number of the stereo you wish to purchase: S147-29B [Enter] The price is $299.00
321
Program 4-28 // This program uses the return value of strcmp to
// alphabetically sort two strings entered by the user. #include <iostream.h> #include <string.h> void main(void) { char name1[30], name2[30]; cout << "Enter a name (last name first): "; cin.getline(name1, 30); cout << "Enter another name: "; cin.getline(name2, 30); Program continues on next slide…
322
Program continued from previous slide.
cout << "Here are the names sorted alphabetically:\n"; if (strcmp(name1, name2) < 0) cout << name1 << endl << name2 << endl; else if (strcmp(name1, name2) > 0) cout << name2 << endl << name1 << endl; else cout << "You entered the same name twice!\n"; }
323
Program Output with Example Input
Enter a name (last name first): Smith, Richard [Enter] Enter another name: Jones, John [Enter] Here are the names sorted alphabetically Jones, John Smith, Richard
324
Program 4-29 Program continues on next slide…
//This program uses strcmp to compare the string entered //by the user with the valid stereo part numbers. #include<iostream.h> #include<string> using namespace std; void main(void) { const float aprice = 249.0, bprice = 299.0; string partNum; cout << "The stereo part numbers are:\n"; cout << "Boom box, part number S147-29A\n"; cout << "Shelf model, part number S147-29B\n"; cout << "Enter the part number of the stereo you\n"; cout << "wish to purchase: "; cin >> partNum; Program continues on next slide…
325
Program continued from previous slide
cout.setf(ios::fixed | ios::showpoint); cout.precision(2); if (partNum == "S147-29A") cout << "The price is $" << aprice << endl; else if (partNum == "S147-29B") cout << "The price is $" << bprice << endl; else cout << partNum << " is not a valid part number."; }
326
Program Output with Example Input
The stereo part numbers are: Boom box, part number S147-29A Shelf model, part number S147-29B Enter the part number of the stereo you wish to purchase: S147-29A The price is $249.00
327
4.15 The Conditional Operator
You can use the conditional operator to create short expressions that work like if/else statements expression ? result if true : result if false;
328
Program 4-30 // This program calculates a consultant's charges at $50 per hour, // for a minimum of 5 hours. The ?: operator adjusts hours to 5 if less // than 5 hours were worked. #include <iostream.h> void main(void) { const float payRate = 50.0; float hours, charges; cout << "How many hours were worked? "; cin >> hours; hours = hours < 5 ? 5 : hours; charges = payRate * hours; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "The charges are $" << charges << endl; }
329
Program Output with Example Input
How many hours were worked? 10 [Enter] The charges are $500.00 Program Output with Example Input How many hours were worked? 2 [Enter] The charges are $250.00
330
Program 4-31 Program continues on next slide…
// This program uses the return value of strcmp to alphabetically // sort two strings entered by the user. #include <iostream.h> #include <string.h> void main(void) { char name1[30], name2[30]; cout << "Enter a name (last name first): "; cin.getline(name1, 30); Program continues on next slide…
331
Program continued from previous slide.
cout << "Enter another name: "; cin.getline(name2, 30); cout << "Here are the names sorted alphabetically:\n"; cout << (strcmp(name1, name2) <= 0 ? name1 : name2) << endl; cout << (strcmp(name1, name2) > 0 ? name1 : name2) << endl; }
332
Program Output with Example Input
Enter a name (last name first): Smith, Richard [Enter] Enter another name: Jones, John [Enter] Here are the names sorted alphabetically Jones, John Smith, Richard
333
4.16 The switch Statement The switch statement lets the value of a variable or expression determine where the program will branch to.
334
Program 4-32 // The switch statement in this program tells the user
// something he or she already knows: what they just entered! #include <iostream.h> void main(void) { char choice; cout << "Enter A, B, or C: "; cin >> choice; Program continues on next slide…
335
Program continues switch (choice) {
case 'A': cout << "You entered A.\n"; break; case 'B': cout << "You entered B.\n"; case 'C': cout << "You entered C.\n"; default: cout << "You did not enter A, B, or C!\n"; }
336
Program Output with Example Input
Enter A, B, or C: B [Enter] You entered B. Program Output with Different Example Input Enter a A, B, or C: F [Enter] You did not enter A, B, or C!
337
Program 4-33 // The switch statement in this program tells the user
// something he or she already knows: what they just // entered! #include <iostream.h> void main(void) { char choice; cout << "Enter A, B, or C: "; cin >> choice; Program continues on next slide…
338
Program continued from previous slide.
switch (choice) { case 'A': cout << "You entered A.\n"; case 'B': cout << "You entered B.\n"; case 'C': cout << "You entered C.\n"; default: cout << "You did not enter A, B, or C!\n"; }
339
Program Output with Example Input
Enter a A, B, or C: A [Enter] You entered A. You entered B. You entered C. You did not enter A, B, or C! Program Output with Example Input Enter a A, B, or C: C [Enter]
340
Program 4-34 // This program is carefully constructed to use the
// "fallthrough" feature of the switch statement. #include <iostream.h> void main(void) { int modelNum; cout << "Our TVs come in three models:\n"; cout << "The 100, 200, and 300. Which do you want? "; cin >> modelNum; cout << "That model has the following features:\n"; Program continues on next slide…
341
Program continues switch (modelNum) {
case 300: cout << "\tPicture-in-a-picture.\n"; case 200: cout << "\tStereo sound.\n"; case 100: cout << "\tRemote control.\n"; break; default: cout << "You can only choose the 100,"; cout << "200, or 300.\n"; }
342
Program Output with Example Input
Our TVs come in three models: The 100, 200, and 300. Which do you want? 100 [Enter] That model has the following features: Remote control. Program Output with Example Input The 100, 200, and 300. Which do you want? 200 [Enter] That model has the following features: Stereo sound. Remote control.
343
Program 4-35 Program continues on next slide…
// The switch statement in this program uses the "fallthrough" // feature to catch both upper and lowercase letters entered // by the user. #include <iostream.h> void main(void) { char feedGrade; cout << "Our dog food is available in three grades:\n"; cout << "A, B, and C. Which do you want pricing for? "; cin >> feedGrade; Program continues on next slide…
344
Program continued from previous slide.
switch(feedGrade) { case 'a': case 'A': cout << "30 cents per pound.\n"; break; case 'b': case 'B': cout << "20 cents per pound.\n"; case 'c': case 'C': cout << "15 cents per pound.\n"; default: cout << "That is an invalid choice.\n"; }
345
Chapter 5. Looping
346
5.1 The Increment and Decrement Operators
++ and -- are operators that add and subtract one from their operands. num = num + 1; num += 1; num++;
347
Program 5-1 // This program demonstrates the increment and decrement
// operators. #include <iostream.h> void main(void) { int bigVal = 10, smallVal = 1; cout << "bigVal is " << bigVal << " and smallVal is " << smallVal << endl; smallVal++; bigVal--; Program continues…
348
Program continued from previous slide.
cout << "bigVal is " << bigVal << " and smallVal is " << smallVal << endl; ++smallVal; --bigVal; }
349
Program Output bigVal is 10 and smallVal is 1 bigVal is 9 and smallVal is 2 bigVal is 8 and smallVal is 3
350
Program 5-2 //This program demonstrates the prefix and postfix modes of the // increment and decrement operators. #include <iostream.h> void main(void) { int bigVal = 10, smallVal = 1; cout << "bigVal starts as " << bigVal; cout << " and smallVal starts as " << smallVal << endl; cout << "bigVal--: " << bigVal-- << endl; cout << "smallVal++: " << smallVal++ << endl; cout << "Now bigVal is: " << bigVal << endl; cout << "Now smallVal is: " << smallVal << endl; cout << "--bigVal: " << --bigVal << endl; cout << "++smallVal: " << ++smallVal << endl; }
351
Program Output bigVal starts as 10 and smallVal starts as 1
Now bigVal is: 9 Now smallVal is: 2 --bigVal: 8 ++smallVal: 3
352
Using ++ and -- in Mathematical Expressions
b = 5; c = a * b++; cout << a << “ “ << b << “ “ << c; Results:
353
Using ++ and -- in Relational Expressions
if ( x++ > 10) cout << “x is greater than 10.\n”; Two operations are happening: the value in x is tested to determine if it is greater than 10 then x is incremented
354
5.2 Introduction to Loops - The while Loop
A loop is part of a program that repeats. A while loop is a “pre test” loop - the expression is tested before the loop is executed while (expression) statement;
355
Program 5-3 // This program demonstrates a simple while loop.
#include <iostream.h> void main(void) { int number = 0; cout << "This program will let you enter number after\n"; cout << "number. Enter 99 when you want to quit the "; cout << "program.\n"; while (number != 99) cin >> number; }
356
Program Output with Example Input
This program will let you enter number after number. Enter 99 when you want to quit the program. 1 [Enter] 2 [Enter] 30 [Enter] 75 [Enter] 99 [Enter]
357
Terminating a Loop A loop that does not have a way of stopping is called an infinite loop int test = 0; while (test < 10) cout << “Hello\n”; A null statement is also an infinite loop, but it does nothing forever: while (test < 10);
358
Programming Style and the while Loop
If there is only one statement repeated by the loop, it should appear on the line after the while statement and be indented one additional level If the loop repeats a block, the block should begin on the line after the while statement and each line inside the braces should be indented
359
5.3 Counters A counter is a variable that is incremented or decremented each time a loop iterates.
360
Program 5-4 // This program displays the numbers 1 through 10 and
// their squares. #include <iostream.h> void main(void) { int num = 1; // Initialize counter cout << "number number Squared\n"; cout << " \n"; while (num <= 10) cout << num << "\t\t" << (num * num) << endl; num++; // Increment counter }
361
Program Output number number Squared
362
Program 5-5 // This program displays the numbers 1 through 10 and
// their squares. #include <iostream.h> void main(void) { int num = 0; cout << "number number Squared\n"; cout << " \n"; while (num++ < 10) cout << num << "\t\t" << (num * num) << endl; }
363
Program Output number number Squared
364
5.4 Letting the User Control the Loop
We can let the user indicate the number of times a loop should repeat.
365
Program 5-6 // This program averages a set of test scores for multiple
// students. It lets the user decide how many. #include <iostream.h> void main(void) { int numStudents, count = 0; cout << "This program will give you the average of three\n"; cout << "test scores per student.\n"; cout << "How many students do you have test scores for? "; cin >> numStudents; cout << "Enter the scores for each of the students.\n"; cout.precision(2); Program continues…
366
Program continued from previous slide.
while (count++ < numStudents) { int score1, score2, score3; float average; cout << "\nStudent " << count << ": "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; cout << "The average is " << average << ".\n"; }
367
Program Output with Example Input
This program will give you the average of three test scores per student. How many students do you have test scores for? 3 [Enter] Enter the scores for each of the students. Student 1: [Enter] The average is 79. Student 2: [Enter] The average is Student 3: [Enter] The average is
368
5.5 Keeping a Running Total
A running total is a sum of numbers that accumulates with each iteration of a loop. The variable used to keep the running total is called an accumulator.
369
Program 5-7 // This program takes daily sales figures over a period of
// time and calculates their total. #include <iostream.h> void main(void) { int days, count = 0; float total = 0.0; cout << "For how many days do you have sales figures? "; cin >> days; Program continues…
370
Program continues while (count++ < days) { float sales;
cout << "Enter the sales for day " << count << ": "; cin >> sales; total += sales; } cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "The total sales are $" << total << endl;
371
Program Output with Example Input
For how many days do you have sales figures? 5 [Enter] Enter the sales for day 1: [Enter] Enter the sales for day 2: [Enter] Enter the sales for day 3: [Enter] Enter the sales for day 4: [Enter] Enter the sales for day 5: [Enter] The total sales are $
372
5.6 Sentinels A sentinel is a special value that marks the end of a list of values.
373
Program 5-8 // 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 -1 when finished. #include <iostream.h> void main(void) { int count = 0, points = 0, total = 0; cout << "Enter the number of points your team has earned\n"; cout << "so far in the season, then enter -1 when\n"; cout << "finished.\n"; Program continues…
374
Program continued from previous slide.
while (points != -1) { count++; cout << "Enter the points for game " << count << ": "; cin >> points; if (points != -1) total += points; } cout << "The total points are " << total << endl;
375
Program Output with Example Input
Enter the number of points your team has earned so far in the season, then enter -1 when you are finished. Enter the points for game 1: 7 [Enter] Enter the points for game 2: 9 [Enter] Enter the points for game 3: 4 [Enter] Enter the points for game 4: 6 [Enter] Enter the points for game 5: 8 [Enter] Enter the points for game 6: -1 [Enter] The total points are 34
376
5.7 The do-while Loop and for Loops
In addition to the while loop, C++ also offers the do-while and for loops. A do-while loop is similar to a while loop, but in post-test format: do statement; while (expression);
377
Program 5-9 //This program averages 3 test scores. It repeats as many times as // the user wishes #include <iostream.h> void main(void) { int score1, score2, score3; float average; char again; do cout << "Enter 3 scores and I will average them: "; cin >> score1 >> score2 >> score3; average = (score1 + score2 + score3) / 3.0; cout << "The average is " << average << ".\n"; cout << "Do you want to average another set? (Y/N) "; cin >> again; } while (again == 'Y' || again == 'y'); }
378
Program Output with Example Input
Enter 3 scores and I will average them: [Enter] The average is 80. Do you want to average another set? (Y/N) y [Enter] Enter 3 scores and I will average them: [Enter] The average is Do you want to average another set? (Y/N) n [Enter]
379
Program 5-10 // This program displays a menu and asks the user to make a // selection. A switch statement determines which item the // user has chosen. A do-while loop repeats the program until // the user selects item 4 from the menu. #include <iostream.h> void main(void) { int choice, months; float charges; cout.setf(ios::fixed | ios::showpoint); cout.precision(2); Program continues…
380
Program continued from previous slide.
do { cout << "\n\t\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: "; cin >> choice; if (choice != 4) cout << "For how many months? "; cin >> months; } Program continues…
381
Program continued from previous slide.
switch (choice) { case 1: charges = months * 40.00; cout << "The total charges are $"; cout << charges << endl; break; case 2: charges = months * 20.00; case 3: charges = months * 30.00; Program continues…
382
Program continued from previous slide.
case 4: cout << "Thanks for using this "; cout << "program.\n"; break; default: cout << "The valid choices are 1-4. "; cout << "Try again.\n"; } } while (choice != 4); } Program continues…
383
Program Output with Example Input
Health Club Membership Menu 1. Standard Adult Membership 2. Child Membership 3. Senior Citizen Membership 4. Quit the Program Enter your choice: 1 [Enter] For how many months 12 [Enter] The total charges are $ Health Club Membership Menu 1. Standard Adult Membership 2. Child Membership 3. Senior Citizen Membership 4. Quit the Program Enter your choice: 4 [Enter] Thanks for using this program.
384
The for Loop Ideal for situations that require a counter because it has built-in expressions that initialize and update variables. for (initialization; test; update) statement;
385
Program 5-11 // This program displays the numbers 1 through 10 and
// their squares. #include <iostream.h> void main(void) { int num; cout << “Number Number Squared\n"; cout << " \n"; for (num = 1; num <= 10; num++) cout << num << "\t\t" << (num * num) << endl; }
386
Program Output Number Number Squared
387
Omitting the for Loop’s Expressions
int num = 1; for ( ; num <= 10; num++) cout << num << “\t\t” << (num * num) << endl;
388
Using initialization and update lists
You may need to perform more than one statement in the initialization part of a for loop. In that case, just separate the statements with commas.
389
Program 5-12 // This program takes daily sales figures for one week
// and calculates their total. #include <iostream.h> void main(void) { const int days = 7; int count; float total; for (count = 1, total = 0.0; count <= days; count++) float sales; cout << "Enter the sales for day " << count << ": "; Program continues…
390
Program continued from previous slide.
cin >> sales; total += sales; } cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "The total sales are $" << total << endl;
391
Program Output with Example Input
Enter the sales for day 1: [Enter] Enter the sales for day 2: [Enter] Enter the sales for day 3: [Enter] Enter the sales for day 4: [Enter] Enter the sales for day 5: [Enter] Enter the sales for day 6: [Enter] Enter the sales for day 7: [Enter] The total sales are $
392
5.8 Other forms of the update expression
Incrementing the counter by something besides 1: for(number = 2; number <= 100; number +=2) cout << number << endl; // print the even numbers 2 – 100 Going backwards: for(number = 10; number >= 0; number--) cout << number << endl; //count from 10 to 0 A stand-alone for loop //This one prints the integers from 1 to 10 for(number = 1; number <= 10; cout << number++) There are quite a few variations, try some of your own!
393
5.8 Focus on Software Engineering: Deciding Which Loop to Use
The while Loop A pre-test loop. Use when you do not want the loop to iterate if the condition is false from the beginning. Ideal if you want to use a sentinel. The do-while Loop A post-test loop. Use if you always want the loop to iterate at least once. The for Loop Automatically executes an update expression at the end of each iteration. Ideal for situations where a counter variable is needed. Used when the exact number of required iterations is known.
394
5.9 Focus on Software Engineering: Nested Loops
A loop that is inside another loop is called a nested loop.
395
Program 5-13 // This program averages test scores. It asks the user for the // number of students and the number of test scores per student. #include <iostream.h> void main(void) { int numStudents, numTests, total; float average; cout << "This program averages test scores.\n"; cout << "For how many students do you have scores? "; cin >> numStudents; cout << "How many test scores does each student have? "; cin >> numTests; Program continues…
396
Program continued from previous slide.
for (int count1 = 1; count1 <= numStudents; count1++) { total = 0; // Initialize accumulator for (int count2 = 1; count2 <= numTests; count2++) int score; cout << "Enter score " << count2 << " for "; cout << "student " << count1 << ": "; cin >> score; total += score; // accumulate running total } average = total / numTests; cout << "The average score for student " << count1; cout << " is " << average << ".\n\n";
397
Program Output with Example Input
This program averages test scores. For how many students do you have scores? 2 [Enter] How many test scores does each student have? 3 [Enter] Enter score 1 for student 1: 84 [Enter] Enter score 2 for student 1: 79 [Enter] Enter score 3 for student 1: 97 [Enter] The average for student 1 is 86. Enter score 1 for student 2: 92 [Enter] Enter score 2 for student 2: 88 [Enter] Enter score 3 for student 2: 94 [Enter] The average for student 2 is 91.
398
5.10 Breaking Out of a Loop The break statement causes a loop to terminate early.
399
Program 5-14 // This program raises the user's number to the powers
// of 0 through 10. #include <iostream.h> #include <math.h> void main(void) { int value; char choice; cout << "Enter a number: "; cin >> value; cout << "This program will raise " << value; cout << " to the powers of 0 through 10.\n"; Program continues…
400
Program continued from previous slide.
for (int count = 0; count < 10; count++) { cout << value << " raised to the power of "; cout << count << " is " << pow(value, count); cout << "\nEnter Q to quit or any other key "; cout << "to continue. "; cin >> choice; if (choice == 'Q' || choice == 'q') break; }
401
Program Output Enter a number: 2 [Enter]
This program will raise 2 to the powers of 0 through 10. 2 raised to the power of 0 is 1 Enter Q to quit or any other key to continue. C [Enter] 2 raised to the power of 1 is 2 Enter Q to quit or any other key to continue. C [Enter] 2 raised to the power of 2 is 4 Enter Q to quit or any other key to continue. Q [Enter]
402
5.11 Using break in a nested loop
The break statement below breaks out of the inner loop but NOT the outer loop for(int row = 0; row < 5; row++) { //begin outer loop for(star = 0; star < 20; star++) { //begin inner loop …………// some statements break; …………// some more statements } //end inner loop } //end outer loop
403
5.11 The continue Statement
The continue statement causes a loop to stop its current iteration and begin the next one.
404
Program 5-15 // This program calculates the charges for video rentals.
// Every third video is free. #include <iostream.h> #include <iomanip.h> void main(void) { int videoCount = 1, numVideos; float total = 0.0; char current; cout << "How many videos are being rented? "; cin >> numVideos; Program continues…
405
Program continued from previous slide.
do { if ((videoCount % 3) == 0) cout << "Video #" << videoCount << " is free!\n"; continue; } cout << "Is video #" << videoCount; cout << " a current release? (Y/N)"; cin >> current; if (current == 'Y' || current == 'y') total += 3.50; else total += 2.50; } while (videoCount++ < numVideos); Program continues…
406
Program continued from previous slide.
cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "The total is $" << total; }
407
Program Output with Example Input
How many Videos are being rented? 6 [Enter] Is video #1 a current release? y [Enter] Is video #2 a current release? n [Enter] Video #3 is free! Is video #4 a current release? n [Enter] Is video #5 a current release? y [Enter] Video #6 is free! The total is $12.00
408
5.12 Using Loops for Input Validation
Loops can be used to create input routines that repeat until acceptable data is entered.
409
Program 5-16 // This program calculates the number of soccer teams
// that a youth league may create from the number of // available players. Input validation is demonstrated // with do-while loops. #include <iostream.h> void main(void) { int players, teamPlayers, numTeams, leftOver; // Get the number of players per team. cout << “How many players you wish per team?\n”; cout << “(Enter a value in the range ): "; cin >> teamPlayers; Program continues…
410
Program continued from previous slide.
while (teamPlayers < 9 || teamPlayers > 15) // Validate input { cout << "You should have at least 9 but no\n"; cout << "more than 15 per team.\n"; cout << “How many players do you wish per team? “; cin >> teamPlayers; } // Get the number of players available cout << “How many players are available? “; cin >> players; while (players < 0) // Validate input { cout << "Please enter a positive number.\n"; // Perform calculations numTeams = players / teamPlayers; leftOver = players % teamPlayers; cout << "There will be " << numTeams << " teams with\n"; cout << leftOver << " players left over.\n";
411
Program Output with Example Input
How many players you wish per team? (Enter a value in the range 9 – 15): 4[Enter] You should have at least 9 but no more than 15 per team. How many players you wish per team? 12[Enter] How many players are available? -142 [Enter] Please enter a positive number: 142[Enter] There will be 11 teams with 10 players left over.
412
Chapter 6 Functions
413
6.1 Focus on Software Engineering: Breaking Up Your Programs
Programs may be broken up into many manageable functions.
414
6.2 Defining and Calling Functions
A function call is a statement that causes a function to execute. A function definition contains the statements that make up the function. The line in the definition that reads void main(void) is called the function header.
415
Figure 6-1 Parameter List (This one is empty) Return Type Name Body
void main(void) { cout << “Hello World\n”; } Return Type Name Parameter List (This one is empty) Body
416
Calling a Function Function Header void displayMessage() Function Call
417
Program 6-1 #include <iostream.h>
//****************************************** // Definition of function displayMessage. * // This function displays a greeting * void displayMessage() { cout << "Hello from the function displayMessage.\n"; } void main(void) cout << "Hello from main.\n"; displayMessage(); cout << "Back in function main again.\n";
418
Program Output Hello from main.
Hello from the function displayMessage. Back in function main again.
419
Figure 6-2 void displayMessage() { cout << “Hello from the function displayMessage.\n”; } void main(void) { cout << “Hello from main.\n”; displayMessage(); cout << “Back in function main again.\n”; }
420
Program 6-2 //The function displayMessage is repeatedly called from a loop #include <iostream.h> //****************************************** // Definition of function displayMessage. * // This function displays a greeting * //****************************************** void displayMessage() { cout << "Hello from the function displayMessage.\n"; } void main(void) cout << "Hello from main.\n"; for (int count = 0; count < 5; count++) displayMessage(); // Call displayMessage cout << "Back in function main again.\n";
421
Program Output Hello from main.
Hello from the function displayMessage. Back in function main again.
422
Program 6-3 // This program has three functions: main, first, and second. #include <iostream.h> //************************************* // Definition of function first * // This function displays a message. * void first(void) { cout << "I am now inside the function first.\n"; }
423
Program continues void second(void) {
//************************************* // Definition of function second. * // This function displays a message. * void second(void) { cout << "I am now inside the function second.\n"; } void main(void) cout << "I am starting in function main.\n"; first(); // Call function first second(); // Call function second cout << "Back in function main again.\n";
424
Program Output I am starting in function main.
I am now inside the function first. I am now inside the function second. Back in function main again.
425
Figure 6-3 void first(void) { cout << “I am now inside function first.\n”; } void second(void) { cout << “I am now inside function second.\n”; } void main(void) { cout << “I am starting in function main.\n”; first(); second(); cout << “Back in function main again.\n” }
426
Program 6-4 #include <iostream.h>
// This program has three functions: main, deep, and deeper #include <iostream.h> //************************************** // Definition of function deeper * // This function displays a message. * void deeper(void) { cout << "I am now inside the function deeper.\n"; }
427
Program continues //**************************************
// Definition of function deep * // This function displays a message. * void deep() { cout << "I am now inside the function deep.\n"; deeper(); // Call function deeper cout << "Now I am back in deep.\n"; } void main(void) cout << "I am starting in function main.\n"; deep(); // Call function deep cout << "Back in function main again.\n";
428
Program Output I am starting in function main.
I am now inside the function deep. I am now inside the function deeper. Now I am back in deep. Back in function main again.
429
Figure 6-4 void deep(void) { cout << “I am now inside function deep.\n”; deeper(); cout << “Now I am back in deep.\n”; } void deeper(void) { cout << “I am now inside function deeper.\n”; } void main(void) { cout << “I am starting in function main.\n”; deep(); cout << “Back in function main again.\n” }
430
6.3 Function Prototypes A function prototype eliminates the need to place a function definition before all calls to the function. Here is a prototype for the displayMessage function in Program 6-1 void displayMessage(void);
431
Program 6-5 // This program has three functions: main, first, and second. #include <iostream.h> // Function Prototypes void first(void); void second(void); void main(void) { cout << "I am starting in function main.\n"; first(); // Call function first second(); // Call function second cout << “Back in function main again.\n"; } Program Continues on next slide
432
Program 6-5 Continues // Definition of function first.
// This function displays a message. void first(void) { cout << “I am now inside the function first.\n”; } // Definition of function second void second(void) cout << “I am now inside the function second.\n”;
433
Program 6-5 Output I am starting in function main.
I am now inside the function first. I am now inside the function second. Back in function main again.
434
6.4 Sending Information Into a Function
When a function is called, the program may send values (arguments) into the function. Arguments are passed into parameters. void displayValue(int num) { cout << “The value is “ << num << endl; }
435
Program 6-6 // This program demonstrates a function with a parameter.
#include <iostream.h> // Function Prototype void displayValue(int) void main(void) { cout << "I am passing 5 to displayValue.\n"; displayValue(5); //Call displayValue with argument 5 cout << "Now I am back in main.\n"; } Program Continues to next slide
436
Program 6-6 //*********************************************
// Definition of function displayValue * // It uses an integer parameter whose value is displayed. * void displayValue(int num) { cout << “The value is “ << num << endl; }
437
Program Output I am passing 5 to displayValue. The value is 5
Now I am back in main.
438
Figure 6-5 displayValue(5);
void displayValue(int num) { cout << “The value is “ << num << endl; }
439
Program 6-7 // This program demonstrates a function with a parameter.
#include <iostream.h> // Function Prototype void displayValue(int); void main(void) { cout << "I am passing several values to displayValue.\n"; displayValue(5); // Call displayValue with argument 5 displayValue(10); // Call displayValue with argument 10 displayValue(2); // Call displayValue with argument 2 displayValue(16); // Call displayValue with argument 16 cout << "Now I am back in main.\n"; } Program continues on next slide
440
Program 6-7 Continued } void displayValue(int num) {
//********************************************************* // Definition of function displayValue * // It uses an integer parameter whose value is displayed. * //********************************************************* void displayValue(int num) { cout << "The value is " << num << endl; }
441
Program Output I am passing several values to displayValue.
The value is 5 The value is 10 The value is 2 The value is 16 Now I am back in main.
442
Program 6-8 void main(void) { int value1, value2, value3;
// This program demonstrates a function with three parameters. #include <iostream.h> // Function prototype void showSum(int, int, int); void main(void) { int value1, value2, value3; cout << "Enter three integers and I will display "; cout << "their sum: "; cin >> value1 >> value2 >> value3; showSum(value1, value2, value3); // Call showSum with // 3 arguments }
443
Program continues //************************************************************ // Definition of function showSum * // It uses three integer parameters. Their sum is displayed. * void showSum(int num1, int num2, int num3) { cout << (num1 + num2 + num3) << endl; }
444
Program Output with Example Input
Enter three integers and I will display their sum: [Enter] 19
445
Figure 6-6 showSum(value1, value2, value3);
void showSum(int num1, int num2, int num3) { cout << num1 + num2 + num3 << endl; }
446
6.5 Changing the value of a Parameter
When an argument is passed into a parameter, only a copy of the argument’s value is passed. Changes to the parameter do not affect the original argument. This is called “passed by value.”
447
Program 6-9 // This program demonstrates that changes to a function parameter // have no effect on the original argument. #include <iostream.h> // Function Prototype void changeThem(int, float); void main(void) { int whole = 12; float real = 3.5; cout << "In main the value of whole is " << whole << endl; cout << "and the value of real is " << real << endl; changeThem(whole, real); // Call changeThem with 2 arguments cout << "Now back in main again, the value of "; cout << "whole is " << whole << endl; }
448
Program continues //************************************************************** // Definition of function changeThem * // It uses i, an int parameter, and f, a float. The values of * // i and f are changed and then displayed * void changeThem(int i, float f) { i = 100; f = 27.5; cout << "In changeThem the value of i is changed to "; cout << i << endl; cout << "and the value of f is changed to " << f << endl; }
449
Program Output In main the value of whole is 12
and the value of real is 3.5 In changeThem the value of i is changed to 100 and the value of f is changed to 27.5 Now back in main again, the value of whole is 12
450
Figure 6-7
451
6.6 Focus on Software Engineering: Using Functions in a Menu-Driven Program
Functions are ideal for use in menu-driven programs. When the user selects an item from a menu, the program can call the appropriate function.
452
Program 6-10 // This is a menu-driven program that makes a function call // for each selection the user makes. #include <iostream.h> // Function Prototypes void adult(int); void child(int); void senior(int); void main(void) { int choice, months;
453
Program continues cout.setf(ios::fixed | ios::showpoint);
cout.precision(2); do { cout << "\n\t\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: "; cin >> choice;
454
Program continues if (choice != 4)
{ cout << "For how many months? "; cin >> months; } switch (choice) { case 1: adult(months); break; case 2: child(months); case 3: senior(months); case 4: cout << "Thanks for using this "; cout << "program.\n";
455
Program continues default: cout << "The valid choices are 1-4. "; cout << "Try again.\n"; } } while (choice != 4); //*********************************************************** // Definition of function adult. Uses an integer parameter, mon. * // mon holds the number of months the membership should be * // calculated for. The cost of an adult membership for that many * // months is displayed * //****************************************************************** void adult(int mon) { cout << "The total charges are $"; cout << (mon * 40.0) << endl;
456
Program continues //******************************************************************** // Definition of function child. Uses an integer parameter, mon. * // mon holds the number of months the membership should be * // calculated for. The cost of a child membership for that many * // months is displayed * //************************************************************* void child(int mon) { cout << "The total charges are $"; cout << (mon * 20.0) << endl; }
457
Program continues //******************************************************************* // Definition of function senior. Uses an integer parameter, mon. * // mon holds the number of months the membership should be * // calculated for. The cost of a senior citizen membership for * // that many months is displayed * //************************************************************ void senior(int mon) { cout << "The total charges are $"; cout << (mon * 30.0) << endl; }
458
Program Output with Example Input
Health Club Membership Menu 1. Standard adult Membership 2. child Membership 3. senior Citizen Membership 4. Quit the Program Enter your choice: 1 For how many months 12 The total charges are $480.00 Enter your choice: 4 Thanks for using this program.
459
6.7 The return Statement The return statement causes a function to end immediately.
460
Program 6-11 #include <iostream.h> // Function prototype
// This program demonstrates a function with a return statement. #include <iostream.h> // Function prototype void halfway(void); void main(void) { cout << "In main, calling halfway...\n"; halfway(); cout << "Now back in main.\n"; }
461
Program continues //********************************************************* // Definition of function halfway * // This function has a return statement that forces it to * // terminate before the last statement is executed * void halfway(void) { cout << "In halfway now.\n"; return; cout <<"Will you ever see this message?\n"; }
462
Program Output In main, calling halfway... In halfway now.
Now back in main.
463
Program 6-12 // This program uses a function to perform division. If division // by zero is detected, the function returns. #include <iostream.h> // Function prototype. void divide(float, float); void main(void) { float num1, num2; cout << "Enter two numbers and I will divide the first\n"; cout << "number by the second number: "; cin >> num1 >> num2; divide(num1, num2); }
464
Program continues //**************************************************************** // Definition of function divide * // Uses two parameters: arg1 and arg2. The function divides arg1 * // by arg2 and shows the result. If arg2 is zero, however, the * // function returns * void divide(float arg1, float arg2) { if (arg2 == 0.0) cout << "Sorry, I cannot divide by zero.\n"; return; } cout << "The quotient is " << (arg1 / arg2) << endl;
465
Program Output with Example Input
Enter two numbers and I will divide the first number by the second number: 12 0 [Enter] Sorry, I cannot divide by zero.
466
6.8 Returning a value From a Function
A function may send a value back to the part of the program that called the function.
467
Figure 6-10
468
Program 6-13 // This program uses a function that returns a value.
#include <iostream.h> //Function prototype int square(int); void main(void) { int value, result; cout << "Enter a number and I will square it: "; cin >> value; result = square(value); cout << value << " squared is " << result << endl; }
469
Program continues //**************************************************** // Definition of function square * // This function accepts an int argument and returns * // the square of the argument as an int * int square(int number) { return number * number; }
470
Program Output with Example Input
Enter a number and I will square it: 20 [Enter] 20 squared is 400
471
Figure 6-11 result = square(value); 20
int square(int number) { return number * number; }
472
6.9 Returning Boolean Values
Function may return true or false values.
473
Program 6-15 // This program uses a function that returns true or false. #include <iostream.h> // Function prototype bool isEven(int); void main(void) { int val; cout << "Enter an integer and I will tell you "; cout << "if it is even or odd: "; cin >> val; if (isEven(val)) cout << val << " is even.\n"; else cout << val << " is odd.\n"; }
474
Program continues //********************************************************************* // Definition of function isEven. This function accepts an * // integer argument and tests it to be even or odd. The function * // returns true if the argument is even or false if the argument is * // odd * // The return value is bool * //********************************************************************* bool isEven(int number) { bool status; if (number % 2) status = false; // The number is odd if there's a remainder. else status = true; // Otherwise, the number is even. return status; }
475
Program Output Enter an integer and I will tell you if it is even or odd: 5 [Enter] 5 is odd.
476
6.10 Local and Global Variables
A local variable is declared inside a function, and is not accessible outside the function. A global variable is declared outside all functions and is accessible in its scope.
477
Program 6-16 // This program shows that variables declared in a function // are hidden from other functions. #include <iostream.h> void func(void); // Function prototype void main(void) { int num = 1; cout << "In main, num is " << num << endl; func(); cout << "Back in main, num is still " << num << endl; }
478
Program continues //********************************************************* // Definition of function func * // It has a local variable, num, whose initial value, 20, * // is displayed * void func(void) { int num = 20; cout << "In func, num is " << num << endl; }
479
Program Output In main, num is 1 In func, num is 20
Back in main, num is still 1
480
Figure 6-8 Function main num = 1
This num variable is only visible in function main. Function func num = 20 This num variable is only visible in function func.
481
Program 6-17 // This program shows that a global variable is visible
// to all the functions that appear in a program after // the variable's declaration. #include <iostream.h> void func(void); // Function prototype int num = 2; // Global variable void main(void) { cout << "In main, num is " << num << endl; func(); cout << "Back in main, num is " << num << endl; }
482
Program continues //***************************************************** // Definition of function func * // func changes the value of the global variable num * void func(void) { cout << "In func, num is " << num << endl; num = 50; cout << "But, it is now changed to " << num << endl; }
483
Program Output In main, num is 2 In func, num is 2
But, it is now changed to 50 Back in main, num is 50
484
Program 6-18 // This program shows that a global variable is visible
// to all the functions that appear in a program after // the variable's declaration. #include <iostream.h> void func(void); // Function prototype void main(void) { cout << "In main, num is not visible!\n"; func(); cout << "Back in main, num still isn't visible!\n"; }
485
Program continues int num = 2; // Global variable
//***************************************************** // Definition of function func * // func changes the value of the global variable num. * void func(void) { cout << "In func, num is " << num << endl; num = 50; cout << "But, it is now changed to " << num << endl; }
486
Program Output In main, num is not visible! In func, num is 2
But, it is now changed to 50 Back in main, num still isn't visible!
487
Global Variables are Initialized to Zero by Default
Unless you explicitly initialize numeric global variables, they are automatically initialized to zero. Global character variables are initialized to NULL, or ASCII code 0.
488
Program 6-19 // This program has an uninitialized global variable.
#include <iostream.h> int globalNum; // Global variable. Automatically set to zero. void main(void) { cout << "globalNum is " << globalNum << endl; }
489
Program Output globalNum is 0
490
Local and Global Variables with the Same Name
If a function has a local variable with the same name as a global variable, only the local variable can be seen by the function.
491
Program 6-20 // This program shows that when a local variable has the
// same name as a global variable, the function only sees // the local variable. #include <iostream.h> // Function prototypes void texas(); void arkansas(); int cows = 10; void main(void) { cout << "There are " << cows << " cows in main.\n"; texas(); arkansas(); cout << "Back in main, there are " << cows << " cows.\n"; }
492
Program continues //******************************************
//****************************************** // Definition of function texas * // The local variable cows is set to * //****************************************** void texas(void) { int cows = 100; cout << "There are " << cows << " cows in texas.\n"; }
493
Program continues //******************************************
// Definition of function arkansas * // The local variable cows is set to * void arkansas(void) { int cows = 50; cout << "There are " << cows << " cows in arkansas.\n"; }
494
Program Output There are 10 cows in main. There are 100 cows in texas.
There are 50 cows in arkansas. Back in main, there are 10 cows.
495
Program 6-21 // This program has local and global variables. In the function // ringUpSale, there is a local variable named tax. There is // also a global variable with the same name. #include <iostream.h> void ringUpSale(void); // Function prototype // Global Variables const float taxRate = 0.06; float tax, sale, total; void main(void) { char again;
496
Program continues cout.precision(2);
cout.setf(ios::fixed | ios::showpoint); do { ringUpSale(); cout << "Is there another item to be purchased? "; cin >> again; } while (again == 'y' || again == 'Y'); tax = sale * taxRate; total = sale + tax; cout << "The tax for this sale is " << tax << endl; cout << "The total is " << total << endl; }
497
Program continues void ringUpSale(void) { int qty;
//****************************************************************** // Definition of function ringUpSale * // This function asks for the quantity and unit price of an item. * // It then calculates and displays the sales tax and subtotal * // for those items * void ringUpSale(void) { int qty; float unitPrice, tax, thisSale, subTotal; cout << "Quantity: "; cin >> qty; cout << "Unit price: "; cin >> unitPrice; thisSale = qty * unitPrice; // Get the total unit price
498
sale += thisSale; // Update global variable sale
Program continues sale += thisSale; // Update global variable sale tax = thisSale * taxRate; // Get sales tax for these items subTotal = thisSale + tax; // Get subtotal for these items cout << "Price for these items: " << thisSale << endl; cout << "tax for these items: " << tax << endl; cout << "subTotal for these items: " << subTotal << endl; }
499
Program Output with Example Input
Quantity: 2 [Enter] Unit Price: [Enter] Price for these items: 40.00 tax for these items: 2.40 subTotal for these items: 42.40 Is there another item to be purchased? y [Enter] Quantity: 3 [Enter] Unit Price: [Enter] Price for these items: 36.00 tax for these items: 2.16 subTotal for these items: 38.16 Is there another item to be purchased? n [Enter] The tax for this sale is 4.56 The total is 80.56
500
Be Careful With Global Variables
It is tempting to make all your variables global. But don’t do it! Using global variables can cause problems. It is harder to debug a program that uses global variables
501
6.11 Static Local Variables
If a function is called more than once in a program, the values stored in the function’s local variables do not persist between function calls. To get a variable to keep it’s value even after the function ends, you must create static variables
502
Program 6-22 // This program shows that local variables do not retain
// their values between function calls. #include <iostream.h> // Function prototype void showLocal(void); void main(void) { showLocal(); }
503
Program continues //*********************************************************** // Definition of function showLocal * // The initial value of localNum, which is 5, is displayed. * // The value of localNum is then changed to 99 before the * // function returns * void showLocal(void) { int localNum = 5; // Local variable cout << "localNum is " << localNum << endl; localNum = 99; }
504
Program Output localNum is 5
505
Program 6-23 //This program uses a static local variable.
#include <iostream.h> void showStatic(void); // Function prototype void main(void) { for (int count = 0; count < 5; count++) showStatic(); } //************************************************************* // Definition of function showStatic * // statNum is a static local variable. Its value is displayed * // and then incremented just before the function returns. * void showStatic(void) static int statNum; cout << "statNum is " << statNum << endl; statNum++;
506
Program Output statNum is 0 statNum is 1 statNum is 2 statNum is 3
507
Program 6-24 // This program shows that a static local variable is only // initialized once. #include <iostream.h> void showStatic(void); // Function prototype void main(void) { for (int count = 0; count < 5; count++) showStatic(); }
508
Program continues //*********************************************************** // Definition of function showStatic * // statNum is a static local variable. Its value is displayed // and then incremented just before the function returns. * void showStatic() { static int statNum = 5; cout << "statNum is " << statNum << endl; statNum++; }
509
Program Output statNum is 5 statNum is 6 statNum is 7 statNum is 8
510
6.12 Default Arguments Default arguments are passed to parameters automatically if no argument is provided in the function call. A function’s default arguments should be assigned in the earliest occurrence of the function name. This will usually mean the function prototype.
511
Program 6-25 // This program demonstrates default function arguments.
#include <iostream.h> // Function prototype with default arguments void displayStars(int = 10, int = 1); void main(void) { displayStars(); cout << endl; displayStars(5); displayStars(7, 3); }
512
Program continues //************************************************************** // Definition of function displayStars * // The default argument for cols is 10 and for rows is * // This function displays a rectangle made of asterisks * void displayStars(int cols, int rows) { // Nested loop. The outer loop controls the rows // and the inner loop controls the columns. for (int down = 0; down < rows; down++) for (int across = 0; across < cols; across++) cout << "*"; cout << endl; }
513
Program Output ********** ***** *******
514
Default Argument Summary
The value of a default argument must be a constant (either a literal value of a named constant). When an argument is left out of a function call (because it has a default value), all the arguments that come after it must be left out too. When a function has a mixture of parameters both with and without default arguments, the parameters with default arguments must be declared last.
515
6.13 Using Reference Variables as Parameters
When used as parameters, reference variables allow a function to access the parameter’s original argument, changes to the parameter are also made to the argument.
516
Example: void doubleNum(int &refVar) { refVar *= 2; }
// The variable refVar is called // “a reference to an int”
517
Program 6-26 // This program uses a reference variable as a function
// parameter. #include <iostream.h> // Function prototype. The parameter is a reference variable. void doubleNum(int &); void main(void) { int value = 4; cout << "In main, value is " << value << endl; cout << "Now calling doubleNum..." << endl; doubleNum(value); cout << "Now back in main. value is " << value << endl; }
518
Program continues //************************************************************ // Definition of doubleNum * // The parameter refVar is a reference variable. The value * // in refVar is doubled * void doubleNum (int &refVar) { refVar *= 2; }
519
Program Output In main, value is 4 Now calling doubleNum...
Now back in main. value is 8
520
Program 6-27 // This program uses reference variables as function
// parameters. #include <iostream.h> // Function prototypes. Both functions use reference variables // as parameters void doubleNum(int &); void getNum(int &); void main(void) { int value; getNum(value); doubleNum(value); cout << "That value doubled is " << value << endl; }
521
Program continues //************************************************************* // Definition of getNum * // The parameter userNum is a reference variable. The user is * // asked to enter a number, which is stored in userNum * void getNum(int &userNum) { cout << "Enter a number: "; cin >> userNum; }
522
Program continues //************************************************************ // Definition of doubleNum * // The parameter refVar is a reference variable. The value * // in refVar is doubled * void doubleNum (int &refVar) { refVar *= 2; }
523
Program Output with Example Input
Enter a number: 12 [Enter] That value doubled is 24
524
Reference Argument Warning
Don’t get carried away with using reference variables as function parameters. Any time you allow a function to alter a variable that’s outside the function, you are creating potential debugging problems. Reference variables should only be used as parameters when the situation demands them.
525
6.14 Overloaded Functions Two or more functions may have the same name as long as their parameter lists are different.
526
Program 6-28 #include <iostream.h> // Function prototypes
int square(int); float square(float); void main(void) { int userInt; float userFloat; cout.precision(2); cout << "Enter an integer and a floating-point value: "; cin >> userInt >> userFloat; cout << "Here are their squares: "; cout << square(userInt) << " and " << square(userFloat); }
527
Program continues int square(int number) { return number * number; }
// Definition of overloaded function square. // This function uses an int parameter, number. It returns the // square of number as an int. int square(int number) { return number * number; } // This function uses a float parameter, number. It returns the // square of number as a float. float square(float number)
528
Program Output with Example Input
Enter an integer and floating-point value: [Enter] Here are their squares: 144 and 17.64
529
Program 6-29 // This program demonstrates overloaded functions to calculate // the gross weekly pay of hourly-paid or salaried employees. #include <iostream.h> // Function prototypes void getChoice(char &); float calcWeeklyPay(int, float); float calcWeeklyPay(float); void main(void) { char selection; int worked; float rate, yearly; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << “Do you want to calculate the weekly pay of\n"; cout << “(H) an hourly-paid employee, or \n”; cout << “(S) a salaried employee?\n”;
530
Program continues { case ‘H’ :
getChoice(selection); switch (selection) { case ‘H’ : case ‘h’ : cout << “How many hours were worked? “; cin >> worked; cout << “What is the hour pay rate? “; cin >> rate; cout << “The gross weekly pay is “; cout << calcWeeklyPay(worked, rate); break; case ‘S’ : case ‘s’ : cout << “What is the annual salary? “; cin >> yearly; cout << calcWeeklyPay(yearly); }
531
Program continues void getChoice(char &letter) { do
//*********************************************************** // Definition of function getChoice * // The parameter letter is a reference to a char * // This function asks the user for an H or an S and returns * // the validated input * void getChoice(char &letter) { do cout << “Enter your choice (H or S): “; cin >> letter; } while (letter != ‘H’ && letter != ‘h’ && letter != ‘S’ && letter != ‘s’); }
532
Program continues void calcWeekly(int hours, float payRate) {
//*********************************************************** // Definition of overloaded function calcWeeklyPay * // This function calculates the gross weekly pay of * // an hourly-paid employee. The parameter hours hold the * // hourly pay rate. The function returns the weekly salary. * void calcWeekly(int hours, float payRate) { return hours * payRate; }
533
Program continues void calcWeekly(float annSalary) {
//*********************************************************** // Definition of overloaded function calcWeeklyPay * // This function calculates the gross weekly pay of * // a salaried employee. The parameter holds the employee’s * // annual salary. The function returns the weekly salary. * void calcWeekly(float annSalary) { return annSalary / 52.0; }
534
Program Output with Example Input
Do you want to calculate the weekly pay of (H) an houly-paid employee, or (S) a salaried employee? H[Enter] How many hours were worked? 40[Enter] What is the hour pay rate? 18.50[Enter] The gross weekly pay is Program Output with Other Example Input (S) a salaried employee? S[Enter] What is the annual salary? [Enter] The gross weekly pay is
535
6.15 The exit() Function The exit() function causes a program to terminate, regardless of which function or control mechanism is executing.
536
Program 6-30 // This program shows how the exit function causes a program // to stop executing. #include <iostream.h> #include <stdlib.h> // For exit void function(void); // Function prototype void main(void) { function(); }
537
Program continues //*********************************************************** // This function simply demonstrates that exit can be used * // to terminate a program from a function other than main. * void function(void) { cout << "This program terminates with the exit function.\n"; cout << "Bye!\n"; exit(0); cout << "This message will never be displayed\n"; cout << "because the program has already terminated.\n"; }
538
Program Output This program terminates with the exit function. Bye!
539
Program 6-31 // This program demonstrates the exit function.
#include <iostream.h> #include <stdlib.h> // For exit void main(void) { char response; cout << "This program terminates with the exit function.\n"; cout << "Enter S to terminate with the EXIT_SUCCESS code\n"; cout << "or f to terminate with the EXIT_FAILURE code: "; cin >> response;
540
Program continues if (response == 'S') {
cout << "Exiting with EXIT_SUCCESS.\n"; exit(EXIT_SUCCESS); } else cout << "Exiting with EXIT_FAILURE.\n"; exit(EXIT_FAILURE);
541
Program Output with Example Input
This program terminates with the exit function. Enter S to terminate with the EXIT_SUCCESS code or f to terminate with the EXIT_FAILURE code: s [Enter] Exiting with EXIT_SUCCESS. Program Output With Other Example Input or f to terminate with the EXIT_FAILURE code: f [Enter] Exiting with EXIT_FAILURE.
542
6.16 Stubs and Drivers Stubs and drivers are very helpful tools for testing and debugging programs that use functions. A stub is a dummy function that is called instead of the actual function it represents. A driver is a program that tests a function by simply calling it.
543
// Stub for the adult function.
void adult(int months) { cout << "The function adult was called with " << months; cout << " as its argument.\n"; } // Stub for the child function. void child(int months) cout << "The function child was called with " << months; // Stub for the senior function. void senior(int months) cout << "The function senior was called with " << months;
544
Chapter 7 – Arrays
545
7.1 Arrays Hold Multiple values
Unlike regular variables, arrays can hold multiple values.
546
Figure 7-1 int count Enough memory for 1 int 12345 float price
Enough memory for 1 float 56.981 char letter Enough memory for 1 char A
547
Figure 7-2
548
Table 7-1
549
7.2 Accessing Array elements
The individual elements of an array are assigned unique subscripts. These subscripts are used to access the elements.
550
Program 7-1 // This program asks the user for the number of hours worked // by 6 employees. It uses a 6-element int array to store the // values. #include <iostream.h> void main(void) { short hours[6]; cout << "Enter the hours worked by six employees: "; cin >> hours[0]; cin >> hours[1]; cin >> hours[2]; cin >> hours[3];
551
Program continues cin >> hours[4]; cin >> hours[5];
cout << "The hours you entered are:"; cout << " " << hours[0]; cout << " " << hours[1]; cout << " " << hours[2]; cout << " " << hours[3]; cout << " " << hours[4]; cout << " " << hours[5] << endl; }
552
Program Output with Example Input
Enter the hours worked by six employees: [Enter] The hours you entered are:
553
Figure 7-7
554
Program 7-2 // This program asks the user for the number of hours worked // by 6 employees. It uses a 6-element short array to store the // values. #include <iostream.h> void main(void) { short hours[6]; cout << "Enter the hours worked by six employees: "; for (int count = 0; count < 6; count++) cin >> hours[count]; cout << "The hours you entered are:"; for (count = 0; count < 6; count++) cout << " " << hours[count]; cout << endl; }
555
Program Output with Example Input
Enter the hours worked by six employees: [Enter] The hours you entered are:
556
Program 7-3 // This program asks the user for the number of hours worked // by 6 employees. It uses a 6-element short array to store the // values. #include<iostream.h> void main(void) { short hours[6]; cout << "Enter the hours worked by six employees.\n"; for (int count = 1; count <= 6; count++) cout << "Employee " << count << ": "; cin >> hours[count - 1]; } cout << "The hours you entered are\n";
557
Program continues for (count = 1; count <= 6; count++) {
cout << "Employee " << count << ": "; cout << hours[count - 1] << endl; }
558
Program Output with Example Input
Enter the hours worked by six employees. Employee 1: 20 [Enter] Employee 2: 12 [Enter] Employee 3: 40 [Enter] Employee 4: 30 [Enter] Employee 5: 30 [Enter] Employee 6: 15 [Enter] The hours you entered are Employee 1: 20 Employee 2: 12 Employee 3: 40 Employee 4: 30 Employee 5: 30 Employee 6: 15
559
7.3 No Bounds Checking in C++
C++ gives you the freedom to store data past an array’s boundaries.
560
Program 7-4 // This program unsafely accesses an area of memory by writing // values beyond an array's boundary. // WARNING: If you compile and run this program, it could cause // the computer to crash. #include <iostream.h> void main(void) { short values[3]; // An array of 3 short integers. cout << "I will store 5 numbers in a 3 element array!\n"; for (int count = 0; count < 5; count++) values[count] = 100; cout << "If you see this message, it means the computer\n"; cout << "has not crashed! Here are the numbers:\n"; cout << values[count] << endl; }
561
Figure 7-8
562
7.4 Array Initialization Arrays may be initialized when they are declared.
563
Program 7-5 // This program displays the number of days in each month.
// It uses a 12-element int array. #include <iostream.h> void main(void) { int days[12]; days[0] = 31; // January days[1] = 28; // February days[2] = 31; // March days[3] = 30; // April days[4] = 31; // May days[5] = 30; // June days[6] = 31; // July
564
Program continues days[7] = 31; // August days[8] = 30; // September
days[9] = 31; // October days[10] = 30; // November days[11] = 31; // December for (int count = 0; count < 12; count++) { cout << "Month " << (count + 1) << " has "; cout << days[count] << " days.\n"; }
565
Program Output Month 1 has 31 days. Month 2 has 28 days.
566
Program 7-6 // This program displays the number of days in each month.
// It uses a 12-element int array. #include <iostream.h> void main(void) { int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; for (int count = 0; count < 12; count++) cout << "Month " << (count + 1) << " has "; cout << days[count] << " days.\n"; }
567
Program Output Month 1 has 31 days. Month 2 has 28 days.
568
Program 7-7 // This program uses an array of ten characters to store the // first ten letters of the alphabet. The ASCII codes of the // characters are displayed. #include <iostream.h> void main(void) { char letters[10] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}; cout << "Character" << "\t" << "ASCII Code\n"; cout << " " << "\t" << " \n"; for (int count = 0; count < 10; count++) cout << letters[count] << "\t\t"; cout << int(letters[count]) << endl; }
569
Program Output Character ASCII Code --------- ---------- A 65 B 66
A 65 B 66 C 67 D 68 E 69 F 70 G 71 H 72 I 73 J 74
570
Partial Array Initialization
When an array is being initialized, C++ does not require a value for every element. int numbers[7] = {1, 2, 4, 8};
571
Program 7-8 // This program has a partially initialized array.
#include <iostream.h> void main(void) { int numbers[7] = {1, 2, 4, 8}; // Initialize the // first 4 elements. cout << "Here are the contents of the array:\n"; for (int index = 0; index < 7; index++) cout << numbers[index] << endl; }
572
Program Output Here are the contents of the array: 1 2 4 8
573
Implicit Array Sizing It is possible to declare an array without specifying its size, as long as you provide an initialization list. float ratings[] = {1.0, 1.5, 2.0, 2.5, 3.0};
574
Initializing With Strings
When initializing a character array with a string, simply enclose the string in quotation marks: char name[] = “Warren”;
575
Figure 7-11
576
Program 7-9 // This program displays the contents of two char arrays.
#include <iostream.h> void main(void) { char name1[] = "Holly"; char name2[] = {'W', 'a', 'r', 'r', 'e', 'n', '\0'}; cout << name1 << endl; cout << name2 << endl; }
577
Program Output Holly Warren
578
7.5 Processing Array Contents
Individual array elements are processed like any other type of variable.
579
Program 7-10 // This program stores, in an array, the hours worked by 5 // employees who all make the same hourly wage. #include <iostream.h> void main(void) { int hours[5]; float payRate; cout << "Enter the hours worked by 5 employees who all\n"; cout << "earn the same hourly rate.\n"; for (int index = 0; index < 5; index++) cout << "Employee #" << (index + 1) << ": "; cin >> hours[index]; }
580
Program continues cout << "Enter the hourly pay rate for all the employees: "; cin >> payRate; cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < 5; index++) { float grossPay = hours[index] * payRate; cout << "Employee #" << (index + 1); cout << ": $" << grossPay << endl; }
581
Program Output with Example Input
Enter the hours worked by 5 employees who all earn the same hourly rate. Employee #1: 5 [Enter] Employee #2: 10 [Enter] Employee #3: 15 [Enter] Employee #4: 20 [Enter] Employee #5: 40 [Enter] Enter the hourly pay rate for all the employees: [Enter] Here is the gross pay for each employee: Employee #1: $63.75 Employee #2: $127.50 Employee #3: $191.25 Employee #4: $255.00 Employee #5: $510.00
582
Program 7-11 // This program stores, in an array, the hours worked by 5 // employees who all make the same hourly wage. It then // displays the gross pay, including any overtime. #include <iostream.h> // Constant for defining the array size void main(void) { int hours[5]; float payRate; cout << "Enter the hours worked by 5 employees who all\n"; cout << "earn the same hourly rate.\n"; for (int index = 0; index < 5; index++) cout << "Employee #" << (index + 1) << ": "; cin >> hours[index]; }
583
Program continues cout << "Enter the hourly pay rate for all the employees: "; cin >> payRate; cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < 5; index++) { float grossPay, overTime; if (hours[index] > 40) // Calculate pay for 40 hours. grossPay = 40 * payRate; // Calculate overtime pay. overTime = (hours[index] - 40) * 1.5 * payRate; // Add regular pay and overtime pay. grossPay += overTime; }
584
Program continues else grossPay = hours[index] * payRate;
cout << "Employee #" << (index + 1); cout << ": $" << grossPay << endl; }
585
Program Output with Example Input
Enter the hours worked by 5 employees who all earn the same hourly rate. Employee #1: 10 [Enter] Employee #2: 20 [Enter] Employee #3: 50 [Enter] Employee #4: 40 [Enter] Employee #5: 60 [Enter] Enter the hourly pay rate for all the employees: [Enter] Here is the gross pay for each employee: Employee #1: $127.50 Employee #2: $255.00 Employee #3: $701.25 Employee #4: $510.00 Employee #5: $892.50
586
7.6 Focus on Software Engineering: Parallel Arrays
By using he same subscript, you can build relationships between data stored in two or more arrays.
587
Program 7-12 // This program stores, in two arrays, the hours worked by 5 // employees, and their hourly pay rates. #include <iostream.h> // Constant for defining the array size const int numEmps = 5; void main(void) { int hours[numEmps]; float payRate[numEmps]; cout << "Enter the hours worked by “ << numEmps << “ employees and their\n"; cout << "hourly rates.\n"; for (int index = 0; index < numEmps; index++) cout << "hours worked by employee #" << (index + 1); cout << ": ";
588
Program continues cin >> hours[index];
cout << "Hourly pay rate for employee #"; cout << (index + 1) << ": "; cin >> payRate[index]; } cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < numEmps; index++) { float grossPay = hours[index] * payRate[index]; cout << "Employee #" << (index + 1); cout << ": $" << grossPay << endl;
589
Program Output with Example Input
Enter the hours worked by 5 employees and their hourly rates. hours worked by employee #1: 10 [Enter] Hourly pay rate for employee #1: 9.75 [Enter] hours worked by employee #2: 15 [Enter] Hourly pay rate for employee #2: 8.62 [Enter] hours worked by employee #3: 20 [Enter] Hourly pay rate for employee #3: [Enter] hours worked by employee #4: 40 [Enter] Hourly pay rate for employee #4: [Enter] hours worked by employee #5: 40 [Enter] Hourly pay rate for employee #5: [Enter] Here is the gross pay for each employee: Employee #1: $97.50 Employee #2: $129.30 Employee #3: $210.00
590
7.7 Thou Shalt Not Assign You cannot use the assignment operator to copy one array’s contents to another. for (int count=0; count < 4; count++) newVal[count] = oldVal[count];
591
Table 7-2
592
7.8 Printing the Contents of an Array
To display the contents of an array, you must use a loop to display the contents of each element. int array[5] = { 10, 20, 30, 40, 50 }; for (int count = 0; count < 5; count++) cout << array[count] << endl;
593
7.9 Arrays As Function Arguments
To pass an array as an argument to a function, pass the name of the array.
594
Program 7-13 // This program demonstrates that an array element is passed // to a function like any other variable. #include <iostream.h> void ShowValue(int); // Function prototype void main(void) { int collection[8] = {5, 10, 15, 20, 25, 30, 35, 40}; for (int Cycle = 0; Cycle < 8; Cycle++) ShowValue(collection[Cycle]); }
595
Program continues //************************************
// Definition of function showValue * // This function accepts an integer argument. * // The value of the argument is displayed * void ShowValue(int Num) { cout << Num << " "; }
596
Program Output
597
Program 7-14 // This program demonstrates an array being passed to a function. #include <iostream.h> void showValues(int []); // Function prototype void main(void) { int collection[8] = {5, 10, 15, 20, 25, 30, 35, 40}; showValues(collection); // Passing address of array collection } //*********************************************** // Definition of function showValues * // This function accepts an array of 8 integers * // as its argument. The contents of the array * // is displayed * void showValues(int nums[]) for (int index = 0; index < 8; index++) cout << nums[index] << " ";
598
Program Output
599
Program 7-15 // This program demonstrates an array being passed to a function. #include <iostream.h> void showValues(int []); // Function prototype void main(void) { int set1[8] = {5, 10, 15, 20, 25, 30, 35, 40}; int set2[8] = {2, 4, 6, 8, 10, 12, 14, 16}; showValues(set1); cout << endl; showValues(set2); } //*********************************************** // Definition of function showValues * // This function accepts an array of 8 integers * // as its argument. The contents of the array * // is displayed * void showValues(int nums[]) for (int index = 0; index < 8; index++) cout << nums[index] << " ";
600
Program Output
601
Program 7-16 // This program uses a function that can display the contents // of an integer array of any size. #include <iostream.h> void showValues(int [], int); // Function prototype void main(void) { int set1[8] = {5, 10, 15, 20, 25, 30, 35, 40}; int set2[4] = {2, 4, 6, 8}; int set3[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; showValues(set1, 8); cout << endl; showValues(set2, 4); showValues(set3, 12); }
602
Program continues //***********************************************
// Definition of function showValues * // This function displays the contents of the * // array passed into nums. The value passed * // into elements is the number of elements in * // the nums array * void showValues(int nums[], int elements) { for (int index = 0; index < elements; index++) cout << nums[index] << " "; }
603
Program Output
604
Program 7-17 // This program uses a function that doubles the contents of // the elements within an array. #include <iostream.h> void doubleArray(int [], int); // Function prototype const int arraySize = 12; void main(void) { int set[arraySize] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; cout << "The arrays values are:\n"; for (int index = 0; index < arraySize; index++) cout << set[index] << " "; cout << endl; doubleArray(set, arraySize); cout << "After calling doubleArray, the values are:\n";
605
Program continues for (int index = 0; index < arraySize; index++)
cout << set[index] << " "; cout << endl; } //************************************************** // Definition of function doubleArray * // This function doubles the value of each element * // in the array passed into nums * // The value passed into size is the number of * // elements in the nums array * void doubleArray(int nums[], int size) { for (int index = 0; index < size; index++) nums[index] *= 2;
606
Program Output The array values are: 1 2 3 4 5 6 7 8 9 10 11 12
After calling doubleArray, the values are:
607
7.10 Two-dimensional Arrays
A two-dimensional array is like several identical arrays put together. It is useful for storing multiple sets of data.
608
Program 7-18 // This program demonstrates a two-dimensional array.
#include <iostream.h> void main(void) { float sales[3][4]; // 2D array, 3 rows and 4 columns. float totalSales = 0; // To hold the total sales. int dir, qtr; // Loop counters.
609
Program continues cout << "This program will calculate the total sales of\n"; cout << "all the company's divisions.\n"; cout << "Enter the following sales information:\n\n"; // Nested loops to fill the array with quarterly // sales figures for each division. for (div = 0; div < 3; div++) { for (qtr = 0; qtr < 4; qtr++) cout << "Division " << (div + 1); cout << ", Quarter " << (qtr + 1) << ": $"; cin >> sales[div][qtr]; } cout << endl; // Print blank line.
610
Program continues // Nested loops to add all the elements.
for (div = 0; div < 3; div++) for (qtr = 0; qtr < 4; qtr++) totalSales += sales[div][qtr]; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "The total sales for the company are: $"; cout << totalSales << endl; }
611
Program Output with Example Input
This program will calculate the total sales of all the company's divisions. Enter the following sales information: Division 1, Quarter 1: $ [Enter] Division 1, Quarter 2: $ [Enter] Division 1, Quarter 3: $ [Enter] Division 1, Quarter 4: $ [Enter] Division 2, Quarter 1: $ [Enter] Division 2, Quarter 2: $ [Enter] Division 2, Quarter 3: $ [Enter] Division 2, Quarter 4: $ [Enter]
612
Output continues Division 3, Quarter 1: $29654.35 [Enter]
The total sales for the company are: $
613
Passing Two-dimensional Arrays to Functions
When a two-dimensional array is passed to a function, the parameter type must contain a size declarator for the number of columns.
614
7.11 Arrays of Strings A two-dimensional array of characters can be used as an array of C-strings.
615
Program 7-20 // This program displays the number of days in each month. // It uses a two-dimensional character array to hold the // names of the months and an int array to hold the number // of days. #include <iostream.h> void main(void) { char months[12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September”, "October", "November","December"}; int days[12] = { 31, 28, 31, 30, , 30, 31, 31, , 31, 30, 31}; for (int count = 0; count < 12; count++) { cout << months[count] << " has "; cout << days[count] << " days.\n"; } }
616
Program 7-20 (continued) Program Output
January has 31 days. February has 28 days. March has 31 days. April has 30 days. May has 31 days. June has 30 days. July has 31 days. August has 31 days. September has 30 days. October has 31 days. November has 30 days. December has 31 days.
617
Three Dimensional Arrays and Beyond
C++ allows you to create arrays with virtually any number of dimensions. Here is an example of a three-dimensional array declaration: float seat[3][5][8];
618
7.14 Introduction to the STL vector
The Standard Template Library (or STL) is a collection of data types and algorithms that you may use in your programs. These data types and algorithms are programmer-defined. They are not part of the C++ language, but were created in addition to the built-in data types.
619
7.14 Introduction to the STL vector
The data types that are defined in the STL are commonly called containers, because they store and organize data. There are two types of containers in the STL: sequence containers and associative containers. The vector data type is a sequence container.
620
7.14 Introduction to the STL vector
A vector is like an array in the following ways: A vector holds a sequence of values, or elements. A vector stores its elements in contiguous memory locations. You can use the array subscript operator [] to read the individual elements in the vector
621
7.14 Introduction to the STL vector
However, a vector offers several advantages over arrays. Here are just a few: You do not have to declare the number of elements that the vector will have. If you add a value to a vector that is already full, the vector will automatically increase its size to accommodate the new value. vectors can report the number of elements they contain.
622
Declaring a vector To use vectors in your program, you must first #include the vector header file with the following statement: #include <vector> Note: There is no .h at the end of the file name.
623
Declaring a vector The next step is to include the following statement after your #include statements: using namespace std; The STL uses namespaces to organize the names of its data types and algorithms.
624
Declaring a vector Now you are ready to declare an actual vector object. Here is an example: vector<int> numbers; The statement above declares numbers as a vector of ints.
625
Declaring a vector You can declare a starting size, if you prefer. Here is an example: vector<int> numbers(10); The statement above declares numbers as a vector of 10 ints.
626
Other examples of vector Declarations
Declaration Format Description vector<float> amounts; Declares amounts as an empty vector of floats. vector<int> scores(15); Declares scores as a vector of 15 ints. vector<char> letters(25, 'A'); Declares letters as a vector of 25 characters. Each element is initialized with 'A'. vector<double> values2(values1); Declares values2 as a vector of doubles. All the elements of values1, which also a vector of doubles, are copied to value2.
627
Storing and Retrieving Values in a vector
To store a value in an element that already exists in a vector, you may use the array subscript operator [].
628
Program 7-23 // This program stores, in two vectors, the hours worked by 5 // employees, and their hourly pay rates. #include <iostream.h> #include <vector> // Needed to declare vectors using namespace std; void main(void) { vector<int> hours(5); // Declare a vector of 5 integers vector<float> payRate(5); // Declare a vector of 5 floats cout << "Enter the hours worked by 5 employees and their\n"; cout << "hourly rates.\n"; for (int index = 0; index < 5; index++) { cout << "Hours worked by employee #" << (index + 1); cout << ": "; cin >> hours[index]; cout << "Hourly pay rate for employee #"; cout << (index + 1) << ": "; cin >> payRate[index]; }
629
Program 7-23 (continued) cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < 5; index++) { float grossPay = hours[index] * payRate[index]; cout << "Employee #" << (index + 1); cout << ": $" << grossPay << endl; } }
630
Program 7-23 (continued) Program Output with Example Input Shown in Bold Enter the hours worked by 5 employees and their hourly rates. Hours worked by employee #1: 10 [Enter] Hourly pay rate for employee #1: 9.75 [Enter] Hours worked by employee #2: 15 [Enter] Hourly pay rate for employee #2: 8.62 [Enter] Hours worked by employee #3: 20 [Enter] Hourly pay rate for employee #3: [Enter] Hours worked by employee #4: 40 [Enter] Hourly pay rate for employee #4: [Enter] Hours worked by employee #5: 40 [Enter] Hourly pay rate for employee #5: [Enter] Here is the gross pay for each employee: Employee #1: $97.50 Employee #2: $ Employee #3: $ Employee #4: $ Employee #5: $626.00
631
Using the push_back Member Function
You cannot use the [] operator to access a vector element that does not exist. To store a value in a vector that does not have a starting size, or is already full, use the push_back member function. Here is an example: numbers.push_back(25);
632
Program 7-24 // This program stores, in two vectors, the hours worked by a specified // number of employees, and their hourly pay rates. #include <iostream.h> #include <vector> // Needed to declare vectors using namespace std; void main(void) { vector<int> hours; // hours is an empty vector vector<float> payRate; // payRate is an empty vector int numEmployees; // The number of employees cout << "How many employees do you have? "; cin >> numEmployees; cout << "Enter the hours worked by " << numEmployees; cout << " employees and their hourly rates.\n";
633
Program 7-24 (continued) for (int index = 0; index < numEmployees; index++) { int tempHours; // To hold the number of hours entered float tempRate; // To hold the payrate entered cout << "Hours worked by employee #" << (index + 1); cout << ": "; cin >> tempHours; hours.push_back(tempHours); // Add an element to hours cout << "Hourly pay rate for employee #"; cout << (index + 1) << ": "; cin >> tempRate; payRate.push_back(tempRate); // Add an element to payRate } cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < numEmployees; index++) { float grossPay = hours[index] * payRate[index]; cout << "Employee #" << (index + 1); cout << ": $" << grossPay << endl; } }
634
Program 7-24 (continued) Program Output with Example Input Shown in Bold How many employees do you have? 3 [Enter] Enter the hours worked by 3 employees and their hourly rates. Hours worked by employee #1: 40 [Enter] Hourly pay rate for employee #1: [Enter] Hours worked by employee #2: 25 [Enter] Hourly pay rate for employee #2: [Enter] Hours worked by employee #3: 45 [Enter] Hourly pay rate for employee #3: [Enter] Here is the gross pay for each employee: Employee #1: $ Employee #2: $ Employee #3: $
635
Determining the Size of a vector
Unlike arrays, vectors can report the number of elements they contain. This is accomplished with the size member function. Here is an example of a statement that uses the size member function: numValues = set.size(); In the statement above, assume that numValues is an int, and set is a vector. After the statement executes, numValues will contain the number of elements in the vector set.
636
Determining the Size of a vector
Example: void showValues(vector<int> vect) { for (int count = 0; count < vect.size(); count++) cout << vect[count] << endl; }
637
Program 7-25 // This program demonstrates the vector size // member function. #include <iostream.h> #include <vector> using namespace std; // Function prototype void showValues(vector<int>); void main(void) { vector<int> values; for (int count = 0; count < 7; count++) values.push_back(count * 2); showValues(values); }
638
Program 7-25 (continued) //************************************************** // Definition of function showValues * // This function accepts an int vector as its * // argument. The value of each of the vector's * // elements is displayed * //************************************************** void showValues(vector<int> vect) { for (int count = 0; count < vect.size(); count++) cout << vect[count] << endl; }
639
Program 7-25 (continued) Program Output
640
Removing Elements from a vector
Use the pop_back member function to remove the last element from a vector. collection.pop_back(); The statement above removes the last element from the collection vector.
641
Program 7-26 // This program demosntrates the vector size member function. #include <iostream.h> #include <vector> using namespace std; void main(void) { vector<int> values; // Store values in the vector values.push_back(1); values.push_back(2); values.push_back(3); cout << "The size of values is " << values.size() << endl; // Remove a value from the vector cout << "Popping a value from the vector...\n"; values.pop_back(); cout << "The size of values is now " << values.size() << endl;
642
Program 7-26 (continued) // Now remove another value from the vector cout << "Popping a value from the vector...\n"; values.pop_back(); cout << "The size of values is now " << values.size() << endl; // Remove the last value from the vector cout << "Popping a value from the vector...\n"; values.pop_back(); cout << "The size of values is now " << values.size() << endl; } Program Output The size of values is 3 Popping a value from the vector... The size of values is now 2 Popping a value from the vector... The size of values is now 1 Popping a value from the vector... The size of values is now 0
643
Clearing a vector To completely clear the contents of a vector, use the clear member function. Here is an example: numbers.clear(); After the statement above executes, the numbers vector will be cleared of all its elements.
644
Program 7-27 // This program demosntrates the vector size member function. #include <iostream.h> #include <vector> using namespace std; void main(void) { vector<int> values(100); cout << "The values vector has “ << values.size() << " elements.\n"; cout << "I will call the clear member function...\n"; values.clear(); cout << "Now, the values vector has “ << values.size() << " elements.\n"; }
645
Program 7-27 (continued) Program Output The values vector has 100 elements. I will call the clear member function... Now, the values vector has 0 elements.
646
Detecting an Empty vector
To determine if a vector is empty, use the empty member function. The function returns true if the vector is empty, and false if the vector has elements stored in it. Here is an example of its use: if (set.empty()) cout << "No values in set.\n";
647
Program 7-28 // This program demosntrates the vector's empty member function. #include <iostream.h> #include <vector> using namespace std; // Function prototype float avgVector(vector<int>); void main(void) { vector<int> values; int numValues; float average; cout << "How many values do you wish to average? "; cin >> numValues;
648
Program 7-28 (continued) for (int count = 0; count < numValues; count++) { int tempValue; cout << "Enter a value: "; cin >> tempValue; values.push_back(tempValue); } average = avgVector(values); cout << "Average: " << average << endl; } //************************************************************* // Definition of function avgVector * // This function accepts an int vector as its argument. If * // the vector contains values, the function returns the * // average of those values. Otherwise, an error message is * // displayed and the function returns * //*************************************************************
649
Program 7-28 (continued) float avgVector(vector<int> vect) { int total = 0; // accumulator float avg; // average if (vect.empty()) // Determine if the vector is empty { cout << "No values to average.\n"; avg = 0.0; } else { for (int count = 0; count < vect.size(); count++) total += vect[count]; avg = total / vect.size(); } return avg; }
650
Program 7-28 (continued) Program Output with Example Input Shown in Bold How many values do you wish to average? Enter a value: 12 Enter a value: 18 Enter a value: 3 Enter a value: 7 Enter a value: 9 Average: 9 Program Output with Example Input Shown in Bold How many values do you wish to average? 0 No values to average. Average: 0
651
Summary of vector Member Functions
Description at(element) Returns the value of the element located at element in the vector. Example: x = vect.at(5); The statement above assigns the value of the 5th element of vect to x. capacity() Returns the maximum number of elements that may be stored in the vector without additional memory being allocated. (This is not the same value as returned by the size member function). x = vect.capacity(); The statement above assigns the capacity of vect to x.
652
Summary of vector Member Functions
clear() Clears a vector of all its elements. Example: vect.clear(); The statement above removes all the elements from vect. empty() Returns true if the vector is empty. Otherwise, it returns false. if (vect.empty()) cout << "The vector is empty."; The statement above displays the message if vect is empty. pop_back() Removes the last element from the vector. vect.pop_back(); The statement above removes the last element of vect, thus reducing its size by 1.
653
Summary of vector Member Functions
push_back(value) Stores a value in the last element of the vector. If the vector is full or empty, a new element is created. Example: vect.push_back(7); The statement above stores 7 in the last element of vect. reverse() Reverses the order of the elements in the vector (the last element becomes the first element, and the first element becomes the last element.) vect.reverse(); The statement above reverses the order of the element in vect. resize(elements, value) Resizes a vector by elements elements. Each of the new elements is initialized with the value in value. vect.resize(5, 1); The statement above increases the size of vect by 5 elements. The 5 new elements are initialized to the value 1.
654
Summary of vector Member Functions
swap(vector2) Swaps the contents of the vector with the contents of vector2. Example: vect1.swap(vect2); The statement above swaps the contents of vect1 and vect2.
655
Chapter 8 – Searching and Sorting Arrays
656
8.1 Introduction to Search Algorithms
A search algorithm is a method of locating a specific item of information in a larger collection of data. This section discusses two algorithms for searching the contents of an array.
657
The Linear Search This is a very simple algorithm.
It uses a loop to sequentially step through an array, starting with the first element. It compares each element with the value being searched for and stops when that value is found or the end of the array is reached.
658
Program 8-1 // This program demonstrates the searchList function, which // performs a linear search on an integer array. #include <iostream.h> // Function prototype int searchList(int [], int, int); const int arrSize = 5; void main(void) { int tests[arrSize] = {87, 75, 98, 100, 82}; int results;
659
Program continues results = searchList(tests, arrSize, 100);
if (results == -1) cout << "You did not earn 100 points on any test\n"; else { cout << "You earned 100 points on test "; cout << (results + 1) << endl; }
660
Program continues // The searchList function performs a linear search on an // integer array. The array list, which has a maximum of numElems // elements, is searched for the number stored in value. If the // number is found, its array subscript is returned. Otherwise, // -1 is returned indicating the value was not in the array. int searchList(int list[], int numElems, int value) { int index = 0; // Used as a subscript to search array int position = -1; // To record position of search value bool found = false; // Flag to indicate if the value was found while (index < numElelments && !found) if (list[count] == value) found = true; position = index; } index++; return position;
661
Program Output You earned 100 points on test 4
662
Efficiency of the Linear Search
The advantage is its simplicity. It is easy to understand Easy to implement Does not require the array to be in order The disadvantage is its inefficiency If there are 20,000 items in the array and what you are looking for is in the 19,999th element, you need to search through the entire list.
663
Binary Search The binary search is much more efficient than the linear search. It requires the list to be in order. The algorithm starts searching with the middle element. If the item is less than the middle element, it starts over searching the first half of the list. If the item is greater than the middle element, the search starts over starting with the middle element in the second half of the list. It then continues halving the list until the item is found.
664
Program 8-2 // This program demonstrates the binarySearch function, which // performs a binary search on an integer array. #include <iostream.h> // Function prototype int binarySearch(int [], int, int); const int arrSize = 20; void main(void) { int tests[arrSize] = {101, 142, 147, 189, 199, 207, 222, 234, 289, 296, 310, 319, 388, 394, 417, 429, 447, 521, 536, 600};
665
Program continues int results, empID;
cout << "Enter the Employee ID you wish to search for: "; cin >> empID; results = binarySearch(tests, arrSize, empID); if (results == -1) cout << "That number does not exist in the array.\n"; else { cout << "That ID is found at element " << results; cout << " in the array\n"; }
666
Program continues // The binarySearch function performs a binary search on an integer array. Array, // which has a maximum of numElems elements, is searched for the number // stored in value. If the number is found, its array subscript is returned. // Otherwise, -1 is returned indicating the value was not in the array. int binarySearch(int array[], int numelems, int value) { int first = 0, last = numelems - 1, middle, position = -1; bool found = false; while (!found && first <= last) { middle = (first + last) / 2; // Calculate mid point if (array[middle] == value) // If value is found at mid { found = true; position = middle; } else if (array[middle] > value) // If value is in lower half last = middle - 1; else first = middle + 1; // If value is in upper half return position;
667
Program Output with Example Input
Enter the Employee ID you wish to search for: 199 That ID is found at element 4 in the array.
668
Efficiency of the Binary Search
Much more efficient than the linear search.
669
8.3 Focus on Software Engineering: Introduction to Sorting Algorithms
Sorting algorithms are used to arrange random data into some order
670
The Bubble Sort An easy way to arrange data in ascending or descending order. Pseudocode: Do Set count variable to 0 For count is set to each subscript in Array from 0 to the next-to-last subscript If array[count] is greater than array[count+1] swap them set swap flag to true end if End for While any elements have been swapped.
671
Program 8-4 // This program uses the bubble sort algorithm to sort an
// array in ascending order. #include <iostream.h> // Function prototypes void sortArray(int [], int); void showArray(int [], int); void main(void) { int values[6] = {7, 2, 3, 8, 9, 1}; cout << "The unsorted values are:\n"; showArray(values, 6); sortArray(values, 6); cout << "The sorted values are:\n"; }
672
Program continues // Definition of function sortArray. This function performs an ascending // order bubble sort on Array. elems is the number of elements in the array. void sortArray(int array[], int elems) { int swap, temp; do swap = 0; for (int count = 0; count < (elems - 1); count++) if (array[count] > array[count + 1]) temp = array[count]; array[count] = array[count + 1]; array[count + 1] = temp; swap = 1; } } while (swap != 0);
673
Program continues // Definition of function showArray.
// This function displays the contents of array. elems is the // number of elements. void showArray(int array[], int elems) { for (int count = 0; count < elems; count++) cout << array[count] << " "; cout << endl; }
674
Program Output The unsorted values are: 7 2 3 8 9 1
The sorted values are:
675
The Selection Sort The bubble sort is inefficient for large arrays because items only move by one element at a time. The selection sort moves items immediately to their final position in the array so it makes fewer exchanges.
676
Selection Sort Pseudocode:
For Start is set to each subscript in Array from 0 through the next-to-last subscript Set Index variable to Start Set minIndex variable to Start Set minValue variable to array[Start] For Index is set to each subscript in Array from Start+1 through the next-to-last subscript If array[Index] is less than minValue Set minValue to array[Index] Set minIndex to Index End if Increment Index End For Set array[minIndex] to array[Start] Set array[Start] to minValue
677
Program 8-5 // This program uses the selection sort algorithm to sort an // array in ascending order. #include <iostream.h> // Function prototypes void selectionSort(int [], int); void showArray(int [], int); void main(void) { int values[6] = {5, 7, 2, 8, 9, 1}; cout << "The unsorted values are\n"; showArray(values, 6); selectionSort(values, 6); cout << "The sorted values are\n"; }
678
Program continues // Definition of function selectionSort. This function performs an // ascending order selection sort on Array. elems is the number of // elements in the array. void selectionSort(int array[], int elems) { int startScan, minIndex, minValue; for (startScan = 0; startScan < (elems - 1); startScan++) { minIndex = startScan; minValue = array[startScan]; for(int index = startScan + 1; index < elems; index++) { if (array[index] < minValue) minValue = array[index]; minIndex = index; } array[minIndex] = array[startScan]; array[startScan] = minValue;
679
Program continues // Definition of function showArray.
// This function displays the contents of Array. elems is the // number of elements. void showArray(int array[], int elems) { for (int count = 0; count < elems; count++) cout << array[count] << " "; cout << endl; }
680
Program Output The unsorted values are 5 7 2 8 9 1
The sorted values are
681
8.5 Sorting and Searching vectors (Continued from Section 7.13)
The sorting and searching algorithms presented in this chapter may also be used with vectors.
682
Program 8-7 // This program produces a sales report for the Demetris // Leadership Center. This version of the program uses // STL vectors instead of arrays. #include <iostream.h> #include <iomanip.h> #include <vector> // Needed to declare vectors using namespace std; // vectors are in the std namespace // Function prototypes void initVectors(vector<int> &, vector<int> &, vector<float> &); void calcSales(vector<int>, vector<float>, vector<float> &); void showOrder(vector<float>, vector<int>); void dualSort(vector<int> &, vector<float> &); void showTotals(vector<float>, vector<int>); void main(void) { vector<int> id; vector<int> units; vector<float> prices; vector<float> sales;
683
Program 8-7 (continued) // Must provide an initialization routine. initVectors(id, units, prices); // Calculate and sort the sales totals, // and display the results. calcSales(units, prices, sales); dualSort(id, sales); cout.precision(2); cout.setf(ios::fixed | ios::showpoint); showOrder(sales, id); showTotals(sales, units); } //****************************************************************** // Definition of initVectors. Accepts id, units, and prices * // vectors as reference arguments. This function initializes each * // vector to a set of starting values * //******************************************************************
684
Program 8-7 (continued) void initVectors(vector<int> &id, vector<int> &units, vector<float> &prices) { // Initialize the id vector for (int value = 914; value <= 922; value++) id.push_back(value); // Initialize the units vector units.push_back(842); units.push_back(416); units.push_back(127); units.push_back(514); units.push_back(437); units.push_back(269); units.push_back(97); units.push_back(492); units.push_back(212);
685
Program 8-7 (continued) // Initialize the prices vector prices.push_back(12.95); prices.push_back(14.95); prices.push_back(18.95); prices.push_back(16.95); prices.push_back(21.95); prices.push_back(31.95); prices.push_back(14.95); prices.push_back(14.95); prices.push_back(16.95); } //**************************************************************** // Definition of calcSales. Accepts units, prices, and sales * // vectors as arguments. The sales vector is passed into a * // reference parameter. This function calculates each product's * // sales by multiplying its units sold by each unit's price. The * // result is stored in the sales vector * //****************************************************************
686
Program 8-7 (continued) void calcSales(vector<int> units, vector<float> prices, vector<float> &sales) { for (int index = 0; index < units.size(); index++) sales.push_back(units[index] * prices[index]); } //**************************************************************** // Definition of function dualSort. Accepts id and sales vectors * // as reference arguments. This function performs a descending * // order selection sort on the sales vector. The elements of the * // id vector are exchanged identically as those of the sales * // vector * //**************************************************************** void dualSort(vector<int> &id, vector<float> &sales) { int startScan, maxIndex, tempid, elems; float maxValue;
687
Program 8-7 (continued) elems = id.size(); for (startScan = 0; startScan < (elems - 1); startScan++) { maxIndex = startScan; maxValue = sales[startScan]; tempid = id[startScan]; for(int index = startScan + 1; index < elems; index++) { if (sales[index] > maxValue) { maxValue = sales[index]; tempid = id[index]; maxIndex = index; } } sales[maxIndex] = sales[startScan]; id[maxIndex] = id[startScan]; sales[startScan] = maxValue; id[startScan] = tempid; } }
688
Program 8-7 (continued) //***************************************************************** // Definition of showOrder function. Accepts sales and id vectors * // as arguments. The function first displays a heading, then the * // sorted list of product numbers and sales * //***************************************************************** void showOrder(vector<float> sales, vector<int> id) { cout << "Product number\tsales\n"; cout << " \n"; for (int index = 0; index < id.size(); index++) { cout << id[index] << "\t\t$"; cout << setw(8) << sales[index] << endl; } cout << endl; }
689
Program 8-7 (continued) //******************************************************************* // Definition of showTotals function. Accepts sales and id vectors * // as arguments. The function first calculates the total units (of * // all products) sold and the total sales. It then displays these * // amounts * //******************************************************************* void showTotals(vector<float> sales, vector<int> units) { int totalUnits = 0; float totalSales = 0.0; for (int index = 0; index < units.size(); index++) { totalUnits += units[index]; totalSales += sales[index]; } cout << "Total units Sold: " << totalUnits << endl; cout << "Total sales: $" << totalSales << endl; }
690
Program 8-7 (continued) Program Output Product number sales $ $ $ $ $ $ $ $ $ Total units Sold: Total sales: $
691
Chapter 9 – Pointers
692
9.1 Getting the address of a Variable
The address operator (&) returns the memory address of a variable.
693
Figure 9-1 letter number amount 1200 1201 1203
694
Program 9-1 // This program uses the & operator to determine a variable’s // address and the sizeof operator to determine its size. #include <iostream.h> void main(void) { int x = 25; cout << "The address of x is " << &x << endl; cout << "The size of x is " << sizeof(x) << " bytes\n"; cout << "The value in x is " << x << endl; }
695
Program Output The address of x is 0x8f05 The size of x is 2 bytes
The value in x is 25
696
Pointer Variables Pointer variables, which are often just called pointers, are designed to hold memory addresses. With pointer variables you can indirectly manipulate data stored in other variables.
697
Pointers are useful for the following:
Working with memory locations that regular variables don’t give you access to Working with strings and arrays Creating new variables in memory while the program is running Creating arbitrarily-sized lists of values in memory
698
Program 9-2 // This program stores the address of a variable in a pointer. #include <iostream.h> void main(void) { int x = 25; int *ptr; ptr = &x; // Store the address of x in ptr cout << "The value in x is " << x << endl; cout << "The address of x is " << ptr << endl; }
699
Program Output The value in x is 25 The address of x is 0x7e00
700
Figure 9-2 0x7e00 25 ptr x Address of x: 0x7e00
701
Program 9-3 // This program demonstrates the use of the indirection
// operator. #include <iostream.h> void main(void) { int x = 25; int *ptr; ptr = &x; // Store the address of x in ptr cout << "Here is the value in x, printed twice:\n"; cout << x << " " << *ptr << endl; *ptr = 100; cout << "Once again, here is the value in x:\n"; }
702
Program Output Here is the value in x, printed twice: 25 25
25 25 Once again, here is the value in x:
703
Program 9-4 #include <iostream> void main(void) {
int x = 25, y = 50, z = 75; int *ptr; cout << "Here are the values of x, y, and z:\n"; cout << x << " " << y << " " << z << endl; ptr = &x; // Store the address of x in ptr *ptr *= 2; // Multiply value in x by 2 ptr = &y; // Store the address of y in ptr *ptr *= 2; // Multiply value in y by 2 ptr = &z; // Store the address of z in ptr *ptr *= 2; // Multiply value in z by 2 cout << "Once again, here are the values of x, y, and z:\n"; }
704
Program Output Here are the values of x, y, and z: 25 50 75
Once again, here are the values of x, y , and z:
705
9.3 Relationship Between Arrays and Pointers
array names can be used as pointers, and vice-versa.
706
Program 9-5 // This program shows an array name being dereferenced
// with the * operator. #include <iostream.h> void main(void) { short numbers[] = {10, 20, 30, 40, 50}; cout << "The first element of the array is "; cout << *numbers << endl; }
707
Program Output The first element in the array is 10
708
Figure 9-3 numbers numbers[0] numbers[1] numbers[2] numbers[3]
709
Figure 9-4 numbers[0] numbers[1] numbers[2] numbers[3] numbers[4]
710
Program 9-6 // This program processes the contents of an array. Pointer // notation is used. #include <iostream.h> void main(void) { int numbers[5]; cout << "Enter five numbers: "; for (int count = 0; count < 5; count++) cin >> *(numbers + count); cout << "Here are the numbers you entered:\n"; cout << *(numbers + count)<< " "; cout << endl; }
711
Program Output with Example Input
Enter five numbers: [Enter] Here are the numbers you entered:
712
Program 9-7 // This program uses subscript notation with a pointer and
// pointer notation with an array name. #include <iostream.h> void main(void) { float coins[5] = {0.05, 0.1, 0.25, 0.5, 1.0}; float *floatPtr; // Pointer to a float int count; // array index floatPtr = coins; // floatPtr now points to coins array cout.precision(2); cout << "Here are the values in the coins array:\n";
713
Program continues for (count = 0; count < 5; count++)
cout << floatPtr[count] << " "; cout << "\nAnd here they are again:\n"; cout << *(coins + count) << " "; cout << endl; }
714
Program Output Here are the values in the coins array:
And here they are again:
715
Program 9-8 // This program uses the address of each element in the array. #include <iostream.h> #include <iomanip.h> void main(void) { float coins[5] = {0.05, 0.1, 0.25, 0.5, 1.0}; float *floatPtr; // Pointer to a float int count; // array index cout.precision(2); cout << "Here are the values in the coins array:\n";
716
Program continues for (count = 0; count < 5; count++) {
floatPtr = &coins[count]; cout << *floatPtr << " "; } cout << endl;
717
Program Output Here are the values in the coins array:
718
9.4 Pointer Arithmetic Some mathematical operations may be performed on pointers. The ++ and – operators may be used to increment or decrement a pointer variable. An integer may be added to or subtracted from a pointer variable. This may be performed with the +, - +=, or -= operators. A pointer may be subtracted from another pointer.
719
Program 9-9 // This program uses a pointer to display the contents
// of an integer array. #include <iostream.h> void main(void) { int set[8] = {5, 10, 15, 20, 25, 30, 35, 40}; int *nums, index; nums = set; cout << "The numbers in set are:\n"; for (index = 0; index < 8; index++) cout << *nums << " "; nums++; }
720
Program continues cout << "\nThe numbers in set backwards are:\n"; for (index = 0; index < 8; index++) { nums--; cout << *nums << " "; }
721
Program Output The numbers in set are: 5 10 15 20 25 30 35 40
The numbers in set backwards are:
722
9.5 Initializing Pointers
Pointers may be initialized with the address of an existing object.
723
9.6 Comparing Pointers If one address comes before another address in memory, the first address is considered “less than” the second. C++’s relational operators maybe used to compare pointer values.
724
Figure 9-5 An array of five integers (Addresses) 0x5A00 0x5A04 0x5A08
0x5A0C 0x5A0F (Addresses) An array of five integers
725
Program 9-10 // This program uses a pointer to display the contents
// of an integer array. #include <iostream.h> void main(void) { int set[8] = {5, 10, 15, 20, 25, 30, 35, 40}; int *nums = set; // Make nums point to set cout << "The numbers in set are:\n"; cout << *nums << " "; // Display first element while (nums < &set[7]) nums++; cout << *nums << " "; }
726
Program continues cout << "\nThe numbers in set backwards are:\n"; cout << *nums << " "; // Display last element while (nums > set) { nums--; cout << *nums << " "; }
727
Program Output The numbers in set are: 5 10 15 20 25 30 35 40
The numbers in set backwards are:
728
9.7 Pointers as Function Parameters
A pointer can be used as a function parameter. It gives the function access to the original argument, much like a reference parameter does.
729
Program 9-11 // This program uses two functions that accept addresses of // variables as arguments. #include <iostream.h> // Function prototypes void getNumber(int *); void doubleValue(int *); void main(void) { int number; getNumber(&number) // Pass address of number to getNumber doubleValue(&number); // and doubleValue. cout << "That value doubled is " << number << endl; }
730
Program continues // Definition of getNumber. The parameter, Input, is a pointer. // This function asks the user for a number. The value entered // is stored in the variable pointed to by Input. void getNumber(int *input) { cout << "Enter an integer number: "; cin >> *input; } // Definition of doubleValue. The parameter, val, is a pointer. // This function multiplies the variable pointed to by val by // two. void doubleValue(int *val) *val *= 2;
731
Program Output with Example Input
Enter an integer number: 10 [Enter] That value doubled is 20
732
Program 9-12 // This program demonstrates that a pointer may be used as a // parameter to accept the address of an array. Either subscript // or pointer notation may be used. #include <iostream.h> #include <iomanip.h> // Function prototypes void getSales(float *); float totalSales(float *); void main(void) { float sales[4]; getSales(sales); cout.precision(2);
733
Program continues cout.setf(ios::fixed | ios::showpoint);
cout << "The total sales for the year are $"; cout << totalSales(sales) << endl; } // Definition of getSales. This function uses a pointer to accept // the address of an array of four floats. The function asks the // user to enter the sales figures for four quarters, and stores // those figures in the array. (The function uses subscript // notation.) void getSales(float *array) { for (int count = 0; count < 4; count++) cout << "Enter the sales figure for quarter "; cout << (count + 1) << ": "; cin >> array[count];
734
Program continues // Definition of totalSales. This function uses a pointer to // accept the address of an array of four floats. The function // gets the total of the elements in the array and returns that // value. (Pointer notation is used in this function.) float totalSales(float *array) { float sum = 0.0; for (int count = 0; count < 4; count++) sum += *array; array++; } return sum;
735
Program Output with Example Input
Enter the sales figure for quarter 1: [Enter] Enter the sales figure for quarter 2: [Enter] Enter the sales figure for quarter 3: [Enter] Enter the sales figure for quarter 4: [Enter] The total sales for the year are $
736
9.8 Focus on Software Engineering: Dynamic Memory Allocation
Variables may be created and destroyed while a program is running. A pointer than contains the address 0 is called a null pointer. Use the new operator to dynamically allocate memory. Use delete to dynamically deallocate memory.
737
Program 9-13 // This program totals and averages the sales figures for any // number of days. The figures are stored in a dynamically // allocated array. #include <iostream.h> #include <iomanip.h> void main(void) { float *sales, total = 0, average; int numDays; cout << "How many days of sales figures do you wish "; cout << "to process? "; cin >> numDays; sales = new float[numDays]; // Allocate memory
738
Program continues if (sales == NULL) // Test for null pointer {
cout << "Error allocating memory!\n"; return; } // Get the sales figures from the user cout << "Enter the sales figures below.\n"; for (int count = 0; count < numDays; count++) cout << "Day " << (count + 1) << ": "; cin >> sales[count]; // Calculate the total sales for (count = 0; count < numDays; count++) total += sales[count];
739
Program continues // Calculate the average sales per day
average = total / numDays; // Display the results cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "\n\nTotal sales: $" << total << endl; cout << "average sales: $" << average << endl; // Free dynamically allocated memory delete [] sales; }
740
Program Output with Example Input
How many days of sales figures do you wish to process? 5 [Enter] Enter the sales figures below. Day 1: [Enter] Day 2: [Enter] Day 3: [Enter] Day 4: [Enter] Day 5: [Enter] total sales: $ average sales: $813.43
741
9.9 Focus on Software Engineering: Returning Pointers from Functions
Functions can return pointers, but you must be sure the object the pointer references still exists. You should only return a pointer from a function if it is: A pointer to an object that was passed into the function as an argument. A pointer to a dynamically allocated object.
742
Chapter 10 – Characters, Strings, and the string Class
743
10.1 Character Testing The C++ library provides several macros for testing characters. Be sure to include ctype.h header file
744
Table 10-1
745
Program 10-1 // This program demonstrates some of the character testing // functions. #include <iostream.h> #include <ctype.h> void main(void) { char input; cout << "Enter any character: "; cin.get(input); cout << "The character you entered is: " << input << endl; cout << "Its ASCII code is: " << int(input) << endl;
746
Program continues if (isalpha(input))
cout << "That's an alphabetic character.\n"; if (isdigit(input)) cout << "That's a numeric digit.\n"; if (islower(input)) cout << "The letter you entered is lowercase.\n"; if (isupper(input)) cout << "The letter you entered is uppercase.\n"; if (isspace(input)) cout << "That's a whitespace character.\n"; }
747
Program Output With Example input
Enter any character: A [Enter] The character you entered is: A Its ASCII code is: 65 That's an alphabetic character. The letter you entered is uppercase. Program Output With Other Example input Enter any character: 7 [Enter] The character you entered is: 7 Its ASCII code is: 55 That's a numeric digit.
748
Program 10-2 // This program tests a customer number to determine if it is // in the proper format. #include <iostream.h> #include <ctype.h> // Function prototype bool testNum(char []); void main(void) { char customer[8]; cout << "Enter a customer number in the form "; cout << "LLLNNNN\n"; cout << "(LLL = letters and NNNN = numbers): "; cin.getline(customer, 8);
749
Program continues if (testNum(customer))
cout << "That's a valid customer number.\n"; else { cout << "That is not the proper format of the "; cout << "customer number.\nHere is an example:\n"; cout << " ABC1234\n"; } // Definition of function testNum. bool testNum(char custNum[]) // Test the first three characters for alphabetic letters for (int count = 0; count < 3; count++)
750
Program continues if (!isalpha(custNum[count])) return false; }
// Test the last 4 characters for numeric digits for (int count = 3; count < 7; count++) { if (!isdigit(custNum[count])) return true;
751
Program Output With Example input
Enter a customer number in the form LLLNNNN (LLL = letters and NNNN = numbers): RQS4567 [Enter] That's a valid customer number. Program Output With Other Example input (LLL = letters and NNNN = numbers): AX467T9 [Enter] That is not the proper format of the customer number. Here is an example: ABC1234
752
10.2 Character Case Conversion
The C++ library offers functions for converting a character to upper or lower case. Be sure to include ctype.h header file
753
Table 10-2
754
Program 10-3 // This program calculates the area of a circle. It asks the // user if he or she wishes to continue. A loop that // demonstrates the toupper function repeats until the user // enters 'y', 'Y', 'n', or 'N'. #include <iostream.h> #include <ctype.h> void main(void) { const float pi = ; float radius; char go; cout << "This program calculates the area of a circle.\n"; cout.precision(2); cout.setf(ios::fixed);
755
Program continues do { cout << "Enter the circle's radius: ";
cin >> radius; cout << "The area is " << (pi * radius * radius); cout << endl; cout << "Calculate another? (Y or N) "; cin >> go; } while (toupper(go) != 'Y' && toupper(go) != 'N'); } while (toupper(go) == 'Y'); }
756
Program Output With Example input
This program calculates the area of a circle. Enter the circle's radius: 10 [Enter] The area is Calculate another? (Y or N) b Enter] Calculate another? (Y or N) y [Enter] Enter the circle's radius: 1 [Enter] The area is 3.14 Calculate another? (Y or N) n [Enter]
757
10.3 Review of the Internal Storage of C-strings
A C-string is a sequence of characters stored in consecutive memory locations, terminated by a null character. Figure 10-1
758
Program 10-4 // This program contains string constants
#include <iostream.h> void main(void) { char again; do cout << "C++ programming is great fun!" << endl; cout << "Do you want to see the message again? "; cin >> again; } while (again == 'Y' || again == 'y'); }
759
Program 10-5 // This program cycles through a character array, displaying // each element until a null terminator is encountered. #include <iostream.h> void main(void) { char line[80]; int count = 0; cout << "Enter a sentence of no more than 79 characters:\n"; cin.getline(line, 80); cout << "The sentence you entered is:\n"; while (line[count] != '\0') cout << line[count]; count++; }
760
Program Output with Example input
Enter a sentence of no more than 79 characters: C++ is challenging but fun! [Enter] The sentence you entered is: C++ is challenging but fun!
761
10.4 Library Functions for Working with C-strings
The C++ library has numerous functions for handling C-strings These functions perform various tests and manipulations. Functions discussed in this section require the inclusion of string.h header file
762
Figure 10-2
763
Table 10-3
764
Program 10-6 // This program uses the strstr function to search an array // of strings for a name. #include <iostream.h> #include <string.h> // For strstr void main(void) { char prods[5][27] = {"TV inch Television", "CD257 CD Player", "TA677 Answering Machine", "CS109 Car Stereo", "PC955 Personal Computer"}; char lookUp[27], *strPtr = NULL; int index;
765
Program continues cout << "\tProduct Database\n\n";
cout << "Enter a product number to search for: "; cin.getline(lookUp, 27); for (index = 0; index < 5; index++) { strPtr = strstr(prods[index], lookUp); if (strPtr != NULL) break; } if (strPtr == NULL) cout << "No matching product was found.\n"; else cout << prods[index] << endl;
766
Program Output With Example input
Product Database Enter a product to search for: CD257 [Enter] CD257 CD Player Program Output With Example input Enter a product to search for: CS [Enter] CS109 Car Stereo Program Output With Other Example input Enter a product to search for: AB [Enter] No matching product was found.
767
10.5 String/Numeric Conversion Functions
The C++ library provides functions for converting a C-string representation of a number to a numeric data type, and vice-versa. The functions in this section require the stdlib.h file to be included.
768
Table 10-4
769
Table 10-4 Continued Function Description
itoa Converts an integer to a C-string. The first argument, value, is the integer. The result will be stored at the location pointed to by the second argument, string. The third argument, base, is an integer. It specifies the numbering system that the converted integer should be expressed in. ( 8 = octal, 10 = decimal, 16 = hexadecimal, etc. ) Example Usage: itoa(value, string, base)
770
Program 10-7 // This program demonstrates the strcmp and atoi functions. #include <iostream.h> #include <string.h> // For strcmp #include <stdlib.h> // For atoi void main(void) { char input[20]; int total = 0, count = 0; float average; cout << "This program will average a series of numbers.\n"; cout << "Enter the first number or Q to quit: "; cin.getline(input, 20);
771
Program continues while ((strcmp(input, "Q") != 0)&&(strcmp(input, "q") != 0)) { total += atoi(input); // Keep a running total count++; // Keep track of how many numbers entered cout << "Enter the next number or Q to quit: "; cin.getline(input, 20); } if (count != 0) average = total / count; cout << "Average: " << average << endl;
772
Program Output With Example input
This program will average a series of numbers. Enter the first number or Q to quit: 74 [Enter] Enter the next number or Q to quit: 98 [Enter] Enter the next number or Q to quit: 23 [Enter] Enter the next number or Q to quit: 54 [Enter] Enter the next number or Q to quit: Q [Enter] Average: 62
773
10.6 Focus on Software Engineering: Writing Your Own C-string-Handling Functions
You can design your own specialized functions for manipulating C-strings.
774
Program 10-8 #include <iostream.h>
// This program uses a function to copy a C-string into an array. #include <iostream.h> void stringCopy(char [], char []); // Function prototype void main(void) { char first[30], second[30]; cout << "Enter a string with no more than 29 characters:\n"; cin.getline(first, 30); stringCopy(first, second); cout << "The string you entered is:\n" << second << endl; }
775
Program continues // Definition of the stringCopy function.
// This function accepts two character arrays as // arguments. The function assumes the two arrays // contain C-strings. The contents of the second array is // copied to the first array. void stringCopy(char string1[], char string2[]) { int index = 0; while (string1[index] != '\0') string2[index] = string1[index]; index++; } string2[index] = '\0';
776
Program Output With Example input
Enter a string with no more than 29 characters: Thank goodness it’s Friday! [Enter] The string you entered is: Thank goodness it's Friday!
777
Program 10-9 // This program uses the function nameSlice to "cut" the last // name off of a string that contains the user's first and // last names. #include <iostream.h> void nameSlice(char []); // Function prototype void main(void) { char name[41]; cout << "Enter your first and last names, separated "; cout << "by a space:\n"; cin.getline(name, 41); nameSlice(name); cout << "Your first name is: " << name << endl; }
778
Program continues // Definition of function nameSlice. This function accepts a // character array as its argument. It scans the array looking // for a space. When it finds one, it replaces it with a null // terminator. void nameSlice(char userName[]) { int count = 0; while (userName[count] != ' ' && userName[count] != '\0') count++; if (userName[count] == ' ') userName[count] = '\0'; }
779
Program Output With Example input
Enter your first and last names, separated by a space: Jimmy Jones [Enter] Your first name is: Jimmy
780
Figure 10-3
781
Figure 10-4
782
Using Pointers to pass C-string arguments
Very useful Can assume string exists from address pointed to by the pointer up to the ‘\0’
783
Program 10-10 // This program demonstrates a function, countChars, that counts // the number of times a specific character appears in a string. #include <iostream.h> // Function prototype int countChars(char *, char); void main(void) { char userString[51], letter; cout << "Enter a string (up to 50 characters): "; cin.getline(userString, 51); cout << "Enter a character and I will tell you how many\n"; cout << "times it appears in the string: "; cin >> letter; cout << letter << " appears "; cout << countChars(userString, letter) << " times.\n"; }
784
Program continues // Definition of countChars. The parameter strPtr is a pointer // that points to a string. The parameter ch is a character that // the function searches for in the string. The function returns // the number of times the character appears in the string. int countChars(char *strPtr, char ch) { int times = 0; while (*strPtr != '\0') if (*strPtr == ch) times++; strPtr++; } return times;
785
Program Output With Example input
Enter a string (up to 50 characters):Starting Out With C++ [Enter] Enter a character and I will tell you how many times it appears in the string: t [Enter] t appears 4 times.
786
The C++ string Class Offers “ease of programming” advantages over the use of C-strings Need to #include the string header file (Notice there is no .h extension.) Use the following statement after the #include statements: using namespace std;
787
Program 10-12 Program output
// This program demonstrates the C++ string class. #include <iostream> #include <string> // Required for the string class using namespace std; void main(void) { string movieTitle; string name("William Smith"); movieTitle = "Wheels of Fury"; cout << "My favorite movie is " << movieTitle << endl; } Program output My favorite movie is Wheels of Fury
788
A note about the iostream header file
The preceding program uses the iostream header, not iostream.h. With some compilers, you must include the iostream header instead of iostream.h when using cout and cin with string objects.
789
Program 10-13: Using cin with a string object
// This program demonstrates how cin can read a string into // a string class object. #include <iostream> #include <string> using namespace std; void main(void) { string name; cout << "What is your name? " << endl; cin >> name; cout << "Good morning " << name << endl; }
790
Program Output With Example Input
What is your name? Peggy Good morning Peggy
791
Reading a line of input into a string class object
Use the getline function to read a line of input, with spaces, into a string object. Example code: string name; cout << “What is your name? “; getline(cin, name);
792
Comparing and Sorting string Objects
You may use the relational operators to compare string objects: < > <= >= == !=
793
Program 10-14 // This program uses the == operator to compare the string entered // by the user with the valid stereo part numbers. #include <iostream> #include <string> using namespace std; void main(void) { const float aprice = 249.0, bprice = 299.0; string partNum; cout << "The stereo part numbers are:\n"; cout << "\tBoom Box, part number S147-29A\n"; cout << "\tShelf Model, part number S147-29B\n"; cout << "Enter the part number of the stereo you\n"; cout << "wish to purchase: "; cin >> partNum; cout.setf(ios::fixed | ios::showpoint); cout.precision(2);
794
Program 10-14 (continued) Program Output
if (partNum == "S147-29A") cout << "The price is $" << aprice << endl; else if (partNum == "S147-29B") cout << "The price is $" << bprice << endl; else cout << partNum << " is not a valid part number.\n"; } Program Output The stereo part numbers are: Boom Box, part number S147-29A Shelf Model, part number S147-29B Enter the part number of the stereo you wish to purchase: S147-29A [Enter] The price is $249.00
795
Other Ways to Declare string Objects
Declaration Example Description string address Declares an empty string object named address. string name(“Bill Smith”); name is a string object initialized with “Bill Smith” string person1(person2); person1 is initialized with a copy of person2. person2 may be either a string object or a char array. See Table 10-8 (page 589) for more examples.
796
Table 10-10 Other Supported Operators
>> Extracts characters from a stream and inserts them into a string. Characters are copied until a whitespace or the end of the string is encountered. << Inserts a string into a stream. = Assigns the string on the right to the string object on the left. += Appends a copy of the string on the right to the string object on the left. + Returns a string that is the concatenation of the two string operands. [] Implements array-subscript notation, as in name[x]. A reference to the character in the x position is returned.
797
Program 10-17 // This program demonstrates the C++ string class.
#include <iostream> #include <string> using namespace std; void main(void) { string str1, str2, str3; str1 = "ABC"; str2 = "DEF"; str3 = str1 + str2; cout << str1 << endl; cout << str2 << endl; cout << str3 << endl; str3 += "GHI"; }
798
Program Output ABC DEF ABCDEF ABCDEFGHI
799
string class member functions
Many member functions exist. See Table (pages )
800
Chapter 11 – Structured Data
Abstract data types (ADTs) are data types created by the programmer. ADTs have their own range (or domain) of data and their own set of operations that may be performed on them.
801
Abstraction An abstraction is a general model of something.
802
Data Types C++ has several primitive data types: Table 11-1
803
Abstract Data Types A data type created by the programmer
The programmer decides what values are acceptable for the data type The programmer decides what operations may be performed on the data type
804
11.2 Focus on Software Engineering: Combining Data into Structures
C++ allows you to group several variables together into a single item known as a structure.
805
Table 11-2
806
Table 11-2 As a Structure: struct PayRoll { int EmpNumber;
char Name[25]; float Hours; float PayRate; float GrossPay; };
807
Figure 11-1 Structure Variable Name Members deptHead empNumber name
hours payRate grossPay deptHead Members
808
Figure 11-2 deptHead foreman empNumber name hours payRate grossPay
associate empNumber name hours payRate grossPay
809
Two steps to implementing structures:
Create the structure declaration. This establishes the tag (or name) of the structure and a list of items that are members. Declare variables (or instances) of the structure and use them in the program to hold data.
810
11.3 Accessing Structure Members
The dot operator (.) allows you to access structure members in a program
811
Program 11-1 // This program demonstrates the use of structures.
#include <iostream.h> struct PayRoll { int empNumber; // Employee number char name[25]; // Employee's name float hours; // Hours worked float payRate; // Hourly Payrate float grossPay; // Gross Pay };
812
Program continues void main(void) {
PayRoll employee; // Employee is a PayRoll structure cout << "Enter the employee's number: "; cin >> employee.empNumber; cout << "Enter the employee's name: "; cin.ignore(); // To skip the remaining '\n' character cin.getline(employee.name, 25); cout << "How many hours did the employee work? "; cin >> employee.hours; cout << "What is the employee's hourly payrate? "; cin >> employee.payRate; employee.grossPay = employee.hours * employee.payRate; cout << "Here is the employee's payroll data:\n"; cout << "Name: " << employee.name << endl;
813
Program continues cout << "Number: " << employee.empNumber << endl; cout << "Hours worked: " << employee.hours << endl; cout << "Hourly Payrate: " << employee.payRate << endl; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Gross Pay: $" << employee.grossPay << endl; }
814
Program Output with Example Input
Enter the employee's number: 489 [Enter] Enter the employee's name: Jill Smith [Enter] How many hours did the employee work? 40 [Enter] What is the employee's hourly payrate? 20 [Enter] Here is the employee's payroll data: Name: Jill Smith Number: 489 Hours worked: 40 Hourly Payrate: 20 Gross Pay: $800.00
815
Displaying a Structure
The contents of a structure variable cannot be displayed by passing he entire variable to cout. For example, assuming employee is a PayRoll structure variable, the following statement will not work: cout << employee << endl; //won’t work!
816
Program 11-2 // This program uses a structure to hold geometric data about a circle. #include <iostream.h> #include <iomanip.h> #include <math.h> // For the pow function struct Circle { float radius; float diameter; float area; }; const float pi = ;
817
Program continues void main(void) { Circle c;
cout << "Enter the diameter of a circle: "; cin >> c.Diameter; c.Radius = C.Diameter / 2; c.Area = pi * pow(c.Radius, 2.0); cout << "The radius and area of the circle are:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Radius: " << c.radius << endl; cout << "Area: " << c.area << endl; }
818
Program Output with Example Input
Enter the diameter of a circle: 10 [Enter] The radius and area of the circle are: Radius: 5 Area: 78.54
819
Strings as Structure Members
When a character array is a structure member, use the same sting manipulation techniques with it as you would with any other character array.
820
Program 11-3 // This program uses a structure to hold someone's first,
// middle, and last name. #include <iostream.h> #include <string.h> struct Name { char first[15]; char middle[15]; char last[15]; char full[45]; };
821
Program continues void main(void) { Name person;
cout << "Enter your first name: "; cin >> person.first; cout << "Enter your middle name: "; cin >> person.middle; cout << "Enter your last name: "; cin >> person.last; strcpy(person.full, person.first); strcat(person.full, " "); strcat(person.full, person.middle); strcat(person.full, person.last); cout << "\nYour full name is " << person.full << endl; }
822
Program Output with Example Input
Enter your first name: Josephine [Enter] Enter your middle name: Yvonne [Enter] Enter your last name: Smith [Enter] Your full name is Josephine Yvonne Smith
823
11.4 Initializing a Structure
The members of a structure variable may be initialized with starting values when the structure variable is declared. struct GeoInfo { char cityName[30]; char state[3]; long population; int distance; }; GeoInfo location = {“Ashville”, “NC”, 50000, 28};
824
11.5 Arrays of Structures Arrays of structures can simplify some programming tasks. struct BookInfo { char title[50]; char author[30]; char publisher[25]; float price; }; BookInfo bookList[20];
825
Program 11-5 // This program stores, in an array of structures,
// the hours worked by 5 employees, and their hourly // pay rates. (This is a modification of Program 7-11.) #include <iostream.h> struct PayInfo { int hours; // Hours Worked float payRate; // Hourly Pay Rate };
826
Program continues void main(void) {
PayInfo workers[5]; // Array of 5 structures cout << "Enter the hours worked by 5 employees and their\n"; cout << "hourly rates.\n"; for (int index = 0; index < 5; index++) cout << "Hours worked by employee #" << (Index + 1); cout << ": "; cin >> workers[index].hours; cout << "Hourly pay rate for employee #"; cout << (index + 1) << ": "; cin >> workers[index].payRate; }
827
Program continues cout << "Here is the gross pay for each employee:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); for (index = 0; index < 5; index++) { float gross; gross = workers[index].hours * workers[index].payRate; cout << "Employee #" << (index + 1); cout << ": $" << gross << endl; }
828
Program Output with Example Input
Enter the hours worked by 5 employees and their hourly rates. Hours worked by employee #1: 10 [Enter] Hourly pay rate for employee #1: 9.75 [Enter] Hours worked by employee #2: 15 [Enter] Hourly pay rate for employee #2: 8.62 [Enter] Hours worked by employee #3: 20 [Enter] Hourly pay rate for employee #3: [Enter] Hours worked by employee #4: 40 [Enter] Hourly pay rate for employee #4: [Enter] Hours worked by employee #5: 40 [Enter] Hourly pay rate for employee #5: [Enter] Here is the gross pay for each employee: Employee #1: $97.50 Employee #2: $129.30 Employee #3: $210.00 Employee #4: $750.00 Employee #5: $626.00
829
Initializing a Structure Array
PayInfo workers[5] = {{ 10, 9.75}, {15, 8.62}, {20, 10.50}, {40, 18.75}, {40, 15.65}};
830
11.6 Focus on Software Engineering: Nested Structures
It’s possible for a structure variable to be a member of another structure variable. struct Costs { float wholesale; float retail; }; struct Item char partNum[10] char description[25]; Costs pricing;
831
Program 11-6 // This program shows a structure with two nested structure members. #include <iostream.h> struct Date { int month; int day; int year; }; struct Place char address[50]; char city[20]; char state[15]; char zip[11];
832
Program continues struct EmpInfo { char name[50]; int empNumber;
Date birthDate; Place residence; }; void main(void) EmpInfo manager; // Ask for the manager's name and employee number cout << "Enter the manager's name: "; cin.getline(manager.name, 50); cout << "Enter the manager's employee number: "; cin >> manager.empNumber;
833
Program continues // Get the manager's birth date
cout << "Now enter the manager's date-of-birth.\n"; cout << "Month (up to 2 digits): "; cin >> manager.birthDate.month; cout << "Day (up to 2 digits): "; cin >> manager.birthDate.day; cout << "Year (2 digits): "; cin >> manager.birthDate.year; cin.get(); // Eat the remaining newline character // Get the manager's residence information cout << "Enter the manager's street address: "; cin.getline(manager.residence.address, 50); cout << "City: "; cin.getline(manager.residence.city, 20); cout << "State: "; cin.getline(manager.residence.state, 15);
834
Program continues cout << "Zip Code: ";
cin.getline(manager.residence.zip, 11); // Display the information just entered cout << "\nHere is the manager's information:\n"; cout << manager.name << endl; cout << "Employee number " << manager.empNumber << endl; cout << "Date of Birth: "; cout << manager.birthDate.month << "-"; cout << manager.birthDate.day << "-"; cout << manager.birthDate.year << endl; cout << "Place of residence:\n"; cout << manager.residence.address << endl; cout << manager.residence.city << ", "; cout << manager.residence.state << " "; cout << manager.residence.zip << endl; }
835
Program Output with Example Input:
Enter the manager's name: John Smith [Enter] Enter the manager's employee number: 789 [Enter] Now enter the manager's date-of-birth Month (up to 2 digits): 10 [Enter] Day (up to 2 digits): 14 [Enter] Year (2 digits): 65 [Enter] Enter the manager's street address: 190 Disk Drive [Enter] City: Redmond [Enter] State: WA [Enter] Zip Code: [Enter] Here is the manager's information: John Smith Employee number 789 Date of birth: Place of residence: 190 Disk Drive Redmond, WA
836
11.7 Structures as Function Arguments
Structure variables may be passed as arguments to functions.
837
Figure 11-3 showRect(box);
void showRect(Rectangle r) { cout << r.length << endl; cout << r.width << endl; cout << r.area << endl; }
838
Program 11-7 // This program demonstrates a function that accepts
// a structure variable as its argument. #include <iostream.h> struct InvItem { int partNum; // Part number char description[50]; // Item description int onHand; // Units on hand float price; // Unit price }; void ShowItem(InvItem); // Function prototype
839
Program continues void main(void) {
InvItem Part = {171, "Industrial Widget", 25, 150.0}; ShowItem(part); } // Definition of function ShowItem. This function accepts // an argument of the InvItem structure type. The contents // of the structure is displayed. void ShowItem(InvItem piece) cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Part Number: " << piece.partNum << endl; cout << "Description: " << piece.description << endl; cout << "Units On Hand: " << piece.onHand << endl; cout << "Price: $" << piece.price << endl;
840
Program Output Part Number: 171 Description: Industrial Widget
Units On Hand: 25 Price: $150.00
841
Program 11-8 // This program has a function that uses a structure reference variable // as its parameter. #include <iostream.h> struct InvItem { int partNum; // Part number char description[50]; // Item description int onHand; // Units on hand float price; // Unit price }; // Function Prototypes void GetItem(InvItem&); void ShowItem(InvItem);
842
Program continues void main(void) { InvItem part; GetItem(part);
ShowItem(part); } // Definition of function GetItem. This function uses a structure reference // variable as its parameter. It asks the user for information to store in the // structure. void GetItem(InvItem &piece) cout << "Enter the part number: "; cin >> piece.partNum; cout << "Enter the part description: "; cin.get(); // Eat the remaining newline cin.getline(piece.description, 50);
843
Program continues cout << "Enter the quantity on hand: ";
cin >> piece.onHand; cout << "Enter the unit price: "; cin >> piece.price; } // Definition of function ShowItem. This function accepts an argument of // the InvItem structure type. The contents of the structure is displayed. void ShowItem(InvItem piece) { cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Part Number: " << piece.partNum << endl; cout << "Description: " << piece.description << endl; cout << "Units On Hand: " << piece.onHand << endl; cout << "Price: $" << piece.price << endl;
844
Program Output Enter the part number: 800 [Enter]
Enter the part description: Screwdriver [Enter] Enter the quantity on hand: 135 [Enter] Enter the unit price: 1.25 [Enter] Part Number: 800 Description: Screwdriver Units On Hand: 135 Price: $1.25
845
Constant Reference Parameters
Sometimes structures can be quite large. Therefore, passing by value can decrease a program’s performance. But passing by reference can cause problems. Instead, pass by constant reference: void ShowItem(const InvItem &piece) { cout.setf(ios::precision(2)|ios::fixed|ios::showpoint); cout << “Part Number: “ << piece.partNum << endl; cout << “Price: $” << piece.price << endl; }
846
11.8 Returning a Structure from a Function
A function may return a structure. struct Circle { float radius, diameter, area; }; Circle getData(void) Circle temp; temp.radius = 10.0; temp.diameter = 20.0; temp.area = ; return temp; }
847
Program 11-9 // This program uses a function to return a structure. This // is a modification of Program 11-2. #include <iostream.h> #include <iomanip.h> #include <math.h> // For the pow function // Circle structure declaration struct Circle { float radius; float diameter; float area; };
848
Program continues // Function prototype Circle getInfo(void);
// Constant definition for Pi const float pi = ; void main(void) { Circle c; c = getInfo(); c.area = pi * pow(c.radius, 2.0); cout << "The radius and area of the circle are:\n"; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Radius: " << c.radius << endl; cout << "Area: " << c.area << endl; }
849
Program continues // Definition of function GetInfo. This function uses a // local variable, Round, which is a Circle structure. // The user enters the diameter of the circle, which is // stored in Round.Diameter. The function then calculates // the radius, which is stored in Round.Radius. Round is then // returned from the function. Circle getInfo(void) { Circle Round; cout << "Enter the diameter of a circle: "; cin >> Round.Diameter; Round.Radius = Round.Diameter / 2; return Round; }
850
Program Output with Example Input
Enter the diameter of a circle: 10 [Enter] The radius and area of the circle are: Radius: 5.00 Area: 78.54
851
11.9 Pointers to Structures
You may take the address of a structure variable and create variables that are pointers to structures. Circle *cirPtr; CirPtr = &piePlate; *cirPtr.Radius = 10; //incorrect way to access Radius because the dot operator has higher precedence (*cirPtr).Radius = 10; //correct access to Radius cirPtr->Radius = 10; //structure pointer operator, easier notation for dereferencing structure pointers
852
Program 11-10 // This program uses a structure pointer to dynamically allocate a structure // variable in memory. It is a modification of Program 11-1. #include <iostream.h> #include <iomanip.h> #include <stdlib.h> struct PayRoll { int empNumber; // Employee number char name[25]; // Employee's name float hours; // Hours worked float payRate; // Hourly Payrate float grossPay; // Gross Pay };
853
Program continues void main(void) {
PayRoll *employee; // Employee is a pointer to a // PayRoll structure employee = new PayRoll; // Dynamically allocate a struct if (employee == NULL) // Test the allocated memory cout << "Memory allocation error!\n"; exit(EXIT_FAILURE); } cout << "Enter the employee's number: "; cin >> employee->empNumber; cout << "Enter the employee's name: "; cin.ignore(); // To skip the remaining '\n' character cin.getline(employee->name, 25);
854
Program continues cout << "How many hours did the employee work? "; cin >> employee->hours; cout << "What is the employee's hourly payrate? "; cin >> employee->payRate; employee->grossPay = employee->hours * employee->payRate; cout << "Here is the employee's payroll data:\n"; cout << "Name: " << employee->name << endl; cout << "Number: " << employee->empNumber << endl; cout << "Hours worked: " << employee->hours << endl; cout << "Hourly Payrate: " << employee->payRate << endl; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Gross Pay: $" << employee->grossPay << endl; delete employee; // Free the allocated memory }
855
Program Output with Example Input
Enter the employee's number: 489 [Enter] Enter the employee's name: Jill Smith [Enter] How many hours did the employee work? 40 [Enter] What is the employee's hourly payrate? 20 [Enter] Here is the employee's payroll data: Name: Jill Smith Number: 489 Hours worked: 40 Hourly Payrate: 20 Gross Pay: $800.00
856
Program 11-11 // This program demonstrates a function that uses a
// pointer to a structure variable as a parameter. #include <iostream.h> #include <iomanip.h> struct Student { char name[35]; // Student's name int idNum; // Student ID number int crdHrs; // Credit hours enrolled float gpa; // Current GPA }; void getData(Student *); // Function prototype
857
Program continues void main(void) { Student freshman;
cout << "Enter the following student data:\n"; getData(&freshman); cout << "\nHere is the student data you entered:\n"; cout.precision(2); // Now display the data stored in Freshman cout << "Name: " << freshman.name << endl; cout << "ID Number: " << freshman.idNum << endl; cout << "Credit Hours: " << freshman.crdHrs << endl; cout << "GPA: " << freshman.gpa << endl; }
858
Program continues // Definition of function GetData. Uses a pointer to a // Student structure variable. The user enters student // information, which is stored in the variable. void getData(Student *s) { cout << "Student Name: "; cin.getline(s->name, 35); cout << "Student ID Number: "; cin.ignore(); // Ignore the leftover newline cin >> s->idNum; cout << "Credit Hours Enrolled: "; cin >> s->crdHrs; cout << "Current GPA: "; cin >> s->gpa; }
859
Program Output with Example Input
Enter the following student data: Student Name: Frank Smith [Enter] Student ID Number: 4876 [Enter] Credit Hours Enrolled: 12 [Enter] Current GPA: 3.45 [Enter] Here is the student data you entered: Name: Frank Smith ID Number: 4876 Credit Hours: 12 GPA: 3.45
860
11. 10 Focus on Software Engineering: When to Use
Focus on Software Engineering: When to Use ., When to Use ->, and When to Use *
862
1st two bytes are used by hours, a short
11.11 Unions A union is like a structure, except all the members occupy the same memory area. Figure 11-4 employee1: a PaySource union variable 1st two bytes are used by hours, a short All four bytes are used by sales, a float
863
Program 11-12 // This program demonstrates a union.
#include <iostream.h> #include <iomanip.h> #include <ctype.h> // For toupper union PaySource { short hours; float sales; }; void main(void) PaySource employee1; char payType; float payRate, grossPay;
864
Program continues cout.precision(2); cout.setf(ios::showpoint);
cout << "This program calculates either hourly wages or\n"; cout << "sales commission.\n"; cout << "Enter H for hourly wages or C for commission: "; cin >> payType; if (toupper(payType) == 'H') { cout << "What is the hourly pay rate? "; cin >> payRate; cout << "How many hours were worked? "; cin >> employee1.hours; GrossPay = employee1.hours * payRate; cout << "Gross pay: $" << grossPay << endl; }
865
Program continues else if (toupper(payType) == 'C') {
cout << "What are the total sales for this employee? "; cin >> employee1.sales; grossPay = employee1.sales * 0.10; cout << "Gross pay: $" << grossPay << endl; } else cout << payType << " is not a valid selection.\n";
866
Program Output with Example Input
This program calculates either hourly wages or sales commission. Enter H for hourly wages or C for commission: C [Enter] What are the total sales for this employee? 5000 [Enter] Gross pay: $500.00
867
Anonymous Unions The members of an anonymous union have names, but the union itself has no name. Union { member declarations; . . . };
868
Program 11-13 // This program demonstrates an anonymous union.
#include <iostream.h> #include <iomanip.h> #include <ctype.h> // For toupper void main(void) { union // Anonymous union short hours; float sales; }; char payType; float payRate, grossPay;
869
Program continues cout.precision(2);
cout.setf(ios::fixed | ios::showpoint); cout << "This program calculates either hourly wages or\n"; cout << "sales commission.\n"; cout << "Enter H for hourly wages or C for commission: "; cin >> payType; if (toupper(payType) == 'H') { cout << "What is the hourly pay rate? "; cin >> payRate; cout << "How many hours were worked? "; cin >> hours; // Anonymous union member grossPay = hours * payRate; cout << "Gross pay: $" << grossPay << endl; }
870
Program continues else if (toupper(payType) == 'C') {
cout << "What are the total sales for this employee? "; cin >> sales; // Anonymous union member grossPay = sales * 0.10; cout << "Gross pay: $" << grossPay << endl; } else cout << payType << " is not a valid selection.\n";
871
Program Output with Example Input
This program calcualtes either hourly wages or sales commission. Enter H for hourly wages or C for commission: C [Enter] What are the total sales for the employee? [Enter] Gross pay: $
872
Chapter 12 – File Operations
873
12.1 What is a File? A file is a collection on information, usually stored on a computer’s disk. Information can be saved to files and then later reused.
874
12.2 File Names All files are assigned a name that is used for identification purposes by the operating system and the user.
875
Table 12-1
876
12.3 Focus on Software Engineering: The Process of Using a File
Using a file in a program is a simple three-step process The file must be opened. If the file does not yet exits, opening it means creating it. Information is then saved to the file, read from the file, or both. When the program is finished using the file, the file must be closed.
877
Figure 12-1
878
Figure 12-2
879
12.4 Setting Up a Program for File Input/Output
Before file I/O can be performed, a C++ program must be set up properly. File access requires the inclusion of fstream.h
880
12.5 Opening a File Before data can be written to or read from a file, the file must be opened. ifstream inputFile; inputFile.open(“customer.dat”);
881
Program 12-1 // This program demonstrates the declaration of an fstream // object and the opening of a file. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; // Declare file stream object char fileName[81]; cout << "Enter the name of a file you wish to open\n"; cout << "or create: "; cin.getline(fileName, 81); dataFile.open(fileName, ios::out); cout << "The file " << fileName << " was opened.\n"; }
882
Program Output with Example Input
Enter the name of a file you wish to open or create: mystuff.dat [Enter] The file mystuff.dat was opened.
883
Table 12-3
884
Table 12-4
885
Table 12-4 continued
886
Opening a File at Declaration
fstream dataFile(“names.dat”, ios::in | ios::out);
887
Program 12-2 // This program demonstrates the opening of a file at the
// time the file stream object is declared. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile("names.dat", ios::in | ios::out); cout << "The file names.dat was opened.\n"; }
888
Program Output with Example Input
The file names.dat was opened.
889
Testing for Open Errors
dataFile.open(“cust.dat”, ios::in); if (!dataFile) { cout << “Error opening file.\n”; }
890
Another way to Test for Open Errors
dataFile.open(“cust.dat”, ios::in); if (dataFile.fail()) { cout << “Error opening file.\n”; }
891
12.6 Closing a File A file should be closed when a program is finished using it.
892
Program 12-3 // This program demonstrates the close function.
#include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; dataFile.open("testfile.txt", ios::out); if (!dataFile) cout << "File open error!" << endl; return; } cout << "File was created successfully.\n"; cout << "Now closing the file.\n"; dataFile.close();
893
Program Output File was created successfully. Now closing the file.
894
12.7 Using << to Write Information to a File
The stream insertion operator (<<) may be used to write information to a file. outputFile << “I love C++ programming !”
895
Program 12-4 // This program uses the << operator to write information to a file. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; char line[81]; dataFile.open("demofile.txt", ios::out); if (!dataFile) cout << "File open error!" << endl; return; }
896
Program continues cout << "File opened successfully.\n";
cout << "Now writing information to the file.\n"; dataFile << "Jones\n"; dataFile << "Smith\n"; dataFile << "Willis\n"; dataFile << "Davis\n"; dataFile.close(); cout << "Done.\n"; }
897
Output to File demofile.txt Jones Smith Willis Davis
Program Screen Output File opened successfully. Now writing information to the file. Done. Output to File demofile.txt Jones Smith Willis Davis
898
Figure 12-3
899
Program 12-5 // This program writes information to a file, closes the file, // then reopens it and appends more information. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; dataFile.open("demofile.txt", ios::out); dataFile << "Jones\n"; dataFile << "Smith\n"; dataFile.close(); dataFile.open("demofile.txt", ios::app); dataFile << "Willis\n"; dataFile << "Davis\n"; }
900
Output to File demofile.txt
Jones Smith Willis Davis
901
12.8 File Output Formatting
File output may be formatted the same way as screen output.
902
Program 12-6 // This program uses the precision member function of a
// file stream object to format file output. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; float num = ; dataFile.open("numfile.txt", ios::out); if (!dataFile) cout << "File open error!" << endl; return; }
903
Program continues dataFile << num << endl;
dataFile.precision(5); dataFile.precision(4); dataFile.precision(3); }
904
Contents of File numfile.txt
123.46 123.5 124
905
Program 12-7 #include <iostream.h> #include <fstream.h>
#include <iomanip.h> void main(void) { fstream outFile("table.txt", ios::out); int nums[3][3] = { 2897, 5, 837, 34, 7, 1623, 390, 3456, 12 }; // Write the three rows of numbers for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) outFile << setw(4) << nums[row][col] << " "; } outFile << endl; outFile.close();
906
Contents of File TABLE.TXT
907
Figure 12-6
908
12.9 Using >> to Read Information from a File
The stream extraction operator (>>) may be used to read information from a file.
909
Program 12-8 #include <iostream.h>
// This program uses the >> operator to read information from a file. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; char name[81]; dataFile.open("demofile.txt", ios::in); if (!dataFile) cout << "File open error!" << endl; return; } cout << "File opened successfully.\n"; cout << "Now reading information from the file.\n\n";
910
Program continues for (int count = 0; count < 4; count++) {
dataFile >> name; cout << name << endl; } dataFile.close(); cout << "\nDone.\n";
911
Program Screen Output File opened successfully.
Now reading information from the file. Jones Smith Willis Davis Done.
912
12.10 Detecting the End of a File
The eof() member function reports when the end of a file has been encountered. if (inFile.eof()) inFile.close();
913
Program 12-9 // This program uses the file stream object's eof() member // function to detect the end of the file. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile; char name[81]; dataFile.open("demofile.txt", ios::in); if (!dataFile) cout << "File open error!" << endl; return; } cout << "File opened successfully.\n"; cout << "Now reading information from the file.\n\n";
914
Program continues dataFile >> name; // Read first name from the file while (!dataFile.eof()) { cout << name << endl; dataFile >> name; } dataFile.close(); cout << "\nDone.\n";
915
Program Screen Output File opened successfully.
Now reading information from the file. Jones Smith Willis Davis Done.
916
Note on eof() In C++, “end of file” doesn’t mean the program is at the last piece of information in the file, but beyond it. The eof() function returns true when there is no more information to be read.
917
12.11 Passing File Stream Objects to Functions
File stream objects may be passed by reference to functions. bool openFileIn(fstream &file, char name[51]) { bool status; file.open(name, ios::in); if (file.fail()) status = false; else status = true; return status; }
918
12.12 More Detailed Error Testing
All stream objects have error state bits that indicate the condition of the stream.
919
Table 12-5
920
Table 12-6
921
Program 12-11 // This program demonstrates the return value of the stream // object error testing member functions. #include <iostream.h> #include <fstream.h> // Function prototype void showState(fstream &); void main(void) { fstream testFile("stuff.dat", ios::out); if (testFile.fail()) cout << "cannot open the file.\n"; return; }
922
Program continues int num = 10;
cout << "Writing to the file.\n"; testFile << num; // Write the integer to testFile showState(testFile); testFile.close(); // Close the file testFile.open("stuff.dat", ios::in); // Open for input if (testFile.fail()) { cout << "cannot open the file.\n"; return; }
923
Program continues cout << "Reading from the file.\n";
testFile >> num; // Read the only number in the file showState(testFile); cout << "Forcing a bad read operation.\n"; testFile >> num; // Force an invalid read operation testFile.close(); // Close the file } // Definition of function ShowState. This function uses // an fstream reference as its parameter. The return values of // the eof(), fail(), bad(), and good() member functions are // displayed. The clear() function is called before the function // returns.
924
Program continues void showState(fstream &file) {
cout << "File Status:\n"; cout << " eof bit: " << file.eof() << endl; cout << " fail bit: " << file.fail() << endl; cout << " bad bit: " << file.bad() << endl; cout << " good bit: " << file.good() << endl; file.clear(); // Clear any bad bits }
925
Program Output Writing to the file. File Status: eof bit: 0
fail bit: 0 bad bit: 0 good bit: 1 Reading from the file. Forcing a bad read operation. eof bit: 1 fail bit: 2 good bit: 0
926
12.13 Member Functions for Reading and Writing Files
File stream objects have member functions for more specialized file reading and writing.
927
Figure 12-8
928
Program 12-12 // This program uses the file stream object's eof() member // function to detect the end of the file. #include <iostream.h> #include <fstream.h> void main(void) { fstream nameFile; char input[81]; nameFile.open("murphy.txt", ios::in); if (!nameFile) cout << "File open error!" << endl; return; }
929
Program 12-12 (continued) nameFile >> input;
while (!nameFile.eof()) { cout << input; } nameFile.close();
930
Program Screen Output JayneMurphy47JonesCircleAlmond,NC28702
931
The getline Member Function
dataFile.getline(str, 81, ‘\n’); str – This is the name of a character array, or a pointer to a section of memory. The information read from the file will be stored here. 81 – This number is one greater than the maximum number of characters to be read. In this example, a maximum of 80 characters will be read. ‘\n’ – This is a delimiter character of your choice. If this delimiter is encountered, it will cause the function to stop reading before it has read the maximum number of characters. (This argument is optional. If it’s left our, ‘\n’ is the default.)
932
Program 12-13 // This program uses the file stream object's getline member // function to read a line of information from the file. #include <iostream.h> #include <fstream.h> void main(void) { fstream nameFile; char input[81]; nameFile.open("murphy.txt", ios::in); if (!nameFile) cout << "File open error!" << endl; return; }
933
Program continues nameFile.getline(input, 81); // use \n as a delimiter while (!nameFile.eof()) { cout << input << endl; nameFile.getline(input, 81); // use \n as a delimiter } nameFile.close();
934
Program Screen Output Jayne Murphy 47 Jones Circle Almond, NC 28702
935
Program 12-14 // This file shows the getline function with a user-
// specified delimiter. #include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile("names2.txt", ios::in); char input[81]; dataFile.getline(input, 81, '$'); while (!dataFile.eof()) cout << input << endl; dataFile.getline(input, 81, '$'); } dataFile.close();
936
Program Output Jayne Murphy 47 Jones Circle Almond, NC 28702
Bobbie Smith 217 Halifax Drive Canton, NC 28716 Bill Hammet PO Box 121 Springfield, NC 28357
937
The get Member Function
inFile.get(ch);
938
Program 12-15 // This program asks the user for a file name. The file is // opened and its contents are displayed on the screen. #include <iostream.h> #include <fstream.h> void main(void) { fstream file; char ch, fileName[51]; cout << "Enter a file name: "; cin >> fileName; file.open(fileName, ios::in); if (!file) cout << fileName << “ could not be opened.\n"; return; }
939
Program continues file.get(ch); // Get a character while (!file.eof())
{ cout << ch; file.get(ch); // Get another character } file.close();
940
The put Member Function
outFile.put(ch);
941
Program 12-16 // This program demonstrates the put member function.
#include <iostream.h> #include <fstream.h> void main(void) { fstream dataFile("sentence.txt", ios::out); char ch; cout << "Type a sentence and be sure to end it with a "; cout << "period.\n"; while (1) { cin.get(ch); dataFile.put(ch); if (ch == '.') break; } dataFile.close();
942
Program Screen Output with Example Input
Type a sentence and be sure to end it with a period. I am on my way to becoming a great programmer. [Enter] Resulting Contents of the File SENTENCE.TXT: I am on my way to becoming a great programmer.
943
12.14 Focus on Software Engineering: Working with Multiple Files
It’s possible to have more than one file open at once in a program.
944
Program 12-17 // This program demonstrates reading from one file and writing // to a second file. #include <iostream.h> #include <fstream.h> #include <ctype.h> // Needed for the toupper function void main(void) { ifstream inFile; ofstream outFile("out.txt"); char fileName[81], ch, ch2; cout << "Enter a file name: "; cin >> fileName; inFile.open(fileName); if (!inFile) { cout << "Cannot open " << fileName << endl; return; }
945
Program continues inFile.get(ch); // Get a characer from file 1
while (!inFile.eof()) // Test for end of file { ch2 = toupper(ch); // Convert to uppercase outFile.put(ch2); // Write to file2 inFile.get(ch); // Get another character from file 1 } inFile.close(); outFile.close(); cout << "File conversion done.\n";
946
Program Screen Output with Example Input
Enter a file name: hownow.txt [Enter] File conversion done. Contents of hownow.txt: how now brown cow. How Now? Resulting Contents of out.txt: HOW NOW BROWN COW. HOW NOW?
947
Binary Files Binary files contain data that is unformatted, and not necessarily stored as ASCII text. file.open(“stuff.dat”, ios::out | ios::binary);
948
Figure 12-9
949
Figure 12-10
950
Program 12-18 // This program uses the write and read functions.
#include <iostream.h> #include <fstream.h> void main(void) { fstream file(“NUMS.DAT", ios::out | ios::binary); int buffer[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; cout << "Now writing the data to the file.\n"; file.write((char*)buffer, sizeof(buffer)); file.close(); file.open("NUMS.DAT", ios::in); // Reopen the file. cout << "Now reading the data back into memory.\n"; file.read((char*)buffer, sizeof(buffer)); for (int count = 0; count < 10; count++) cout << buffer[count] << " "; }
951
Program Screen Output Now writing the data to the file.
Now reading the data back into memory.
952
12.16 Creating Records with Structures
Structures may be used to store fixed-length records to a file. struct Info { char name[51]; int age; char address1[51]; char address2[51]; char phone[14]; }; Since structures can contain a mixture of data types, you should always use the ios::binary mode when opening a file to store them.
953
Program 12-19 // This program demonstrates the use of a structure variable to // store a record of information to a file. #include <iostream.h> #include <fstream.h> #include <ctype.h> // for toupper // Declare a structure for the record. struct Info { char name[51]; int age; char address1[51]; char address2[51]; char phone[14]; };
954
Program continues void main(void) {
fstream people("people.dat", ios::out | ios::binary); Info person; char again; if (!people) cout << "Error opening file. Program aborting.\n"; return; } do cout << "Enter the following information about a ” << "person:\n"; cout << "Name: ";
955
Program continues cin.getline(person.name, 51); cout << "Age: ";
cin >> person.age; cin.ignore(); // skip over remaining newline. cout << "Address line 1: "; cin.getline(person.address1, 51); cout << "Address line 2: "; cin.getline(person.address2, 51); cout << "Phone: "; cin.getline(person.phone, 14); people.write((char *)&person, sizeof(person)); cout << "Do you want to enter another record? "; cin >> again; cin.ignore(); } while (toupper(again) == 'Y'); people.close(); }
956
Program Screen Output with Example Input
Enter the following information about a person: Name: Charlie Baxter [Enter] Age: 42 [Enter] Address line 1: 67 Kennedy Bvd. [Enter] Address line 2: Perth, SC [Enter] Phone: (803) [Enter] Do you want to enter another record? Y [Enter] Name: Merideth Murney [Enter] Age: 22 [Enter] Address line 1: 487 Lindsay Lane [Enter] Address line 2: Hazelwood, NC [Enter] Phone: (704) [Enter] Do you want to enter another record? N [Enter]
957
Random Access Files Random Access means non-sequentially accessing informaiton in a file. Figure 12-11
958
Table 12-7
959
Table 12-8
960
Program 12-21 // This program demonstrates the seekg function.
#include <iostream.h> #include <fstream.h> void main(void) { fstream file("letters.txt", ios::in); char ch; file.seekg(5L, ios::beg); file.get(ch); cout << "Byte 5 from beginning: " << ch << endl; file.seekg(-10L, ios::end); cout << "Byte 10 from end: " << ch << endl;
961
Program continues file.seekg(3L, ios::cur); file.get(ch);
cout << "Byte 3 from current: " << ch << endl; file.close(); }
962
Program Screen Output Byte 5 from beginning: f Byte 10 from end: q
Byte 3 from current: u
963
The tellp and tellg Member Functions
tellp returns a long integer that is the current byte number of the file’s write position. tellg returns a long integer that is the current byte number of the file’s read position.
964
Program 12-23 // This program demonstrates the tellg function.
#include <iostream.h> #include <fstream.h> #include <ctype.h> // For toupper void main(void) { fstream file("letters.txt", ios::in); long offset; char ch, again; do cout << "Currently at position " << file.tellg() << endl; cout << "Enter an offset from the beginning of the file: "; cin >> offset;
965
Program continues file.seekg(offset, ios::beg); file.get(ch);
cout << "Character read: " << ch << endl; cout << "Do it again? "; cin >> again; } while (toupper(again) == 'Y'); file.close(); }
966
Program Output with Example Input
Currently at position 0 Enter an offset from the beginning of the file: 5 [Enter] Character read: f Do it again? y [Enter] Currently at position 6 Enter an offset from the beginning of the file: 0 [Enter] Character read: a Currently at position 1 Enter an offset from the beginning of the file: 20 [Enter] Character read: u Do it again? n [Enter]
967
12.18 Opening a File for Both Input and Output
You may perform input and output on an fstream file without closing it and reopening it. fstream file(“data.dat”, ios::in | ios::out);
968
Program 12-24 // This program sets up a file of blank inventory records. #include <iostream.h> #include <fstream.h> // Declaration of Invtry structure struct Invtry { char desc[31]; int qty; float price; }; void main(void) fstream inventory("invtry.dat", ios::out | ios::binary); Invtry record = { "", 0, 0.0 };
969
Program continues // Now write the blank records
for (int count = 0; count < 5; count++) { cout << "Now writing record " << count << endl; inventory.write((char *)&record, sizeof(record)); } inventory.close();
970
Program Screen Output Now writing record 0 Now writing record 1
971
Program 12-25 // This program displays the contents of the inventory file. #include <iostream.h> #include <fstream.h> // Declaration of Invtry structure struct Invtry { char desc[31]; int qty; float price; }; void main(void) fstream inventory("invtry.dat", ios::in | ios::binary); Invtry record = { "", 0, 0.0 };
972
Program continues // Now read and display the records
inventory.read((char *)&record, sizeof(record)); while (!inventory.eof()) { cout << "Description: "; cout << record.desc << endl; cout << "Quantity: "; cout << record.qty << endl; cout << "Price: "; cout << record.price << endl << endl; } inventory.close();
973
Here is the screen output of Program if it is run immediately after Program sets up the file of blank records. Program Screen Output Description: Quantity: 0 Price: 0.0
974
Program 12-26 // This program allows the user to edit a specific record in // the inventory file. #include <iostream.h> #include <fstream.h> // Declaration of Invtry structure struct Invtry { char desc[31]; int qty; float price; }; void main(void)
975
Program continues fstream inventory("invtry.dat", ios::in | ios::out | ios::binary); Invtry record; long recNum; cout << "Which record do you want to edit?"; cin >> recNum; inventory.seekg(recNum * sizeof(record), ios::beg); inventory.read((char *)&record, sizeof(record)); cout << "Description: "; cout << record.desc << endl; cout << "Quantity: "; cout << record.qty << endl; cout << "Price: "; cout << record.price << endl; cout << "Enter the new data:\n";
976
Program continues cin.ignore(); cin.getline(record.desc, 31);
cout << "Quantity: "; cin >> record.qty; cout << "Price: "; cin >> record.price; inventory.seekp(recNum * sizeof(record), ios::beg); inventory.write((char *)&record, sizeof(record)); inventory.close(); }
977
Program Screen Output with Example Input
Which record do you ant to edit? 2 [Enter] Description: Quantity: 0 Price: 0.0 Enter the new data: Description: Wrench [Enter] Quantity: 10 [Enter] Price: 4.67 [Enter]
978
Chapter 13 – Introduction to Classes
979
13.1 Procedural and Object-Oriented Programming
Procedural programming is a method of writing software. It is a programming practice centered on the procedures, or actions that take place in a program. Object-Oriented programming is centered around the object. Objects are created form abstract data types that encapsulate data and functions together.
980
What’s Wrong with Procedural Programming?
Programs with excessive global data Complex and convoluted programs Programs that are difficult to modify and extend
981
What is Object-Oriented Programming?
OOP is centered around the object, which packages together both the data and the functions that operate on the data.
982
Figure 13-1 Member Variables float width; float length; float area;
Member Functions void setData(float w, float l) { … function code … } void calcArea(void) { … function code … } void getWidth(void) { … function code … } void getLength(void) { … function code … } void getArea(void) { … function code … }
983
Terminology In OOP, an object’s member variables are often called its attributes and its member functions are sometimes referred to as its behaviors or methods.
984
Figure 13-2
985
How are Objects Used? Although the use of objects is only limited by the programmer’s imagination, they are commonly used to create data types that are either very specific or very general in purpose.
986
General Purpose Objects
Creating data types that are improvements on C++’s built-in data types. For example, an array object could be created that works like a regular array, but additionally provides bounds-checking. Creating data types that are missing from C++. For instance, an object could be designed to process currencies or dates as if they were built-in data types. Creating objects that perform commonly needed tasks, such as input validation and screen output in a graphical user interface.
987
Application-Specific Objects
Data types created for a specific application. For example, in an inventory program.
988
13.2 Introduction to the Class
In C++, the class is the construct primarily used to create objects. class class-name { // declaration statements here };
989
Example: class Rectangle { private: float width, length, area; public:
void setData(float, float); void calcArea(void); float getWidth(void); float getLength(void); float getArea(void); };
990
Access Specifiers The key words private and public are access specifiers. private means they can only be accessed by the member functions. public means they can be called from statements outside the class. Note: the default access of a class is private, but it is still a good idea to use the private key word to explicitly declare private members. This clearly documents the access specification of the class.
991
13.3 Defining Member Functions
Class member functions are defined similarly to regular functions. void Rectangle::setData(float w, float l) { width = w; length = l; }
992
13.4 Defining an Instance of a Class
Class objects must be defined after the class is declared. Defining a class object is called the instantiation of a class. Rectangle box; // box is an instance of Rectangle
993
Accessing an Object’s Members
box.calcArea();
994
Pointers to Objects Rectangle *boxPtr; boxPtr = &box;
boxPtr->setData(15,12);
995
Program 13-1 // This program demonstrates a simple class.
#include <iostream.h> // Rectangle class declaration. class Rectangle { private: float width; float length; float area; public: void setData(float, float); void calcArea(void); float getWidth(void); float getLength(void); float getArea(void); };
996
Program continues // setData copies the argument w to private member width and // l to private member length. void Rectangle::setData(float w, float l) { width = w; length = l; } // calcArea multiplies the private members width and length. // The result is stored in the private member area. void Rectangle::calcArea(void) area = width * length;
997
Program continues // getWidth returns the value in the private member width. float Rectangle::getWidth(void) { return width; } // getLength returns the value in the private member length. float Rectangle::getLength(void) return length; // getArea returns the value in the private member area. float Rectangle::getArea(void) return area;
998
Program continues void main(void) { 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 is the rectangle's data:\n"; cout << "width: " << box.getWidth() << endl; cout << "length: " << box.getLength() << endl; cout << "area: " << box.getArea() << endl; }
999
Program Output This program will calculate the area of a
rectangle. What is the width? 10 [Enter] What is the length? 5 [Enter] Here is the rectangle's data: width: 10 length: 5 area: 50
1000
13.5 Why Have Private Members?
In object-oriented programming, an object should protect its important data by making it private and providing a public interface to access that data.
1001
13.6 Focus on Software Engineering: Some Design Considerations
Usually class declarations are stored in their own header files. Member function definitions are stored in their own .CPP files. The #ifndef directive allows a program to be conditionally compiled. This prevents a header file from accidentally being included more than once.
1002
Program 13-2 Contents of RECTANG.H #ifndef RECTANGLE_H
#define RECTANGLE_H // Rectangle class declaration. class Rectangle { private: float width; float length; float area; public: void setData(float, float); void calcArea(void); float getWidth(void); float getLength(void); float getArea(void); }; #endif
1003
Program continues Contents of RECTANG.CPP #include "rectang.h"
// setData copies the argument w to private member width and // l to private member length. void Rectangle::setData(float w, float l) { width = w; length = l; } // calcArea multiplies the private members width and length. // The result is stored in the private member area. void Rectangle::calcArea(void) area = width * length;
1004
Program continues // getWidth returns the value in the private member width. float Rectangle::getWidth(void) { return width; } // getLength returns the value in the private member length. float Rectangle::getLength(void) return length; // getArea returns the value in the private member area. float Rectangle::getArea(void) return area;
1005
Program continues Contents of the main program, PR13-2.CPP
// This program demonstrates a simple class. #include <iostream.h> #include "rectang.h" // contains Rectangle class declaration // Don't forget to link this program with rectang.cpp! void main(void) { 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;
1006
Program continues 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; }
1007
Performing I/O in a Class Object
Notice that the Rectangle example has no cin or cout. This is so anyone who writes a program that uses the Rectangle class will not be “locked into” the way the class performs input or output. Unless a class is specifically designed to perform I/O, operations like user input and output are best left to the person designing the application.
1008
Table 13-1
1009
13.7 Focus on Software Engineering: Using Private Member Functions
A private member function may only be called from a function that is a member of the same object.
1010
Program 13-3 #include <iostream.h>
#include "rectang2.h" // contains Rectangle class declaration // Don't forget to link this program with rectang2.cpp! void main(void) { 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); cout << "Here rectangle's data:\n"; cout << "width: " << box.getWidth() << endl; cout << "length: " << box.getLength() << endl; cout << "area: " << box.getArea() << endl; }
1011
Program Output This program will calculate the area of a
rectangle. What is the width? 10 [Enter] What is the length? 5 [Enter] Here rectangle's data: width: 10 length: 5 area: 50
1012
13.8 Inline Member Functions
When the body of a member function is defined inside a class declaration, it is declared inline.
1013
Program 13-4 Contents of RECTANG3.H #ifndef RECTANGLE_H
#define RECTANGLE_H // Rectangle class declaration. class Rectangle { private: float width; float length; float area; void calcArea(void) { area = width * length; }
1014
Program continues public: void setData(float, float); // Prototype
float getWidth(void) { return width; } float getLength(void) { return length; } float getArea(void) { return area; } }; #endif Contents of rectang3.cpp #include "rectang3.h" // setData copies the argument w to private member width and // l to private member length. void Rectangle::setData(float w, float l) { width = w; length = l; calcArea(); }
1015
Program continues Contents of the main program, pr13-4.cpp
#include <iostream.h> #include "rectang3.h" // contains Rectangle class declaration // Don't forget to link this program with rectang3.cpp! void main(void) { 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;
1016
Program continues box.setData(wide, long);
cout << "Here rectangle's data:\n"; cout << "width: " << box.getWidth() << endl; cout << "length: " << box.getLength() << endl; cout << "area: " << box.getArea() << endl; }
1017
Program Output This program will calculate the area of a
rectangle. What is the width? 10 [Enter] What is the length? 5 [Enter] Here rectangle's data: width: 10 length: 5 area: 50
1018
13.9 Constructors A constructor is a member function that is automatically called when a class object is created. Constructors have the same name as the class. Constructors must be declared publicly. Constructors have no return type.
1019
Program 13-5 // This program demonstrates a constructor.
#include <iostream.h> class Demo { public: Demo(void); // Constructor }; Demo::Demo(void) cout << "Welcome to the constructor!\n"; }
1020
Program continues void main(void) {
Demo demoObj; // Declare a Demo object; cout << "This program demonstrates an object\n"; cout << "with a constructor.\n"; }
1021
Program Output Welcome to the constructor.
This program demonstrates an object with a constructor.
1022
Program 13-6 // This program demonstrates a constructor.
#include <iostream.h> class Demo { public: Demo(void); // Constructor }; Demo::Demo(void) cout << "Welcome to the constructor!\n"; }
1023
Program continues void main(void) {
cout << "This is displayed before the object\n"; cout << "is declared.\n\n"; Demo demoObj; cout << "\nThis is displayed after the object\n"; cout << "is declared.\n"; }
1024
Program Output This is displayed before the object is declared.
Welcome to the constructor. This is displayed after the object
1025
Constructor Arguments
When a constructor does not have to accept arguments, it is called an object’s default constructor. Like regular functions, constructors may accept arguments, have default arguments, be declared inline, and be overloaded.
1026
Program 13-7 // This program demonstrates a class with a constructor
#include <iostream.h> #include <string.h> class InvItem { private: char *desc; int units; public: InvItem(void) { desc = new char[51]; } void setInfo(char *dscr, int un) { strcpy(desc, dscr); units = un;} char *getDesc(void) { return desc; } int getUnits(void) { return units; } };
1027
Program continues void main(void) { InvItem stock;
stock.setInfo("Wrench", 20); cout << "Item Description: " << stock.getDesc() << endl; cout << "Units on hand: " << stock.getUnits() << endl; }
1028
Program Output Item Description: Wrench Units on hand: 20
1029
Destructors A destructor is a member function that is automatically called when an object is destroyed. Destructors have the same name as the class, preceded by a tilde character (~) In the same way that a constructor is called then the object is created, the destructor is automatically called when the object is destroyed. In the same way that a constructor sets things up when an object is created, a destructor performs shutdown procedures when an object is destroyed.
1030
Program 13-8 // This program demonstrates a destructor.
#include <iostream.h> class Demo { public: Demo(void); // Constructor ~Demo(void); // Destructor }; Demo::Demo(void) cout << "Welcome to the constructor!\n"; }
1031
Program continues Demo::~Demo(void) {
cout << "The destructor is now running.\n"; } void main(void) Demo demoObj; // Declare a Demo object; cout << "This program demonstrates an object\n"; cout << "with a constructor and destructor.\n";
1032
Program Output Welcome to the constructor!
This program demonstrates an object with a constructor and destructor. The destructor is now running.
1033
Program 13-9 #include <iostream.h> #include <string.h>
class InvItem { private: char *desc; int units; public: InvItem(void) { desc = new char[51]; } ~InvItem(void) { delete desc; } void setInfo(char *dscr, int un) { strcpy(desc, dscr); units = un;} char *getDesc(void) { return desc; } int getUnits(void) { return units; } };
1034
Program continues void main(void) { InvItem stock;
stock.setInfo("Wrench", 20); cout << "Item Description: " << stock.getDesc() << endl; cout << "Units on hand: " << stock.getUnits() << endl; }
1035
Program Output Item Description: Wrench Units on hand: 20
1036
13.11 Constructors that Accept Arguments
Information can be passed as arguments to an object’s constructor.
1037
Program 13-10 Contents of sale.h #ifndef SALE_H #define SALE_H
// Sale class declaration class Sale { private: float taxRate; float total; public: Sale(float rate) { taxRate = rate; } void calcSale(float cost) { total = cost + (cost * taxRate) }; float getTotal(void) { return total; } }; #endif
1038
Program continues Contents of main program, pr13-10.cpp
#include <iostream.h> #include "sale.h" void main(void) { Sale cashier(0.06); // 6% sales tax rate float amnt; cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "Enter the amount of the sale: "; cin >> amnt; cashier.calcSale(amnt); cout << "The total of the sale is $"; cout << cashier.getTotal << endl; }
1039
Program Output Enter the amount of the sale: 125.00
The total of the sale is $132.50
1040
Program 13-11 Contents of sale2.h #ifndef SALE2_H #define SALE2_H
// Sale class declaration class Sale { private: float taxRate; float total; public: Sale(float rate = 0.05) { taxRate = rate; } void calcSale(float cost) { total = cost + (cost * taxRate) }; float getTotal (void) { return total; } }; #endif
1041
Program continues Contents of main program, pr13-11.cpp
#include <iostream.h> #include "sale2.h" void main(void) { Sale cashier1; // Use default sales tax rate Sale cashier2 (0.06); // Use 6% sales tax rate float amnt; cout.precision(2); cout.set(ios::fixed | ios::showpoint); cout << "Enter the amount of the sale: "; cin >> amnt; cashier1.calcSale(amnt); cashier2.calcSale(amnt);
1042
Program continues cout << "With a 0.05 sales tax rate, the total\n"; cout << "of the sale is $"; cout << cashier1.getTotal() << endl; cout << "With a 0.06 sales tax rate, the total\n"; cout << cashier2.getTotal() << endl; }
1043
Program Output Enter the amount of the sale: 125.00
With a 0.05 sales tax rate, the total of the sale is $131.25 With a 0.06 sales tax rate, the total of the sale is $132.50
1044
13.12 Focus on Software Engineering: Input Validation Objects
This section shows how classes may be designed to validate user input.
1045
Program 13-12 // This program demonstrates the CharRange class.
#include <iostream.h> #include "chrange.h" // Remember to compile & link chrange.cpp void main(void) { // Create an object to check for characters // in the range J - N. CharRange input('J', 'N'); cout << "Enter any of the characters J, K, l, M, or N.\n"; cout << "Entering N will stop this program.\n"; while (input.getChar() != 'N'); }
1046
Program Output with Example Input
Enter any of the characters J, K, l, M, or N Entering N will stop this program. j k q n [Enter]
1047
13.13 Overloaded Constructors
More than one constructor may be defined for a class.
1048
Program 13-13 Contents of invitem2.h #ifndef INVITEM2_H
#define INVITEM2_H #include <string.h> // Needed for strcpy function call. // InvItem class declaration class InvItem { private: char *desc; int units; public: InvItem(int size = 51) { desc = new char[size]; } InvItem(char *d) { desc = new char[strlen(d)+1]; strcpy(desc, d); }
1049
Program continues ~InvItem(void) { delete[] desc; }
void setInfo(char *d, int u) { strcpy(desc, d); units = u;} void setUnits (int u) { units = u; } char *getDesc(void) { return desc; } int getUnits(void) { return units; } }; #endif Contents of main program, pr13-13.cpp // This program demonstrates a class with overloaded constructors #include <iostream.h> #include "invitem2.h" void main(void) {
1050
Program continues InvItem item1("Wrench"); InvItem item2;
item1.setUnits(15); item2.setInfo("Pliers", 25); cout << "The following items are in inventory:\n"; cout << "Description: " << item1.getDesc() << "\t\t"; cout << "Units on Hand: " << item1.getUnits() << endl; cout << "Description: " << item2.getDesc() << "\t\t"; cout << "Units on Hand: " << item2.getUnits() << endl; }
1051
Program Output The following items are in inventory:
Description: Wrench Units on Hand: 15 Description: Pliers Units on Hand 25
1052
13.14 Only One Default Constructor and one Destructor
A class may only have one default constructor and one destructor.
1053
Arrays of Objects You may declare and work with arrays of class objects. InvItem inventory[40];
1054
Program 13-14 Contents of invitem3.h #ifndef INVITEM3_H
#define INVITEM3_H #include <string.h> // Needed for strcpy function call. // InvItem class declaration class InvItem { private: char *desc; int units; public: InvItem(int size = 51) { desc = new char[size]; } InvItem(char *d) { desc = new[strlen(d)+1]; strcpy(desc, d); }
1055
Program continues InvItem(char *d, int u) { desc = new[strlen(d)+1];
strcpy(desc, d); units = u; } ~InvItem(void) { delete [] desc; } void setInfo(char * dscr, int u) { strcpy(desc, dscr); units = un;} void setUnits (int u) { units = u; } char *getDesc(void) { return desc; } int getUnits(void) { return units; } }; #endif Contents of main program, pr13-14.cpp // This program demonstrates an array of objects. #include <iostream.h> #include <iomanip.h> #include "invitem3.h"
1056
Program continues void main(void) {
InvItem Inventory[5] = { InvItem("Adjustable Wrench", 10), InvItem("Screwdriver", 20), InvItem("Pliers", 35), InvItem("Ratchet", 10), InvItem("Socket Wrench", 7) }; cout << "Inventory Item\t\tUnits On Hand\n"; cout << " \n"; for (int Index = 0; Index < 5; Index++) cout << setw(17) << Inventory[Index].GetDesc(); cout << setw(12) << Inventory[Index].GetUnits() << endl; }
1057
Program Output Inventory Item Units On Hand
Adjustable Wrench Screwdriver Pliers Ratchet Socket Wrench
1058
Chapter 14 – More About Classes
1059
14.1 Static Members If a member variable is declared static, all objects of that class have access to that variable. If a member function is declared static, it may be called before any instances of the class are defined.
1060
Figure 14-1
1061
Figure 14-2
1062
Program 14-1 Contents of budget.h #ifndef BUDGET_H #define BUDGET_H
// Budget class declaration class Budget { private: static float corpBudget; float divBudget; public: Budget(void) { divBudget = 0; } void addBudget(float b) { divBudget += b; corpBudget += divBudget; } float getDivBudget(void) { return divBudget; } float getCorpBudget(void) { return corpBudget; } }; #endif
1063
Program continues Contents of main program, pr14-1.cpp
// This program demonstrates a static class member variable. #include <iostream.h> #include <iomanip.h> #include "budget.h" // For Budget class declaration float Budget::corpBudget = 0; // Definition of static member of Budget class void main(void) { Budget divisions[4]; for (int count = 0; count < 4; count++) float bud; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> bud;
1064
Program continues divisions[count].addBudget(bud); }
cout.precision(2); cout.setf(ios::showpoint | ios::fixed); cout << "\nHere are the division budget requests:\n"; for (int count = 0; count < 4; count++) { cout << "\tDivision " << (count + 1) << "\t$ "; cout << divisions[count].getDivBudget() << endl; cout << "\tTotal Budget Requests:\t$ "; cout << divisions[0].getCorpBudget() << endl;
1065
Program Output with Example Input
Enter the budget request for Division 1: [Enter] Enter the budget request for Division 2: [Enter] Enter the budget request for Division 3: [Enter] Enter the budget request for Division 4: [Enter] Here are the division budget requests: Division 1 $ Division 1 $ Division 1 $ Division 1 $ Total Budget Requests: $
1066
Static Member Functions
static <return type><function name>(<parameter list>); Even though static member variables are declared in a class, they are actually defined outside the class declaration. The lifetime of a class’s static member variable is the lifetime of the program. This means that a class’s static member variables come into existence before any instances of the class are created. The static member functions of a class are callable before any instances of the class are created. This means that the static member functions of a class can access the class’s static member variables before any instances of the class are defined in memory. This gives you the ability to create very specialized setup routines for class objects.
1067
Program 14-2 Contents of BUDGET2.H #ifndef BUDGET_H #define BUDGET_H
class Budget { private: static float corpBudget; float divBudget; public: Budget(void) { divBudget = 0; } void addBudget(float b) { divBudget += b; corpBudget += divBudget; } float getDivBudget(void) { return divBudget; } float getCorpBudget(void) { return corpBudget; } static void mainOffice(float); }; #endif
1068
Program continues Contents of budget2.cpp #include "budget2.h" float Budget::corpBudget = 0; // Definition of static member of Budget class // Definition of static member function MainOffice. // This function adds the main office's budget request to // the CorpBudget variable. void Budget::mainOffice(float moffice) { corpBudget += moffice; }
1069
Program continues Contents of main program, pr14-2.cpp
// This program demonstrates a static class member function. #include <iostream.h> #include <iomanip.h> #include "budget2.h" // For Budget class declaration void main(void) { float amount; cout << "Enter the main office's budget request: "; cin >> amount; Budget::mainOffice(amount); Budget divisions[4];
1070
Program continues for (int count = 0; count < 4; count++) {
float bud; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> bud; divisions[count].addBudget(bud); } cout.precision(2); cout.setf(ios::showpoint | ios::fixed); cout << "\nHere are the division budget requests:\n"; cout << "\tDivision " << (count + 1) << "\t$ "; cout << divisions[count].getDivBudget() << endl;
1071
Program continues cout << "\tTotal Requests (including main office): $ "; cout << divisions[0].getCorpBudget() << endl; }
1072
Program Output with Example Input
Enter the main office's budget request: [Enter] Enter the budget request for Division 1: [Enter] Enter the budget request for Division 2: [Enter] Enter the budget request for Division 3: [Enter] Enter the budget request for Division 4: [Enter] Here are the division budget requests: Division 1 $ Division 1 $ Division 1 $ Division 1 $ Total Requests (including main office): $
1073
14.2 Friends of Classes A friend is a function that is not a member of a class, but has access to the private members of the class. friend <return type><function name>(<parameter type list>);
1074
Program 14-3 Contents of auxil.h #ifndef AUXIL_H #define AUXIL_H
class Budget; // Forward declaration of Budget class // Aux class declaration class Aux { private: float auxBudget; public: Aux(void) { auxBudget = 0; } void addBudget(float, Budget &); float getDivBudget(void) { return auxBudget; } }; #endif
1075
Program continues Contents of budget3.h #ifndef BUDGET3_H
#define BUDGET3_H #include "auxil.h" // For Aux class declaration // Budget class declaration class Budget { private: static float corpBudget; float divBudget; public: Budget(void) { divBudget = 0; } void addBudget(float b) { divBudget += b; corpBudget += divBudget; }
1076
Program continues float getDivBudget(void) { return divBudget; }
float getCorpBudget(void) { return corpBudget; } static void mainOffice(float); friend void Aux::addBudget(float, Budget &); }; #endif Contents of budget3.cpp #include "budget3.h" float Budget::corpBudget = 0; // Definition of static member of Budget class // Definition of static member function MainOffice. // This function adds the main office's budget request to // the CorpBudget variable.
1077
Program continues void Budget::mainOffice(float moffice) {
corpBudget += moffice; } Contents of auxil.cpp #include "auxil.h" #include "budget3.h" void Aux::addBudget(float b, Budget &div) auxBudget += b; div.corpBudget += auxBudget;
1078
Program continues Contents of main program pr14-3.cpp
// This program demonstrates a static class member variable. #include <iostream.h> #include <iomanip.h> #include "budget3.h" void main(void) { float amount; cout << "Enter the main office's budget request: "; cin >> amount; Budget::mainOffice(amount); Budget divisions[4]; Aux auxOffices[4];
1079
Program continues for (int count = 0; count < 4; count++) {
float bud; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> bud; divisions[count].addBudget(bud); cout << (count + 1) << "'s\nauxiliary office: "; auxOffices[count].addBudget(bud, divisions[count]); } cout.precision(2); cout.setf(ios::showpoint | ios::fixed); cout << "Here are the division budget requests:\n";
1080
Program continues for (count = 0; count < 4; count++) {
cout << "\tDivision " << (count + 1) << "\t\t\t$ "; cout << setw(7); cout << divisions[count].getDivBudget() << endl; cout << "\tAuxilary Office of Division " << (count+1); cout << "\t$ "; cout << auxOffices[count].getDivBudget() << endl; } cout << "\tTotal Requests (including main office): $ "; cout << divisions[0].getCorpBudget() << endl;
1081
Program Output with Example Input
Enter the main office's budget request: [Enter] Enter the budget request for Division 1: [Enter] Enter the budget request for Division 1's auxilary office: [Enter] Enter the budget request for Division 2: [Enter] Enter the budget request for Division 2's auxilary office: [Enter] Enter the budget request for Division 3: [Enter] Enter the budget request for Division 3's auxilary office: [Enter] Enter the budget request for Division 4: [Enter] Enter the budget request for Division 4's auxilary office: [Enter] Here are the division budget requests: Division 1: $ Auxilary office of Division 1: $ Division 2: $ Auxilary office of Division 2: $ Division 3: $ Auxilary office of Division 3: $ Division 4: $ Auxilary office of Division 4: $ Total Requests (including main office): $
1082
Friend classes As mentioned before, it is possible to make an entire class a friend of another class. The Budget class could make the Aux class its friend with the following declaration: friend class Aux;
1083
14.3 Memberwise Assignment
The = operator may be used to assign one object to another, or to initialize one object with another object’s data. By default, each member of one object is copied to its counterpart in the other object.
1084
Program 14-4 #include <iostream.h> class Rectangle { private:
float width; float length; float area; void calcArea(void) { area = width * length; } public: void setData(float w, float l) { width = w; length = l; calcArea(); } float getWidth(void) { return width; }
1085
Program continues float getLength(void) { return length; }
float getArea(void) { return area; } }; void main(void) { Rectangle box1, box2; box1.setData(10, 20); box2.setData(5, 10); cout << "Before the assignment:\n"; cout << "Box 1's Width: " << box1.getWidth() << endl; cout << "Box 1's Length: " << box1.getLength() << endl; cout << "Box 1's Area: " << box1.getArea() << endl;
1086
Program continues cout << "Box 2's Width: " << box2.getWidth() << endl; cout << "Box 2's Length: " << box2.getLength() << endl; cout << "Box 2's Area: " << box2.getArea() << endl; box2 = box1; cout << " \n"; cout << "After the assignment:\n"; cout << "Box 1's Width: " << box1.getWidth() << endl; cout << "Box 1's Length: " << box1.getLength() << endl; cout << "Box 1's Area: " << box1.getArea() << endl; }
1087
Program Output Before the assignment: Box 1's Width: 10
Box 1's Length: 20 Box 1's Area: 200 Box 2's Width: 5 Box 2's Length: 10 Box 2's Area: 50 After the assignment: Box 2's Width: 10 Box 2's Length: 20 Box 2's Area: 200
1088
14.4 Copy Constructors A copy constructor is a special constructor, called whenever a new object is created and initialized with another object’s data. PersonInfo person1(“Maria Jones-Tucker”,25); PersonInfo person2 = person1;
1089
Figure 14-3 Maria Jones-Tucker name Pointer
Dynamically allocated memory
1090
Figure 14-4 Dynamically allocated memory Maria Jones-Tucker
person1’s name Pointer Both objects’ name members point to the same section of memory person2’s name Pointer
1091
Using const Parameters
Because copy constructors are required to use reference parameters, they have access to their argument’s data. They should not be allowed to change the parameters, therefore, it is a good idea to make the parameter const so it can’t be modified. PersonInfo(const PersonInfo &Obj) { Name= new char[strlen(Obj.Name) + 1]; strcpy(Name, Obj.Name); Age = Obj.Age; }
1092
The Default Copy Constructor
If a class doesn’t have a copy constructor, C++ automatically creates a default copy constructor. The default copy constructor performs a memberwise assignment.
1093
14.5 Operator Overloading C++ allows you to redefine how standard operators work when used with class objects.
1094
Overloading the = Operator
void operator = (const PersonInfo &Right); Will be called with a statement like: person2 = person1; Or person2.operator=(person1); Note that the parameter, Right, was declared as a reference for efficiency purposes – the reference prevents the compiler form making a copy of the object being passed into the function. Also note that the parameter was declared constant so the function will not accidentally change the contents of the argument.
1095
Program 14-5 // This program demonstrates the overloaded = operator.
#include <iostream.h> #include <string.h> // For strlen class PersonInfo { private: char *name; int age; public: PersonInfo(char *n, int a) { name = new char[strlen(n) + 1]; strcpy(name, n); age = a; }
1096
Program continues PersonInfo(const PersonInfo &obj) // Copy constructor { name = new char[strlen(obj.name) + 1]; strcpy(name, obj.name); age = obj.age; } ~PersonInfo(void) { delete [] name; } char *getName(void) { return name; } int getAge(void) { return age; } void operator=(const PersonInfo &right) { delete [] name; name = new char[strlen(right.name) + 1]; strcpy(name, right.name); age = right.age; } };
1097
Program continues void main(void) { PersonInfo jim("Jim Young", 27),
bob("Bob Faraday", 32), clone = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << Jim.GetAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; cout << "Now the clone will change to Bob and "; cout << "Bob will change to Jim.\n"; clone = bob; // Call overloaded = operator bob = jim; // Call overloaded = operator
1098
Program continues cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; }
1099
Program Output The Jim Object contains: Jim Young, 27
The Bob Object contains: Bob Faraday, 32 The Clone Object contains: Jim Young, 27 Now the clone will change to Bob and Bob will change to Jim. The Bob Object contains: Jim Young, 27 The Clone Object contains: Bob Faraday, 32
1100
The = Operator’s Return Value
If the operator= function returns a void, as in the above example, then multiple assignment statements won’t work. To enable a statement such as person3 = person2 = person1; You must have the following prototype: PersonInfo operator=(const PersonInfo &right);
1101
The this Pointer *this is a special built in pointer that is available in any member function. *this contains the address of the object that called the member function. The this pointer is passed as a hidden argument to all non-static member functions.
1102
Program 14-6 // This program demonstrates the overloaded = operator.
#include <iostream.h> #include <string.h> // For strlen class PersonInfo { private: char *name; int age; public: PersonInfo(char *n, int a) { name = new char[strlen(n)+ 1]; strcpy(name, n); age = a; }
1103
Program continues PersonInfo(const PersonInfo &obj) // Copy constructor { name = new char[strlen(obj.name)+ 1]; strcpy(name, obj.name); age = obj.age; } ~PersonInfo(void) { delete [] name; } char *getName(void) { return name; } int getAge(void) { return age; } PersonInfo operator=(const PersonInfo &right) { delete [] name; name = new char[strlen(right.name) + 1]; strcpy(name, right.name); age = right.age; return *this; } };
1104
Program continues void main(void) { PersonInfo jim("Jim Young", 27),
bob("Bob Faraday", 32), clone = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; cout << "Now the clone and Bob will change to Jim.\n"; clone = bob = jim; // Call overloaded = operator
1105
Program continues cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; }
1106
Program Output The Jim Object contains: Jim Young, 27
The Bob Object contains: Bob Faraday, 32 The Clone Object contains: Jim Young, 27 Now the clone and Bob will change to Jim. The Bob Object contains: Jim Young, 27 The Clone Object contains: Jim Young, 2
1107
Some General Issues of Operator Overloading
You can change an operator’s entire meaning when you overload it. (But don’t.) You cannot change the number of operands taken by an operator. For example, the = symbol must always be a binary operator. Likewise, ++ and – must always be unary operators. You cannot overload the ?: . .* :: and sizeof operators.
1108
Table 14-1
1109
Program 14-7 Contents of feetinc2.h
#include <stdlib.h> // Needed for abs() #ifndef FEETINCHES_H #define FEETINCHES_H // A class to hold distances or measurements expressed in feet and inches. class FeetInches { private: int feet; int inches; void simplify(void); // Defined in feetinc2.cpp public: FeetInches(int f = 0, int i = 0) { feet = f; inches = i; simplify(); }
1110
Program continues void setData(int f, int i)
{ feet = f; inches = i; simplify(); } int getFeet(void) { return feet; } int getInches(void) { return inches; } FeetInches operator + (const FeetInches &); // Overloaded + FeetInches operator - (const FeetInches &); // Overloaded - }; #endif
1111
Program continues Contents of feetinc2.cpp #include "feetinc2.h"
// Definition of member function Simplify. This function checks for values // in the Inches member greater than twelve and less than zero. If such a // value is found, the numbers in Feet and Inches are adjusted to conform // to a standard feet & inches expression. void FeetInches::simplify(void) { if (inches >= 12) feet += (inches / 12); // Integer division inches = inches % 12; } else if (inches < 0) feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12);
1112
Program continues // Overloaded binary + operator.
FeetInches FeetInches::operator+(const FeetInches &right) { FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp; } // Overloaded binary - operator. FeetInches FeetInches::operator-(const FeetInches &right) temp.inches = inches - right.inches; temp.feet = feet - right.feet; return Temp;
1113
Program continues Contents of the main program file, pr14-7.cpp // This program demonstrates the FeetInches class's overloaded // + and - operators. #include <iostream.h> #include "feetinc2.h" void main(void) { FeetInches first, second, third; int f, i; cout << "Enter a distance in feet and inches: "; cin >> f >> i; first.setData(f, i); cout << "Enter another distance in feet and inches: ";
1114
Program continues second.setData(f, i); third = first + second;
cout << "First + Second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; third = first - second; cout << "First - Second = "; }
1115
Program Output with Example Input
Enter a distance in feet and inches: 6 5 [Enter] Enter another distance in feet and inches: 3 10 [Enter] First + Second = 10 feet, 3 inches. First - Second = 2 feet, 7 inches.
1116
Overloading the Prefix ++ Operator
FeetInches FeetInches::operator++(void) { ++inches; simplify(); return *this; }
1117
Overloading the Postfix ++ Operator
FeetInches FeetInches::operator++(int) { FeetInches temp(feet,inches); inches++; simplify(); return temp; }
1118
Program 14-8 Contents of feetinc3.h
#include <stdlib.h> // Needed for abs() #ifndef FEETINCHES_H #define FEETINCHES_H // A class to hold distances or measurements expressed // in feet and inches. class FeetInches { private: int feet; int inches; void simplify(void); // Defined in feetinc3.cpp public: FeetInches(int f = 0, int i = 0)
1119
Program continues { feet = f; inches = i; simplify(); }
void setData(int f, int i) int getFeet(void) { return feet; } int getInches(void) { return inches; } FeetInches operator + (const FeetInches &); // Overloaded + FeetInches operator - (const FeetInches &); // Overloaded - FeetInches operator++(void); // Prefix ++ FeetInches operator++(int); // Postfix ++ }; #endif
1120
Program continues Contents of feetinc3.cpp #include "feetinc3.h"
// Definition of member function Simplify. This function // checks for values in the Inches member greater than // twelve and less than zero. If such a value is found, // the numbers in Feet and Inches are adjusted to conform // to a standard feet & inches expression. For example, // 3 feet 14 inches would be adjusted to 4 feet 2 inches and // 5 feet -2 inches would be adjusted to 4 feet 10 inches. void FeetInches::simplify(void) { if (inches >= 12) feet += (inches / 12); // Integer division inches = inches % 12; }
1121
Program continues else if (inches < 0) {
feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12); } // Overloaded binary + operator. FeetInches FeetInches::operator+(const FeetInches &right) FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp;
1122
Program continues // Overloaded binary - operator.
FeetInches FeetInches::operator-(const FeetInches &right) { FeetInches temp; temp.inches = inches - right.inches; temp.feet = feet - right.feet; temp.simplify(); return temp; } // Overloaded prefix ++ operator. Causes the Inches member to // be incremented. Returns the incremented object. FeetInches FeetInches::operator++(void) ++inches; simplify(); return *this;
1123
Program continues // Overloaded postfix ++ operator. Causes the Inches member to // be incremented. Returns the value of the object before the // increment. FeetInches FeetInches::operator++(int) { FeetInches temp(feet, inches); inches++; simplify(); return temp; } Contents of the main program file, pr14-8.cpp // This program demonstrates the FeetInches class's overloaded // prefix and postfix ++ operators. #include <iostream.h> #include "feetinc3.h"
1124
Program continues void main(void) { FeetInches first, second(1, 5);
cout << "Demonstrating prefix ++ operator.\n"; for (int count = 0; count < 12; count++) first = ++second; cout << "First: " << first.getFeet() << " feet, "; cout << first.getInches() << " inches. "; cout << "Second: " << second.getFeet() << " feet, "; cout << second.getInches() << " inches.\n"; } cout << "\nDemonstrating postfix ++ operator.\n"; for (count = 0; count < 12; count++) first = second++;
1125
Program continues cout << "First: " << first.getFeet() << " feet, "; cout << first.getInches() << " inches. "; cout << "Second: " << second.getFeet() << " feet, "; cout << second.getInches() << " inches.\n"; }
1126
Program Output with Example Input
Demonstrating prefix ++ operator. First: 1 feet 6 inches. Second: 1 feet 6 inches. First: 1 feet 7 inches. Second: 1 feet 7 inches. First: 1 feet 8 inches. Second: 1 feet 8 inches. First: 1 feet 9 inches. Second: 1 feet 9 inches. First: 1 feet 10 inches. Second: 1 feet 10 inches. First: 1 feet 11 inches. Second: 1 feet 11 inches. First: 2 feet 0 inches. Second: 2 feet 0 inches. First: 2 feet 1 inches. Second: 2 feet 1 inches. First: 2 feet 2 inches. Second: 2 feet 2 inches. First: 2 feet 3 inches. Second: 2 feet 3 inches. First: 2 feet 4 inches. Second: 2 feet 4 inches. First: 2 feet 5 inches. Second: 2 feet 5 inches.
1127
Output continues Demonstrating postfix ++ operator.
First: 2 feet 5 inches. Second: 2 feet 6 inches. First: 2 feet 6 inches. Second: 2 feet 7 inches. First: 2 feet 7 inches. Second: 2 feet 8 inches. First: 2 feet 8 inches. Second: 2 feet 9 inches. First: 2 feet 9 inches. Second: 2 feet 10 inches. First: 2 feet 10 inches. Second: 2 feet 11 inches. First: 2 feet 11 inches. Second: 3 feet 0 inches. First: 3 feet 0 inches. Second: 3 feet 1 inches. First: 3 feet 1 inches. Second: 3 feet 2 inches. First: 3 feet 2 inches. Second: 3 feet 3 inches. First: 3 feet 3 inches. Second: 3 feet 4 inches. First: 3 feet 4 inches. Second: 3 feet 5 inches.
1128
Overloading Relational Operators
if (distance1 < distance2) { … code … }
1129
Relational operator example
int FeetInches:: operator>(const FeetInches &right) { if (feet > right.feet) return 1; else if (feet == right.feet && inches > right.inches) return 0; }
1130
Overloading the [] Operator
In addition to the traditional operators, C++ allows you to change the way the [] symbols work.
1131
Program 14-12 #include <iostream.h> #include "intarray.h"
void main(void) { IntArray table(10); // Store values in the array. for (int x = 0; x < 10; x++) table[x] = x; // Display the values in the array. cout << table[x] << " "; cout << endl; // Use the built-in + operator on array elements. table[x] = table[x] + 5;
1132
Program continues // Display the values in the array.
for (int x = 0; x < 10; x++) cout << table[x] << " "; cout << endl; // Use the built-in ++ operator on array elements. table[x]++; }
1133
Program Output
1134
Program 14-13 #include <iostream.h> #include "intarray.h"
void main(void) { IntArray table(10); // Store values in the array. for (int x = 0; x < 10; x++) table[x] = x; // Display the values in the array. cout << table[x] << " "; cout << endl; cout << “Now attempting to store a value in table[11]. table[11] = 0; }
1135
Program Output Now attempting to store a value in table[11]. ERROR: Subscript out of range.
1136
14.6 Object Conversion Special operator functions may be written to convert a class object to any other type. FeetInches::operator float(void) { float temp = feet; temp += (inches / 12.0); return temp; }
1137
Note: No return type is specified in the function header for the previous example. Because it is a FeetInches-to-float conversion function, it will always return a float.
1138
Program 14-13 Contents of feetinc6.h
#include <iostream.h> // Needed to overload << and >> #include <stdlib.h> // Needed for abs() #ifndef FEETINCHES_H #define FEETINCHES_H // A class to hold distances or measurements expressed // in feet and inches. class FeetInches { private: int feet; int inches; void simplify(void); // Defined in feetinc3.cpp
1139
Program continues public: FeetInches(int f = 0, int i = 0)
{ feet = f; inches = i; simplify(); } void setData(int f, int i) int getFeet(void) { return feet; } int getInches(void) { return inches; } FeetInches operator + (const FeetInches &); // Overloaded + FeetInches operator - (const FeetInches &); // Overloaded - FeetInches operator++(void); // Prefix ++ FeetInches operator++(int); // Postfix ++ int operator>(const FeetInches &); int operator<(const FeetInches &); int operator==(const FeetInches &);
1140
Program continues operator float(void);
operator int(void) // Truncates the Inches value { return feet; } friend ostream &operator<<(ostream &, FeetInches &); friend istream &operator>>(istream &, FeetInches &); }; #endif Contents of feetinc6.cpp #include "feetinc6.h" // Definition of member function Simplify. This function // checks for values in the Inches member greater than // twelve and less than zero. If such a value is found, // the numbers in Feet and Inches are adjusted to conform // to a standard feet & inches expression.
1141
Program continues void FeetInches::simplify(void) {
if (inches >= 12) feet += (inches / 12); // Integer division inches = inches % 12; } else if (Inches < 0) feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12);
1142
Program continues // Overloaded binary + operator.
FeetInches FeetInches::operator+(const FeetInches &right) { FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp; } // Overloaded binary - operator. FeetInches FeetInches::operator-(const FeetInches &right) temp.Inches = inches - right.inches; temp.feet = feet - right.feet;
1143
Program continues // Overloaded prefix ++ operator. Causes the Inches member to // be incremented. Returns the incremented object. FeetInches FeetInches::operator++(void) { ++inches; simplify(); return *this; } // Overloaded postfix ++ operator. Causes the Inches member to // be incremented. Returns the value of the object before the increment. FeetInches FeetInches::operator++(int) FeetInches temp(feet, inches); inches++; return temp;
1144
Program continues // Overloaded > operator. Returns 1 if the current object is // set to a value greater than that of Right. int FeetInches::operator>(const FeetInches &right) { if (feet > right.feet) return 1; else if (feet == right.feet && inches > right.inches) else return 0; } // Overloaded < operator. Returns 1 if the current object is // set to a value less than that of Right. int FeetInches::operator<(const FeetInches &right) if (feet < right.feet)
1145
Program continues else if (Feet == Right.Feet && Inches < Right.Inches) return 1; else return 0; } // Overloaded == operator. Returns 1 if the current object is // set to a value equal to that of Right. int FeetInches::operator==(const FeetInches &right) { if (feet == right.feet && inches == right.inches)
1146
Program continues // Conversion function to convert a FeetInches object to a float. FeetInches::operator float(void) { float temp = feet; temp += (inches / 12.0); return temp; } // Overloaded << operator. Gives cout the ability to // directly display FeetInches objects. ostream &operator<<(ostream &strm, FeetInches &obj) strm << obj.feet << " feet, " << obj.inches << " inches"; return strm;
1147
Program continues // Overloaded >> operator. Gives cin the ability to // store user input directly into FeetInches objects. istream &operator>>(istream &strm, FeetInches &obj) { cout << "Feet: "; strm >> obj.feet; cout << "Inches: " strm >> obj.inches; return strm; } Main program file, pr14-13.cpp // This program demonstrates the << and >> operators, // overloaded to work with the FeetInches class. #include <iostream.h> #include "feetinc5.h"
1148
Program continues void main(void) { FeetInches distance; float f;
int i; cout << "Enter a distance in feet and inches:\n "; cin >> distance; f = distance; i = distance; cout << "The value " << distance; cout << " is equivalent to " << f << " feet\n"; cout << "or " << i << " feet, rounded down.\n"; }
1149
Program Output with Example Input
Enter a distance in feet and inches: Feet: 8 [Enter] Inches: 6 [Enter] The value 8 feet, 6 inches is equivalent to 8.5 feet or 8 feet, rounded down.
1150
14.7 Creating a String Class
This section shows the use of a C++ class to create a string data type.
1151
The MyString class Memory is dynamically allocated for any string stored in a MyString object. Strings may be assigned to a MyString object with the = operator. One string may be concatenated to another with the += operator. Strings may be tested for equality with the == operator.
1152
MyString #ifndef MYSTRING_H #define MYSTRING_H
#include <iostream.h> #include <string.h> // For string library functions #include <stdlib.h> // For exit() function // MyString class. An abstract data type for handling strings. class MyString { private: char *str; int len; void memError(void); public: MyString(void) { str = NULL; len = 0; } MyString(char *); MyString(MyString &); // Copy constructor ~MyString(void) { if (len != 0) delete [] str; }
1153
MyString continues int length(void) { return len; }
char *getValue(void) { return str; }; MyString operator+=(MyString &); char *operator+=(const char *); MyString operator=(MyString &); char *operator=(const char *); int operator==(MyString &); int operator==(const char *); int operator!=(MyString &); int operator!=(const char *); int operator>(MyString &); int operator>(const char *); int operator<(const char *); int operator<(MyString &); int operator>=(MyString &); int operator<=(const char *); friend ostream &operator<<(ostream &, MyString &); friend istream &operator>>(istream &, MyString &); }; #endif
1154
Contents of mystring.cpp
#include "mystring.h" // Definition of member function MemError. // This function is called to terminate a program // if a memory allocation fails. void MyString::memError(void) { cout << "Error allocating memory.\n"; exit(0); } // Constructor to initialize the Str member // with a string constant. MyString::MyString(char *sptr) len = strlen(sptr); str = new char[len + 1]; if (str == NULL) memError(); strcpy(str, sptr);
1155
MyString continues // Copy constructor MyString MyString::operator=(MyString &right) { str = new char[right.length() + 1]; if (str == NULL) memError(); strcpy(str, right.getValue()); len = right.length(); }
1156
MyString continues // Overloaded = operator. Called when operand // on the right is another MyString object. // Returns the calling object. MyString MyString::operator=(MyString &right) { if (len != 0) delete [] str; str = new char[right.length() + 1]; if (str == NULL) memError(); strcpy(str, right.getValue()); len = right.length(); return *this; }
1157
MyString continues // Overloaded = operator. Called when operand // on the right is a string. // Returns the Str member of the calling object. char *MyString::operator=(const char *right) { if (len != 0) delete [] str; len = strlen(right); str = new char[len + 1]; if (str == NULL) memError(); strcpy(str, right); return str; }
1158
MyString continues // Overloaded += operator. Called when operand on the right is another // MyString object. Concatenates the Str member of Right to the Str member of // the calling object. Returns the calling object. MyString MyString::operator+=(MyString &right) { char *temp = str; str = new char[strlen(str) + right.length() + 1]; if (str == NULL) memError(); strcpy(str, temp); strcat(str, right.getvalue()); if (len != 0) delete [] temp; len = strlen(str); return *this; }
1159
MyString continues // Overloaded += operator. Called when operand on the right is a string. // Concatenates the Str member of Right to the Str member of the calling object. // Returns the Str member of the calling object. char *MyString::operator+=(const char *right) { char *temp = str; str = new char[strlen(str) + strlen(right) + 1]; if (str == NULL) memError(); strcpy(str, temp); strcat(str, right); if (len != 0) delete [] temp; return str; }
1160
MyString continues // Overloaded == operator. Called when the operand on the right is a MyString // object. Returns 1 if Right.Str is the same as Str. int MyString::operator==(MyString &right) { return !strcmp(str, right.getValue()); } // Overloaded == operator. Called when the operand on the right is a string. // Returns 1 if Right is the same as Str. int MyString::operator==(const char *right) return !strcmp(str, right);
1161
MyString continues // Overloaded != operator. Called when the operand on the right is a MyString // object. Returns 1 if Right.Str is not equal to Str. int MyString::operator!=(MyString &right) { return strcmp(str, right.getValue()); } // Overloaded != operator. Called when the operand on the right is a string. // Returns 1 if Right is not equal to Str. int MyString::operator!=(const char *right) return strcmp(str, right);
1162
MyString continues // Overloaded > operator. Called when the operand on the right is a MyString // object. Returns 1 if Right.Str is greater than Str. int MyString::operator>(MyString &right) { if (strcmp(str, right.getValue()) > 0) return 1; else return 0; }
1163
MyString continues // Overloaded > operator. Called when the operand on the right is a string. // Returns 1 if Right is greater than Str. int MyString::operator>(const char *right) { if (strcmp(str, right) > 0) return 1; else return 0; } // Overloaded < operator. Called when the operand on the right is a // MyString object. Returns 1 if Right.Str is less than Str. int MyString::operator<(MyString &right) if (strcmp(str, right.getValue()) < 0)
1164
MyString continues // Overloaded < operator. Called when the operand on the right is a string. // Returns 1 if right is less than str. int MyString::operator<(const char *right) { if (strcmp(str, right) < 0) return 1; else return 0; } // Overloaded >= operator. Called when the operand on the right is a // MyString object. Returns 1 if right.str is greater than or equal to str. int MyString::operator>=(MyString &right) if (strcmp(str, right.getValue()) >= 0)
1165
MyString continues // Overloaded >= operator. Called when the operand on the right is a // string. Returns 1 if right is greater than or equal to str. int MyString::operator>=(const char *right) { if (strcmp(str, right) >= 0) return 1; else return 0; } // Overloaded <= operator. Called when the operand on the right is a // MyString object. Returns 1 if right.str is less than or equal to str. int MyString::operator<=(MyString &right) if (strcmp(str, right.getValue()) <= 0)
1166
MyString continues // Overloaded <= operator. Called when the operand on the right is a // string. Returns 1 if right is less than or equal to str. int MyString::operator<=(const char *right) { if (strcmp(str, right) <= 0) return 1; else return 0; } // Overloaded stream insertion operator (<<). ostream &operator<<(ostream &strm, MyString &obj) strm << obj.str; return strm;
1167
MyString continues // Overloaded stream extraction operator (>>). istream &operator>>(istream &strm, MyString &obj) { strm.getline(obj.str); strm.ignore(); return strm; }
1168
Program 14-15 // This program demonstrates the MyString class. Be sure to // compile this program with mystring.cpp. #include <iostream.h> #include "mystring.h" void main(void) { MyString object1("This"), object2("is"); MyString object3("a test."); MyString object4 = object1; // Call copy constructor. MyString object5("is only a test."); char string1[] = "a test."; cout << "Object1: " << object1 << endl; cout << "Object2: " << object2 << endl; cout << "Object3: " << object3 << endl;
1169
Program continues cout << "Object4: " << object4 << endl; cout << "Object5: " << object5 << endl; cout << "String1: " << string1 << endl; object1 += " "; object1 += object2; object1 += object3; object1 += object4; object1 += object5; cout << "Object1: " << object1 << endl; }
1170
Program Output Object1: This Object2: is Object3: a test.
Object5: is only a test. String1: a test. Object1: This is a test. This is only a test.
1171
Program 14-16 // This program demonstrates the MyString class. Be sure to // compile this program with mystring.cpp. #include <iostream.h> #include "mystring.h" void main(void) { MyString name1("Billy"), name2("Sue"); MyString name3("joe"); MyString string1("ABC"), string2("DEF"); cout << "Name1: " << name1.getValue() << endl; cout << "Name2: " << name2.getValue() << endl; cout << "Name3: " << name3.getValue() << endl; cout << "String1: " << string1.getValue() << endl; cout << "String2: " << string2.getValue() << endl;
1172
Program continues if (name1 == name2)
cout << "Name1 is equal to Name2.\n"; else cout << "Name1 is not equal to Name2.\n"; if (name3 == "joe") cout << "Name3 is equal to joe.\n"; cout << "Name3 is not equal to joe.\n"; if (string1 > string2) cout << "String1 is greater than String2.\n"; cout << "String1 is not greater than String2.\n"; if (string1 < string2) cout << "String1 is less than String2.\n";
1173
Program continues cout << "String1 is not less than String2.\n";
if (string1 >= string2) cout << "String1 is greater than or equal to " << "String2.\n"; else cout << "String1 is not greater than or equal to " if (string1 >= "ABC") << "ABC.\n"; if (string1 <= string2) cout << "String1 is less than or equal to "
1174
Program continues else
cout << "String1 is not less than or equal to " << "String2.\n"; if (string2 <= "DEF") cout << "String2 is less than or equal to " << "DEF.\n"; cout << "String2 is not less than or equal to " }
1175
Program Output Name1: Billy Name2: Sue Name3: joe String1: ABC
String2: DEF Name1 is not equal to Name2. Name3 is equal to joe. String1 is not greater than String2. String1 is less than String2. String1 is not greater than or equal to String2. String1 is greater than or equal to ABC. String1 is less than or equal to String2. String2 is less than or equal to DEF.
1176
14.8 Object Composition Object composition occurs when a class contains an instance of another class. Creates a “has a” relationship between classes.
1177
Chapter 15 – Inheritance, Polymorphism, and Virtual Functions
1178
15.1 What is Inheritance? Inheritance allows a new class to be based on an existing class. The new class inherits all the member variables and functions of the class it is based on.
1179
Figure 15-1
1180
Figure 15-2
1181
Program 15-1 Contents of grade.h #ifndef GRADE_H #define GRADE_H
// Grade class declaration class Grade { private: char letter; float score; void calcGrade(void); public: void setScore(float s) { score = s; calcGrade();} float getScore(void) {return score; } char getLetter(void) { return letter; } }; #endif
1182
Program continues Contents of grade.cpp #include "grade.h"
// Definition of member function Grade::calcGrade void Grade::calcGrade() { if (score > 89) letter = 'A'; else if (score > 79) letter = 'B'; else if (score > 69) letter = 'C'; else if (score > 59) letter = 'D'; else letter = 'F'; }
1183
Program continues Contents of test.h #ifndef TEST_H #define TEST_H
#include "grade.h" // Must include Grade class declaration. // Test class declaration class Test : public Grade { private: int numQuestions; float pointsEach; int numMissed; public: Test(int, int); }; #endif
1184
Program continues Contents of test.cpp #include "test.h"
// Definition of Test class constructor // Parameters: q = Number of questions, m = number of // questions missed. Test::Test(int q, int m) { float numericGrade; numQuestions = q; numMissed = m; pointsEach = / numQuestions; numericGrade = (numMissed * pointsEach); setScore(numericGrade); }
1185
Contents of the main program pr15-1.cpp
Program continues Contents of the main program pr15-1.cpp #include <iostream.h> #include <iomanip.h> #include "test.h“ void main(void) { int questions, missed; cout << "How many questions are on the test? "; cin >> questions; cout << "How many questions did the student miss? "; cin >> missed; Test exam(questions, missed); cout.precision(2); cout << "The score is " << exam.getScore() << endl; cout << "The grade is " << exam.getLetter() << endl; }
1186
Program Output with Example Input
How many questions are on the test? 20 [Enter] How many questions did the student miss? 3 [Enter] The score is 85 The grade is B
1187
15.2 Protected Members and Class Access
Protected members of a base class are like private members, but they may be accessed by derived classes. The base class access specification determines how private, protected, and public base class members may be accessed by derived classes.
1188
Program 15-2 Contents of grade2.h #ifndef GRADE2_H #define GRADE2_H
// Grade class declaration class Grade { protected: char letter; float score; void calcGrade(void); public: void setScore(float s) { score = s; calcGrade(); } float getScore(void) {return score; } char getLetter(void) { return letter; } }; #endif
1189
Program continues Contents of grade2.cpp #include "grade2.h"
// Definition of member function Grade::calcGrade void Grade::calcGrade() { if (score > 89) letter = 'A'; else if (score > 79) letter = 'B'; else if (score > 69) letter = 'C'; else if (score > 59) letter = 'D'; else letter = 'F'; }
1190
Program continues Contents of test2.h #ifndef TEST2_H #define TEST2_H
#include "grade2.h" // Test class declaration class Test : public Grade { private: int numQuestions; float pointsEach; int numMissed; public: Test(int, int); void adjustScore(); }; #endif
1191
Program continues Contents of test2.cpp #include "test2.h"
// Definition of Test constructor. // Parameters: q = Number of questions, m = number of // questions missed. Test::Test(int q, int m) { float numericGrade; numQuestions = q; numMissed = m; pointsEach = / numQuestions; numericGrade = (numMissed * pointsEach); setScore(numericGrade); }
1192
Program continues // Definition of Test::adjustScore. If score is within // 0.5 points of the next whole point, it rounds the score up // and recalculates the letter grade. void Test::adjustScore() { if ((score - int(score)) >= 0.5) score += (score - int(score)); calcGrade(); }
1193
Contents of the main program, pr15-2.cpp
Program continues Contents of the main program, pr15-2.cpp // This program demonstrates a base class and a derived class #include <iostream.h> #include <iomanip.h> #include "test2.h“ void main(void) { int questions, missed; cout << "How many questions are on the test? "; cin >> questions; cout << "How many questions did the student miss? "; cin >> missed; // Declare a Test object Test exam(questions, missed); cout.precision(2);
1194
Program continues cout << "Unadjusted score: " << exam.getScore() << endl; cout << "Unadjusted grade: " << exam.getLetter() << endl; exam.adjustScore(); cout << "Adjusted score is: " << exam.getScore() << endl; cout << "Adjusted grade is: " << exam.getLetter() << endl; }
1195
Program Output with Example Input
How many questions are on the test? 200 [Enter] How many questions did the student miss? 21 [Enter] Unadjusted score: 89.5 Unadjusted grade: B Adjusted score is: 90 Adjusted grade is: A
1196
Table 15-1
1197
Table 15-1 continued
1198
Table 15-1 continued
1199
Figure 15-3
1200
15.3 Constructors and Destructors
The base class’s constructor is called before the derived class’s constructor. The destructors are called in reverse order, with the derived class’s destructor being called first.
1201
Program 15-3 // This program demonstrates the order in which base and
// derived class constructors and destructors are called. // For the sake of simplicity, all the class declarations // are in this file. #include <iostream.h> // BaseDemo class class BaseDemo { public: BaseDemo(void) // Constructor { cout << "This is the BaseDemo constructor.\n"; } ~BaseDemo(void) // Destructor { cout << "This is the BaseDemo destructor.\n"; } };
1202
Program continues class DeriDemo : public BaseDemo { public:
DeriDemo(void) //Constructor { cout << "This is the DeriDemo constructor.\n"; } ~DeriDemo(void) // Destructor { cout << "This is the DeriDemo destructor.\n"; } }; void main(void) cout << "We will now declare a DeriDemo object.\n"; DeriDemo object; cout << "The program is now going to end.\n"; }
1203
Program Output We will now declare a DeriDemo object.
This is the BaseDemo constructor. This is the DeriDemo constructor. The program is now going to end. This is the DeriDemo destructor. This is the BaseDemo destructor.
1204
Passing Arguments to Base Class Constructors
Assume a class called Cube is derived from a class called Rect. Here is how the constructor looks in Rect: Rect::Rect(float w, float l) { width = w; length = l; area = length * width; }
1205
Cube constructor: Cube::Cube(float wide, float long, float high) : Rect(wide, long) { height = high; volume = area * high; }
1206
General Form: <class name>::<class name>(parameter list) : <base class name> (parameter list) Note that the derived class constructor must take enough arguments to be able to pass to the base class constructor
1207
Program 15-4 Contents of rect.h #ifndef RECT_H #define RECT_H
// Rect class declaration class Rect { protected: float width; float length; float area; public: Rect(void) { width = length = area = 0.0; } Rect(float, float); float getArea(void) { return area; } float getLen(void) { return length; } float getWidth(void) { return width; } }; #endif
1208
Program continues Contents of rect.cpp #include "rect.h"
// Definition of Rect constructor. Rect::Rect(float w, float l) { width = w; length = l; area = width * length; }
1209
Program continues Contents of cube.h #ifndef CUBE_H #define CUBE_H
#include "rect.h" // Cube class declaration class Cube : public Rect { protected: float height; float volume; public: Cube(float, float, float); float getHeight(void) { return height; } float getVol(void) { return volume; } }; #endif
1210
Program continues Contents of cube.cpp #include "cube.h"
// Definition of Cube constructor. Cube::Cube(float wide, float long, float high) : Rect(wide, long) { height = high; volume = area * high; } Contents of the main program, pr15-4.cpp // This program demonstrates passing arguments to a base // class constructor. #include <iostream.h>
1211
Program continues void main(void) {
float cubeWide, cubeLong, cubeHigh; cout << "Enter the dimensions of a Cube:\n"; cout << “Width: "; cin >> cubeWide; cout << “Length: "; cin >> cubeLong; cout << “Height: "; cin >> cubeHigh; Cube holder(cubeWide, cubeLong, cubeHigh); cout << "Here are the Cube's properties:\n"; cout << “Width: " << holder.getWidth() << endl; cout << “Length: " << holder.getLen() << endl; cout << “Height: " << holder.getHeight() << endl; cout << “Base area: " << holder.getArea() << endl; cout << “Volume: " << holder.getVol() << endl; }
1212
Program Output with Example Input
Enter the dimensions of a Cube: Width: 10 [Enter] Length: 15 [Enter] Height: 12 [Enter] Here are the Cube's properties: Width: 10 Length: 15 Height: 12 Base area: 150 Volume: 1800
1213
15.4 Overriding Base Class Functions
A member function of a derived class may have the same name as a member function of a base class.
1214
Program 15-5 Contents of miledist.h #ifndef MILEDIST_H
#define MILEDIST_H // MileDist class declaration. class MileDist { protected: float miles; public: void setDist(float d) { miles = d; } float getDist(void) { return miles; } }; #endif
1215
Program continues Contents of ftdist.h #ifndef FTDIST_H
#define FTDIST_H #include "miledist.h" // FtDist class declaration/ class FtDist : public MileDist { protected: float feet; public: void setDist(float); float getDist(void) { return feet; } float getMiles(void) { return miles; } }; #endif
1216
Program continues Contents of ftdist.cpp
#include "ftdist.h" void FtDist::setDist(float ft) { feet = ft; MileDist::setDist(feet / 5280); // Call base class function } Contents of the main program, pr15-5.cpp // This program demonstrates a derived class with // functions that override base class functions. // NOTE: FTDIST.CPP must be compiled and linked with this // program. #include <iostream.h>
1217
Program continues void main(void) { FtDist feet; float ft;
cout << "Enter a distance in feet and I will convert it\n"; cout << "to miles: "; cin >> ft; feet.setDist(ft); cout.precision(1); cout.setf(ios::fixed); cout << feet.getDist(void) << " feet equals "; cout << feet.getMiles(void) << " miles.\n"; }
1218
Program Output with Example Input
Enter a distance in feet and I will convert it to miles: [Enter] 12600 feet equals 2.4 miles.
1219
Program 15-6 // This program demonstrates that when a derived class function // overrides a base class function, objects of the base class // still call the base class version of the function. #include <iostream.h> class Base { public: void showMsg(void) { cout << "This is the Base class.\n"; } }; class Derived : public Base { cout << "This is the Derived class.\n"; }
1220
Program continues void main(void) { Base b; Derived d; b.showMsg();
d.showMsg(); }
1221
Program Output This is the Base class. This is the Derived class.
1222
15.5 Polymorphism and Virtual Member Functions
A virtual member function in a base class expects to be overridden in a derived class
1223
Figure 15-4
1224
Program 15-7 Contents of miledis2.h #ifndef MILEDIS2_H
#define MILEDIS2_H // MileDist class declaration. class MileDist { protected: float miles; public: void setDist(float d) { miles = d; } float getDist(void) { return miles; } float Square(void) { return getDist() * getDist(); } }; #endif
1225
Program continues Contents of ftdist2.h #ifndef FTDIST2_H
#define FTDIST2_H #include "miledis2.h" // FtDist class declaration/ class FtDist : public MileDist { protected: float feet; public: void setDist(float); float getDist(void) { return feet; } float getMiles(void) { return miles; } }; #endif
1226
Program continues Contents of ftdist2.cpp
#include "ftdist2.h" void FtDist::setDist(float ft) { feet = ft; MileDist::setDist(feet / 5280); //Call base class function } Contents of the main program, PR15-7.CPP // This program demonstrates a base class with an improperly // overridden function. #include <iostream.h>
1227
Program continues void main(void) { FtDist feet; float ft;
cout << "Enter a distance in feet and I will convert it\n"; cout << "to miles: "; cin >> ft; feet.setDist(ft); cout.precision(1); cout.setf(ios::fixed); cout << feet.getDist(void) << " feet equals "; cout << feet.getMiles(void) << " miles.\n"; cout << feet.getDist(void) << " square feet equals "; cout << feet.Square(void) << " total feet.\n"; }
1228
Program Output with Example Input
Enter a distance in feet and I will convert it to miles: [Enter] 12600 feet equals 2.4 miles. 12600 square feet equals 5.7 total feet.
1229
Program 15-8 Contents of miledis3.h #ifndef MILEDIS3_H
#define MILEDIS3_H // MileDist class declaration. class MileDist { protected: float miles; public: void setDist(float d) { miles = d; } virtual float getDist(void) { return miles; } float Square(void) { return getDist() * getDist(); } }; #endif
1230
Program continues Contents of ftdist3.h #ifndef FTDIST3_H
#define FTDIST3_H #include "miledis3.h" // FtDist class declaration/ class FtDist : public MileDist { protected: float feet; public: void setDist(float); virtual float getDist(void) { return feet; } float getMiles(void) { return miles; } }; #endif
1231
Program continues Contents of ftdist3.cpp
#include "ftdist3.h" void FtDist::setDist(float ft) { feet = ft; MileDist::setDist(feet / 5280); // Call base class function } Contents of the main program, pr15-8.cpp // This program demonstrates a base class with an improperly // overriden function. #include <iostream.h> #include <iomanip.h>
1232
Program continues void main(void) { FtDist distObject; float ft;
cout << "Enter a distance in feet and I will convert it\n"; cout << "to miles: "; cin >> ft; distObject.setDist(ft); cout.precision(1); cout.setf(ios::fixed); cout << distObject.getDist(void) << " feet equals "; cout << distObject.getMiles(void) << " miles.\n"; cout << distObject.getDist(void) << " square feet equals "; cout << distObject.Square(void) << " total feet.\n"; }
1233
Program Output with Example Input
Enter a distance in feet and I will convert it to miles: [Enter] 12600 feet equals 2.4 miles. 12600 square feet equals total feet.
1234
15.6 Abstract Base Classes and Pure Virtual Functions
An abstract base class is not instantiated, but other classes are derived from it. A pure virtual function is a virtual member function of a base class that must be overridden.
1235
15.6 Abstract Base Classes and Pure Virtual Functions
A class becomes an abstract base class when it contains one or more pure virtual functions. A pure virtual function is a virtual member function declared in a manner similar to the following: virtual void showInfo(void) = 0;
1236
Contents of student.h #ifndef STUDENT_H #define STUDENT_H #include <string.h> // For strcpy class Student { protected: char name[51]; char id[21]; int yearAdmitted; int hoursCompleted; public: Student(void) // Constructor {name[0] = id[0] = yearAdmitted = hoursCompleted = 0; }
1237
void setName(char. n). { strcpy(name, n); }. void setID(char. i)
void setName(char *n) { strcpy(name, n); } void setID(char *i) { strcpy(id, i); } void setYearAdmitted(int y) { yearAdmitted = y; } virtual void setHours(void) = 0; // Pure virtual function virtual void showInfo(void) = 0; // Pure virtual function }; #endif
1238
Contents of csstudent.h
ifndef CSSTUDENT_H #define CSSTUDENT_H #include "student.h" class CsStudent : public Student { private: int mathHours; // Hours of math taken int csHours; // Hours of Computer Science taken int genEdHours; // Hours of general education taken public: void setMathHours(int mh) { mathHours = mh; } void setCsHours(int csh) { csHours = csh; } void setGenEdHours(int geh) { genEdHours = geh; }
1239
Contents of csstudent.cpp
void setHours(void) { hoursCompleted = genEdHours + mathHours + csHours; } void showInfo(void); // Defined in csstudent.cpp }; #endif Contents of csstudent.cpp #include <iostream.h> #include "csstudent.h“ void CsStudent::showInfo(void) { cout << "Name: " << name << endl; cout << "Student ID: " << id << endl; cout << "Year admitted: " << yearAdmitted << endl; cout << "Summary of hours completed:\n"; cout << "\tGeneral Education: " << genEdHours << endl; cout << "\tMath: " << mathHours << endl; cout << "\tComputer Science: " << csHours << endl << endl; cout << "\tTotal Hours Completed: " << hoursCompleted << endl; }
1240
Program 15-9 // This program demonstrates the CsStudent class, which i// derived from the abstract base class, Student. #include <iostream.h> #include "csstudent.h“ void main(void) { CsStudent student1; char chInput[51]; // Input buffer for entering C-strings. int intInput; // Input buffer for entering integers. cout << "Enter the following student information:\n"; // Set the student's name. cout << "Name: "; cin.getline(chInput, 51); student1.setName(chInput);
1241
// Set the student's ID number. cout << "Student ID: ";. cin
// Set the student's ID number. cout << "Student ID: "; cin.getline(chInput, 21); student1.setID(chInput); // Set the year admitted. cout << "Year admitted: "; cin >> intInput; student1.setYearAdmitted(intInput); // Set the # of general ed hours completed. cout << "Number of general ed hours completed: "; cin >> intInput; student1.setGenEdHours(intInput); // Set the # of math hours completed. cout << "Number of math hours completed: "; cin >> intInput; student1.setMathHours(intInput);
1242
// Set the # of computer science hours completed
// Set the # of computer science hours completed. cout << "Number of computer science hours completed: "; cin >> intInput; student1.setCsHours(intInput); // Total the hours entered. student1.setHours(); // Display the information provided. cout << "\nSTUDENT INFORMATION\n"; student1.showInfo(); }
1243
Program Output Enter the following student information: Name: Marty Stamey Student ID: 167W98337 Year admitted: 2000 Number of general ed hours completed: 12 Number of math hours completed: 9 Number of computer science hours completed: 18
1244
15.7 Base Class Pointers Pointer to a base class may be assigned the address of a derived class object. The pointer, however, will ignore any overrides the derived class performs
1245
Program 15-10 15.7 Base Class Pointers
// This program demonstrates the behavior of a base class pointer // when it is pointing to a derived class that overrides members // of the base class. // The class declarations are placed directly in the file for // simplicity. #include <iostream.h> class Base { public: void show(void) { cout << "This is from the Base class.\n"; } };
1246
Program continues class Derived : public Base { public:
void show(void) { cout << "This is from the Derived class.\n"; } }; void main(void) Base *bptr; Derived dObject; bptr = &dObject; bptr->show(); // Base class pointer, ignores override. }
1247
Program Output This is from the Base class
1248
15.8 Classes Derived from Derived Classes
A base class can also be derived from another class.
1249
Figure 15-5
1250
Table 15-2
1251
Program 15-11 Contents of inchdist.h #ifndef INCHDIST_H
#define INCHDIST_H #include "ftdist3.h" // Needed for FtDist class declaration. // InchDist class declaration class InchDist : public FtDist { protected: float inches; public: void setDist(float); float getDist(void) { return inches; } float getFeet(void) { return feet; } }; #endif
1252
Program continues Contents of inchdist.cpp
#include "inchdist.h" // Definition of setDist member of InchDist class. void InchDist::setDist(float in) { inches = in; FtDist::setDist(inches / 12); // Call base class function } Contents of the main program, pr15-11.cpp // This program demonstrates a derived class derived from another // derived class. // NOTE: INCHDIST.CPP and FTDIST.CPP must be compiled and linked // with this program. #include <iostream.h> #include <iomanip.h>
1253
Program continues void main(void) { InchDist inch; float in;
cout << "Enter a distance in inches and I will convert\n"; cout << "it to feet and miles: "; cin >> in; inch.setDist(in); cout.precision(1); cout.setf(ios::fixed); cout << inch.getDist() << " inches equals "; cout << inch.getFeet() << " feet.\n"; cout << inch.getMiles() << " miles.\n"; }
1254
Program Output with Example Input
Enter a distance in inches and I will convert it to feet and miles: [Enter] inches equals feet. inches equals 1.8 miles.
1255
15.9 Multiple Inheritance Multiple inheritance is when a derived class has two or more base classes
1256
Figure 15-6
1257
Program 15-12 Contents of date.h #ifndef DATE_H #define DATE_H
class Date { protected: int day; int month; int year; public: Date(int d, int m, int Y) { day = d; month = m; year = Y; } int getDay(void) { return day; } int getMonth(void) { return month; } int getYear(void) { return year; } }; #endif
1258
Program continues Contents of time.h #ifndef TIME_H #define TIME_H
class Time { protected: int hour; int min; int sec; public: Time(int h, int m, int s) { hour = h; min = m; sec = s; } int getHour(void) { return hour; } int getMin(void) { return min; } int getSec(void) { return sec; } }; #endif
1259
Program continues Contents of datetime.h #ifndef DATETIME_H
#define DATETIME_H #include "date.h" // For Date class declaration #include "time.h" // For Time class declaration class DateTime : public Date, public Time { protected: char dTString[20]; public: DateTime(int, int, int, int, int, int); void getDateTime(char *str) { strcpy(str, dTString); } }; #endif
1260
Program continues Contents of datetime.cpp #include “datetime.h”
#include <string.h> // For strcpy and strcat #include <stdlib.h> // For itoa void DateTime::DateTime(int dy, int mon, int yr, int hr, int mt, int sc) : Date(dy, mon, yr), Time(hr, mt, sc) { char temp[10]; // Temporary work area for itoa() // Store the date in dTString, in the form MM/DD/YY strcpy(dTString, itoa(getMonth(), temp, 10)); strcat(dTString, “/”); strcat(dTString, itoa(getDay(), temp, 10)); strcat(dTString, itoa(getYear(), temp, 10)); strcat(dTString, “ “);
1261
Program continues Contents of the main program, pr15-12.cpp
// Store the time in dtString, in the form HH:MM:SS strcpy(dTString, itoa(getHour(), temp, 10)); strcat(dTString, “:”); strcat(dTString, itoa(getMin(), temp, 10)); strcat(dTString, itoa(getSec(), temp, 10)); } Contents of the main program, pr15-12.cpp // This program demonstrates a class with multiple inheritance. // NOTE: datetime.cpp must be compiled and linked with this // file. #include <iostream.h> #include “datetime.h”
1262
Program continues void main(void) { char formatted[20];
DateTime pastDay(4, 2, 60, 5, 32, 27); pastDay.getDateTime(formatted); cout << formatted << endl; }
1263
Program Output 4/2/60 5:32:27
1264
Chapter 16 – Exceptions, Templates, and the Standard Template Library (STL)
Exceptions are used to signal errors or unexpected events that occur while a program is running. We have checked for errors before by placing if statements that checked for the condition or by using assert statements.
1265
Exceptions (cont) An exceptional condition is a value or an object that signals an error. When the error occurs, an exception is “thrown.”
1266
Throwing an Exception Rational::Rational ( int numerator, int denominator ) { if ( denominator == 0 ) throw "ERROR: Cannot divide by zero.\n"; this->numerator = numerator; this->denominator = denominator; } // divide
1267
Throw The line containing a throw statement is called the throw point.
When a throw statement is executed, control is passed to an exception handler. When an exception is thrown by a function, the function aborts. Any type can be “thrown”
1268
Handling an Exception An exception is handled by a try/catch construct. The try block contains a block of code that may directly or indirectly cause an exception to be thrown. The catch block contains a block of code that handles the exception.
1269
Example Exception Handler
try { Rational q = Rational( num1, num2 ); cout << q << endl; } // try catch ( char *exceptionString ) cout << exceptionString; } // catch
1270
Handling an Exception (cont)
If divide throws an exception, the exception is caught by the catch statement. The type of the parameter to the catch statement must be the same as in the throw statement (or class from which it is derived). Execution continues after the try/catch statement, unless the catch statement does something else.
1271
Uncaught Exceptions Ways for uncaught exceptions:
No catch statement with a parameter of the correct data type. The exception is thrown outside a try statement. In either case, the exception causes the program to abort.
1272
More on Exceptions Exceptions can be put in classes. This allows us to do more with them. We can have multiple exception classes. Exception classes can have parameters that allow information to be returned.
1273
IntMain.cpp – Program (cont)
in getInput… throw OutOfRange( input ); in main… try { userValue = range.getInput(); cout << "You entered " << uservalue << endl; } // try catch ( IntRange::OutOfRange ex ) { cout << "That value " << ex.value << " is out of range." << endl; } // catch cout << "End of program." << endl; } // main
1274
Class for exceptions class BadTrait{ private: string msg; public:
BadTrait(string errorMsg, int val){ char str[10]; itoa(val,str,10); // integer, string to convert to, number sys msg = errorMsg+str; } string getMsg(){ return msg;} };
1275
How to Throw // add newEle to set only if it is a legal element
Set &Set::operator+=(int newEle){ if (newEle <memberMax && newEle >=0) member[newEle]=true; else throw BadTrait("Error: Adding element which is out of range " , newEle); return *this; }
1276
How to catch try{ Traits me; me+=4; me += 5;me +=11; me +=27;
}catch (BadTrait b){ cout<< b.getMsg() << endl;}
1277
Unwinding the Stack When an exception is thrown, the function immediately terminates. If that function was called by another function, then the calling function terminates as well. This process continues. This is called unwinding the stack.
1278
Dynamic Arrays Suppose I wanted an array that changed in size.
How would I implement that? What operations would I expect to have?
1279
Magic Genie Give me what I want. Would I have any concerns?
1280
Introduction to the Standard Template Library (STL)
The Standard Template Library contains many templates for useful algorithms and data structures. template: a stencil, pattern or overlay used in graphic arts Is a template complete? The Magic Genie
1281
Abstract Data Types – what is an abstract data type?
The most important data structures in STL are containers and iterators: Container – a class that stores data and organizes it in some fashion. Iterator – similar to a pointer and is used to access the individual data elements in a container. Why do we need iterators at all?
1282
Container Classes Sequence – organizes data in a sequential fashion similar to an array. “Give me item 7” Associative – uses keys to rapidly access elements in the data structure. “Give me the scissors”
1283
Sequence Containers – Has an order
Container Name Description vector An expandable array. Values may be added to or removed from the end (push back) or middle (insert). deque Like a vector, but also allows values to be added to or removed from the front. list A doubly-linked list of data elements. Values may be inserted in or removed from any position. They differ in the underlying representation.
1284
Weak Sauce Genie Makes you give him more information. “What are you going to do with it?” Which is better for racing - a general purpose bike or a racing bike? This genie has an attitude. He doesn’t give it the way you want it, but just the way he wants.
1285
Associative Containers – stored by value
Container Name Description set Stores a set of keys. No duplicate values are allowed. multiset Stores a set of keys. Duplicates are allowed. map Maps a set of keys to data elements. Only one key per data element is allowed. Duplicates are not allowed. multimap Maps a set of keys to data elements. Many keys per data element are allowed. Duplicates are allowed.
1286
So how do associative containers work?
Come back next semester…
1287
Using Vectors – Program
#include <iostream> #include <vector> #include <algorithm> using namespace std; void doubleValue ( int &val ) { val *= 2; } // doubleValue void main ( void ) { vector<int> numbers; vector<int>::iterator iter; // Notice scope resolution operator ::
1288
Using Vectors – Program (cont)
for ( int x = 0; x < 10; x++ ) numbers.push_back( x ); cout << “The numbers in the vector are:\n”; for ( iter = numbers.begin(); iter != numbers.end(); iter++ ) cout << *iter << endl; cout << endl; for_each ( numbers.begin(), numbers.end(), doubleValue ); cout << “The numbers again are:\n”; } // main
1289
“for each” acts like… for_each(Iterator first, Iterator last, Function f) for ( ; first!=last; ++first ) f(*first);
1290
Visit with your neighbor
Create a vector of strings. Add the lines of your favorite poem to the vector. Print them out assuming you really can’t remember how many lines you put in.
1291
Visit with your neighbor
Create a vector of integers. Put in multiples of 5. Print them out, backwards USING ITERATORS.
1292
What do you think this does?
const int SIZE=5; vector<vector<int> > items ( SIZE, vector<int> ( SIZE ) ); for (int i=0; i < SIZE; i++) for (int j=0; j < SIZE; j++) items[i][j]=i+j; for(int ii=0; ii < SIZE; ii++) { for(int jj=0; jj < SIZE; jj++) cout << items[ii][jj] << " "; } cout << endl;
1293
What do you think this does?
int k=0; vector<vector<int> > things ; for (int i=0; i < SIZE; i++) { things.push_back(vector<int>()); for (int j=0; j < SIZE; j++) things[i].push_back(k++); } for(int ii=0; ii < SIZE; ii++) { for(int jj=0; jj < SIZE; jj++) cout << setw(3) << things[ii][jj] << " "; cout << endl;
1294
What do you think this does?
int num_of_col = 5; int num_of_row = 9; const char TREE = 'T'; const char BURNING = '*'; const char EMPTY = ' '; vector< vector<char> > forest; //now we have an empty 2D-matrix of size (0,0). Resizing it with one single command forest.resize( num_of_row , vector<char>( num_of_col , TREE ) ); for(int ii=0; ii < num_of_row; ii++) { for(int jj=0; jj < num_of_col; jj++) cout << forest[ii][jj] ; } cout << endl;
1295
Function Templates A function template is a “generic” function that can work with any data type. The programmer writes the specifications of the function, but substitutes parameters for data types. Given the examples we did for vectors. Can you think of a generic function we may want?
1296
When the compiler encounters a call to the function, it generates code to handle the specific data type(s) used in the call. We call this inefficient, right? This is not like inheritance. Tell me the difference.
1297
Template Example We want a function that prints out the values of an array. This function should work with arrays of type int, float, char, or string. In a perfect world (where all these types descended from the same base type), we could use inheritance to make this happen.
1298
First, do it for one type – at your seats
We want a function that prints out the values of an array. Let’s print out values ten to a line.
1299
printArray.cpp – Program
#include <iostream> #include <string> using namespace std; template< class T> void printArray ( const T *array, const int size ) { for ( int i = 0; i < size; i++ ) { if ( !( i % 10 ) ) cout << endl; cout << array[i] << " "; } // for } // printArray
1300
printArray.cpp – Program (cont)
void main ( void ) { const int aSize = 5, bSize = 7, cSize = 6, dSize = 3; int a[ aSize ] = { 1, 2, 3, 4, 5 }; float b[ bSize ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; char c[ cSize ] = "Hello"; string d[ dSize ] = { "I", "love", "CS" }; printArray( a, aSize ); printArray( b, bSize ); printArray( c, cSize ); printArray( d, dSize ); } // main
1301
Generic swap Suppose we wanted a generic swap.
First do it for one type – at your seats.
1302
Generic swap Suppose we wanted a generic swap.
template <class T> void swap ( T &var1, T &var2 ) { T temp; temp = var1; var1 = var2; var2 = temp; } // swap
1303
Suppose we wanted a generic Max function
Try it at your seats
1304
Suppose we want a generic Max function
template <class T> T maximum(T a, T b) { return a > b ? a : b ; // Familiar operator? } void main() { cout << "max(10, 15) = " << maximum(10, 15) << endl ; cout << "max('k', 's') = " << maximum('k', 's') << endl ; cout << "max(10.1, 15.2) = " << maximum(10.1, 15.2) << endl ;
1305
Template with Multiple Types
template <class T1, class T2> void swap ( T1 &var1, T2 &var2 ) { T1 temp; temp = var1; var1 = (T1)var2; var2 = (T2)temp; } // swap
1306
Operators in Template If arithmetic or relational operators are used in templates, they must be defined for the different types of the templates actually passed in. If the operators are not defined for a particular type, the compiler generates an error.
1307
Class Templates Templates may also be used to create generic classes and abstract data types. Class templates allow you to create one general version of a class without having to duplicate code to handle multiple data types.
1308
Generic Class Suppose you wanted to have a class that held a collection of objects. We want this class to work with different data types. We could create a different class for each data type, but there is a better solution. We will look at a class template.
1309
SimpleVector.h – Program
template <class T> class SimpleVector { private: T *v; int arraySize; public: SimpleVector ( void ) { v = NULL; arraySize = 0; } ; SimpleVector ( int ); SimpleVector ( const SimpleVector & ); ~SimpleVector ( void ); int getSize ( void ) { return arraySize; }; T &operator[] ( const int & ); }; // SimpleVector
1310
SimpleVector.cpp – Program
template <class T> SimpleVector<T>::SimpleVector ( int s ) { arraySize = s; v = new T [ s ]; assert( v); for ( int i = 0; i < arraySize; i++ ) v[i]= 0; } // SimpleVector::SimpleVector SimpleVector<T>::~SimpleVector ( void ) { if ( arraySize > 0 ) delete [] v; } // SimpleVector::~SimpleVector void main() { SimpleVector<int> mine(5); cout << mine.getSize() << endl; }
1311
Declaring Objects of Class Templates
The declaration of class templates is a little different. Consider the following examples: SimpleVector<int> intTable ( 10 ); SimpleVector<float> floatTable ( 10 ); In these, the parameter inside the angle brackets replaces the T in the previous declarations.
1312
At your seats Try adding a new function to print out the contents of the simple vector
1313
void printAll(void); template <class T>
void SimpleVector<T>::printAll(void) { cout << "contents:"; for (int i=0 ;i < arraySize; i++) cout << v[i] << " "; cout << endl; }
1314
Class Templates and Inheritance
#ifndef SEARCHABLEVECTOR_H #define SEARCHABLEVECTOR_H #include “SimpleVector.h” template <class T> class SearchableVector : public SimpleVector<T> { public: SearchableVector ( ) : SimpleVector<T>( ) { } SearchableVector ( int s ) : SimpleVector<T>( s ) { } SearchableVector ( SearchableVector & ); int findItem ( T ); }; // SearchableVector
1315
Chapter 17 Linked Lists
1316
17.1 Introduction to the Linked List ADT
A linked list is a series of connected nodes, where each node is a data structure. A linked list can grow or shrink in size as the program runs
1317
Advantages of Linked Lists over Arrays and vectors
A linked list can easily grow or shrink in size. Insertion and deletion of nodes is quicker with linked lists than with vectors.
1318
The composition of a Linked List
Each node in a linked list contains one or more members that represent data. In addition to the data, each node contains a pointer, which can point to another node.
1319
The composition of a Linked List
A linked list is called "linked" because each node in the series has a pointer that points to the next node in the list.
1320
Declarations First you must declare a data structure that will be used for the nodes. For example, the following struct could be used to create a list where each node holds a float: struct ListNode { float value; struct ListNode *next; };
1321
Declarations The next step is to declare a pointer to serve as the list head, as shown below. ListNode *head; Once you have declared a node data structure and have created a NULL head pointer, you have an empty linked list. The next step is to implement operations with the list.
1322
17.2 Linked List Operations
We will use the following class declaration (on the next slide), which is stored in FloatList.h.
1323
class FloatList { private:. // Declare a structure for the list
class FloatList { private: // Declare a structure for the list struct ListNode { float value; struct ListNode *next; }; ListNode *head; // List head pointer public: FloatList(void) // Constructor { head = NULL; } ~FloatList(void); // Destructor void appendNode(float); void insertNode(float); void deleteNode(float); void displayList(void); };
1324
Appending a Node to the List
To append a node to a linked list means to add the node to the end of the list. The pseudocode is shown below. The C++ code follows. Create a new node. Store data in the new node. If there are no nodes in the list Make the new node the first node. Else Traverse the List to Find the last node. Add the new node to the end of the list. End If.
1325
void FloatList::appendNode(float num) {. ListNode. newNode,. nodePtr;
void FloatList::appendNode(float num) { ListNode *newNode, *nodePtr; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; newNode->next = NULL; // If there are no nodes in the list // make newNode the first node if (!head) head = newNode; else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; } }
1326
Program 17-1 // This program demonstrates a simple append // operation on a linked list. #include <iostream.h> #include "FloatList.h” void main(void) { FloatList List; list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); } (This program displays no output.)
1327
Stepping Through the Program
The head pointer is declared as a global variable. head is automatically initialized to 0 (NULL), which indicates that the list is empty. The first call to appendNode passes 2.5 as the argument. In the following statements, a new node is allocated in memory, 2.5 is copied into its value member, and NULL is assigned to the node's next pointer.
1328
newNode = new ListNode;. newNode->value = num;
newNode = new ListNode; newNode->value = num; newNode->next = nULL;
1329
The next statement to execute is the following if statement.
if (!head) head = newNode; There are no more statements to execute, so control returns to function main.
1330
In the second call to appendNode, 7. 9 is passed as the argument
In the second call to appendNode, 7.9 is passed as the argument. Once again, the first three statements in the function create a new node, store the argument in the node's value member, and assign its next pointer to NULL.
1331
Since head no longer points to NULL, the else part of the if statement executes:
else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; }
1332
nodePtr is already at the end of the list, so the while loop immediately terminates. The last statement, nodePtr->next = newNode; causes nodePtr->next to point to the new node. This inserts newNode at the end of the list.
1333
The third time appendNode is called, 12. 6 is passed as the argument
The third time appendNode is called, 12.6 is passed as the argument. Once again, the first three statements create a node with the argument stored in the value member.
1334
next, the else part of the if statement executes
next, the else part of the if statement executes. As before, nodePtr is made to point to the same node as head.
1335
Since nodePtr->next is not NULL, the while loop will execute
Since nodePtr->next is not NULL, the while loop will execute. After its first iteration, nodePtr will point to the second node in the list.
1336
The while loop's conditional test will fail after the first iteration because nodePtr->next now points to NULL. The last statement, nodePtr->next = newNode; causes nodePtr->next to point to the new node. This inserts newNode at the end of the list The figure above depicts the final state of the linked list.
1337
Traversing the List The displayList member function traverses the list, displaying the value member of each node. The following pseudocode represents the algorithm. The C++ code for the member function follows on the next slide. Assign List head to node pointer. While node pointer is not NULL Display the value member of the node pointed to by node pointer. Assign node pointer to its own next member. End While.
1338
void FloatList::displayList(void) {. ListNode. nodePtr;
void FloatList::displayList(void) { ListNode *nodePtr; nodePtr = head; while (nodePtr) { cout << nodePtr->value << endl; nodePtr = nodePtr->next; } }
1339
Program 17-2 // This program calls the displayList member function. // The funcion traverses the linked list displaying // the value stored in each node. #include <iostream.h> #include "FloatList.h" void main(void) { FloatList List; list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); list.displayList(); }
1340
Program 17-2 Output
1341
Inserting a Node Using the listNode structure again, the pseudocode on the next slide shows an algorithm for finding a new node’s proper position in the list and inserting there. The algorithm assumes the nodes in the list are already in order.
1342
Create a new node. Store data in the new node
Create a new node. Store data in the new node. If there are no nodes in the list Make the new node the first node. Else Find the first node whose value is greater than or equal the new value, or the end of the list (whichever is first). Insert the new node before the found node, or at the end of the list if no node was found. End If.
1343
The entire insertNode function begins on the next slide.
The code for the traversal algorithm is shown below. (As before, num holds the value being inserted into the list.) // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is less // than num. while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } The entire insertNode function begins on the next slide.
1344
Continued on next slide…
void FloatList::insertNode(float num) { ListNode *newNode, *nodePtr, *previousNode; // Allocate a new node & store Num newNode = new ListNode; newNode->value = num; // If there are no nodes in the list // make newNode the first node if (!head) { head = newNode; newNode->next = NULL; } else // Otherwise, insert newNode. { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is less // than num. while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } Continued on next slide…
1345
Continued from previous slide.
// If the new mode is to be the 1st in the list, // insert it before all other nodes. if (previousNode == NULL) { head = newNode; newNode-> = nodePtr; } else { previousNode->next = newNode; newNode->next = nodePtr; } } }
1346
Program 17-3 // This program calls the displayList member function. // The function traverses the linked list displaying // the value stored in each node. #include <iostream.h> #include "FloatList.h” void main(void) { FloatList list; // Build the list list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); // Insert a node in the middle // of the list. list.insertNode(10.5); // Dispay the list list.displayList(); }
1347
Program 17-3 Output
1348
In insertNode, a new node is created and the function argument is copied to its value member. Since the list already has nodes stored in it, the else part of the if statement will execute. It begins by assigning nodePtr to head.
1349
Since nodePtr is not NULL and nodePtr->value is less than num, the while loop will iterate. During the iteration, previousNode will be made to point to the node that nodePtr is pointing to. nodePtr will then be advanced to point to the next node.
1350
Once again, the loop performs its test
Once again, the loop performs its test. Since nodePtr is not NULL and nodePtr->value is less than num, the loop will iterate a second time. During the second iteration, both previousNode and nodePtr are advanced by one node in the list.
1351
This time, the loop's test will fail because nodePtr is not less than num. The statements after the loop will execute, which cause previousNode->next to point to newNode, and newNode->next to point to nodePtr. If you follow the links, from the head pointer to the NULL, you will see that the nodes are stored in the order of their value members.
1352
Deleting a Node Deleting a node from a linked list requires two steps:
Remove the node from the list without breaking the links created by the next pointers Deleting the node from memory The deleteNode function begins on the next slide.
1353
Continued on next slide…
void FloatList::deleteNode(float num) { ListNode *nodePtr, *previousNode; // If the list is empty, do nothing. if (!head) return; // Determine if the first node is the one. if (head->value == num) { nodePtr = head->next; delete head; head = nodePtr; } Continued on next slide…
1354
Continued from previous slide.
else { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is // not equal to num. while (nodePtr != NULL && nodePtr->value != num) { previousNode = nodePtr; nodePtr = nodePtr->next; } // Link the previous node to the node after // nodePtr, then delete nodePtr. previousNode->next = nodePtr->next; delete nodePtr; } }
1355
Program 17-4 Continued on next slide…
// This program demonstrates the deleteNode member function #include <iostream.h> #include "FloatList.h“ void main(void) { FloatList list; // Build the list list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); cout << "Here are the initial values:\n"; list.displayList(); cout << endl; cout << "Now deleting the node in the middle.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(7.9); list.displayList(); cout << endl; Continued on next slide…
1356
Continued from previous slide.
cout << "Now deleting the last node.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(12.6); list.displayList(); cout << endl; cout << "Now deleting the only remaining node.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(2.5); list.displayList(); }
1357
Program Output Here are the initial values: 2. 5 7. 9 12
Program Output Here are the initial values: Now deleting the node in the middle. Here are the nodes left Now deleting the last node. Here are the nodes left Now deleting the only remaining node. Here are the nodes left.
1358
Look at the else part of the second if statement
Look at the else part of the second if statement. This is where the function will perform its action since the list is not empty, and the first node does not contain the value 7.9. Just like insertNode, this function uses nodePtr and previousNode to traverse the list. The while loop terminates when the value 7.9 is located. At this point, the list and the other pointers will be in the state depicted in the figure below.
1359
next, the following statement executes.
previousNode->next = nodePtr->next; The statement above causes the links in the list to bypass the node that nodePtr points to. Although the node still exists in memory, this removes it from the list. The last statement uses the delete operator to complete the total deletion of the node.
1360
Destroying the List The class's destructor should release all the memory used by the list. It does so by stepping through the list, deleting each node one-by-one. The code is shown on the next slide.
1361
FloatList::~FloatList(void) { ListNode *nodePtr, *nextNode;
nodePtr = head; while (nodePtr != NULL) { nextNode = nodePtr->next; delete nodePtr; nodePtr = nextNode; } } Notice the use of nextNode instead of previousNode. The nextNode pointer is used to hold the position of the next node in the list, so it will be available after the node pointed to by nodePtr is deleted.
1362
17.3 A Linked List Template Continued on next slide…
#ifndef LINKEDLIST_H #define LINKEDLIST_H template <class T> class LinkedList { private: // Declare a structure for the list struct ListNode { T value; struct ListNode *next; }; ListNode *head; // List head pointer Continued on next slide…
1363
Continued on next slide…
public: LinkedList(void) // Constructor { head = NULL; } ~LinkedList(void); // Destructor void appendNode(T); void insertNode(T); void deleteNode(T); void displayList(void); }; // appendNode appends a node containing the // value pased into num, to the end of the list. template <class T> void LinkedList<T>::AppendNode(T num) { ListNode *newNode, *nodePtr; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; newNode->next = NULL; Continued on next slide…
1364
Continued on next slide…
// If there are no nodes in the list // make newNode the first node if (!head) head = newNode; else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; } } Continued on next slide…
1365
Continued on next slide…
// DisplayList shows the value // stored in each node of the linked list // pointed to by head. template <class T> void LinkedList<T>::DisplayList(void) { ListNode *nodePtr; nodePtr = head; while (nodePtr) { cout << nodePtr->value << endl; nodePtr = nodePtr->next; } } Continued on next slide…
1366
Continued on next slide…
// The insertNode function inserts a node with // num copied to its value member. template <class T> void LinkedList<T>::insertNode(T num) { ListNode *newNode, *nodePtr, *previousNode; // Allocate a new node & store Num newNode = new ListNode; newNode->value = num; // If there are no nodes in the list // make newNode the first node if (!head) { head = newNode; newNode->next = NULL; } Continued on next slide…
1367
Continued on next slide…
else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is less // than num. while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } // Insert the node after the one pointed to // by previousNode and before the one pointed to // by nodePtr. previousNode->next = newNode; newNode->next = nodePtr; } } Continued on next slide…
1368
Continued on next slide…
// The deleteNode function searches for a node // with Num as its value. The node, if found, is // deleted from the list and from memory. template <class T> void LinkedList<T>::deleteNode(T num) { ListNode *nodePtr, *previousNode; // If the list is empty, do nothing. if (!head) return; // Determine if the first node is the one. if (head->value == num) { nodePtr = head->next; delete head; head = nodePtr; } Continued on next slide…
1369
Continued on next slide…
else { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is // not equal to num. while (nodePtr != NULL && nodePtr->value != num) { previousNode = nodePtr; nodePtr = nodePtr->next; } // Link the previous node to the node after // nodePtr, then delete nodePtr. previousNode->next = nodePtr->next; delete nodePtr; } } Continued on next slide…
1370
// Destructor // This function deletes every node in the list
// Destructor // This function deletes every node in the list. template <class T> LinkedList<T>::~LinkedList(void) { ListNode *nodePtr, *nextNode; nodePtr = head; while (nodePtr != NULL) { nextNode = nodePtr->next; delete nodePtr; nodePtr = nextNode; } } #endif
1371
Program 17-5 Continued on next slide…
// This program demonstrates the linked list template. #include <iostream.h> #include "LinkedList.h“ void main(void) { LinkedList<int> list; // Build the list list.appendNode(2); list.appendNode(4); list.appendNode(6); cout << "Here are the initial values:\n"; list.displayList(); cout << endl; Continued on next slide…
1372
cout << "Now inserting the value 5. \n";. list. insertNode(5);
cout << "Now inserting the value 5.\n"; list.insertNode(5); cout << "Here are the nodes now.\n"; list.displayList(); cout << endl; cout << "Now deleting the last node.\n"; list.deleteNode(6); cout << "Here are the nodes left.\n"; list.displayList(); }
1373
Program Output Here are the initial values: Now inserting the value 5. Here are the nodes now Now deleting the last node. Here are the nodes left
1374
17.4 Variations of the Linked List
The Doubly-Linked List
1375
17.4 Variations of the Linked List
The Circular Linked List
1376
17.5 The STL list Container The list container, found in the Standard Template Library, is a template version of a doubly linked list. STL lists can insert elements, or add elements to their front quicker than vectors can, because lists do not have to shift the other elements. lists are also efficient at adding elements at their back because they have a built-in pointer to the last element in the list (no traversal required).
1377
Member Function Examples & Description
back cout << list.back() << endl; The back member function returns a reference to the last element in the list. erase list.erase(iter); list.erase(firstIter, lastIter) The first example causes the list element pointed to by the iterator iter to be removed. The second example causes all of the list elements from firstIter to lastIter to be removed. empty if (list.empty()) The empty member function returns true if the list is empty. If the list has elements, it returns false.
1378
Member Function. Examples & Description end. iter = list. end();
Member Function Examples & Description end iter = list.end(); end returns a bi-directional iterator to the end of the list. front cout << list.front() << endl; front returns a reference to the first element of the list. insert list.insert(iter, x) The insert member function inserts an element into the list. The example shown above inserts an element with the value x, just before the element pointed to by iter. merge list1.merge(list2); merge inserts all the items in list2 into list1. list1 is expanded to accommodate the new elements plus any elements already stored in list1. merge expects both lists to be sorted. When list2 is inserted into list1, the elements are inserted into their correct position, so the resulting list is also sorted.
1379
Member Function. Examples & Description pop_back. list. pop_back();
Member Function Examples & Description pop_back list.pop_back(); pop_back removes the last element of the list. pop_front list.pop_front(); pop_front removes the first element of the list. push_back list.push_back(x); push_back inserts an element with value x at the end of the list. push_front list.push_front(x); push_front inserts an element with value x at the beginning of the list. reverse list.reverse(); reverse reverses the order in which the elements appear in the list.
1380
Member Function. Examples & Description size()
Member Function Examples & Description size() Returns the number of elements in the list. swap list1.swap(List2) The swap member function swaps the elements stored in two lists. For example, assuming list1 and list2 are lists, the statement shown above will exchange the values in the two. unique list.unique(); unique removes any element that has the same value as the element before it.
1381
Program 17-6 Continued on next slide…
// This program demonstrates the STL list container. #include <iostream.h> #include <list> // Include the list header using namespace std; // Required by some compilers void main(void) { list<int> myList; list<int>::iterator iter; // Add values to the list for (int x = 0; x < 100; x += 10) myList.push_back(x); // Display the values for (iter = myList.begin(); iter != myList.end(); iter++) cout << *iter << " "; cout << endl; Continued on next slide…
1382
// Now reverse the order of the elements. myList. reverse();
// Now reverse the order of the elements myList.reverse(); // Display the values again for (iter = myList.begin(); iter != myList.end(); iter++) cout << *iter << " "; cout << endl; } Program Output
1383
Chapter 18 Stacks and Queues
1384
18.1 Introduction to the Stack ADT
A stack is a data structure that stores and retrieves items in a last-in-first-out (LIFO) manner.
1385
Applications of Stacks
Computer systems use stacks during a program’s execution to store function return addresses, local variables, etc. Some calculators use stacks for performing mathematical operations.
1386
Static and Dynamic Stacks
Static Stacks Fixed size Can be implemented with an array Dynamic Stacks Grow in size as needed Can be implemented with a linked list
1387
Stack Operations Push Pop
causes a value to be stored in (pushed onto) the stack Pop retrieves and removes a value from the stack
1388
The Push Operation Suppose we have an empty integer stack that is capable of holding a maximum of three values. With that stack we execute the following push operations. push(5); push(10); push(15);
1389
The state of the stack after each of the push operations:
1390
The Pop Operation Now, suppose we execute three consecutive pop operations on the same stack:
1391
Other Stack Operations
isFull: A Boolean operation needed for static stacks. Returns true if the stack is full. Otherwise, returns false. isEmpty: A Boolean operation needed for all stacks. Returns true if the stack is empty. Otherwise, returns false.
1392
The IntStack Class Table 18-1: Member Variables
Member Variable Description stackArray stackArray A pointer to int. When the constructor is executed, it uses stackArray to dynamically allocate an array for storage. stackSize An integer that holds the size of the stack. top An integer that is used to mark the top of the stack.
1393
The IntStack Class Table 18-2: Member Functions
Member Function Description stackArray Constructor The class constructor accepts an integer argument, which specifies the size of the stack. An integer array of this size is dynamically allocated, and assigned to stackArray. Also, the variable top is initialized to –1. push The push function accepts an integer argument, which is pushed onto the top of the stack. pop The pop function uses an integer reference parameter. The value at the top of the stack is removed, and copied into the reference parameter.
1394
The IntStack Class Table 18-2: Member Functions (continued)
Member Function Description stackArray isFull Returns true if the stack is full and false otherwise. The stack is full when top is equal to stackSize – 1. isEmpty Returns true if the stack is empty, and false otherwise. The stack is empty when top is set to –1.
1395
Contents of IntStack.h #ifndef INTSTACK_H #define INTSTACK_H class IntStack { private: int *stackArray; int stackSize; int top; public: IntStack(int); void push(int); void pop(int &); bool isFull(void); bool isEmpty(void); }; #endif
1396
Contents of IntStack.cpp
#include <iostream.h> #include "intstack.h“ //******************* // Constructor * //******************* IntStack::IntStack(int size) { stackArray = new int[size]; stackSize = size; top = -1; }
1397
Contents of IntStack.cpp
//************************************************* // Member function push pushes the argument onto * // the stack * //************************************************* void IntStack::push(int num) { if (isFull()) { cout << "The stack is full.\n"; } else { top++; stackArray[top] = num; } }
1398
Contents of IntStack.cpp
//**************************************************** // Member function pop pops the value at the top * // of the stack off, and copies it into the variable * // passed as an argument * //**************************************************** void IntStack::pop(int &num) { if (isEmpty()) { cout << "The stack is empty.\n"; } else { num = stackArray[top]; top--; } }
1399
Contents of IntStack.cpp
//*************************************************** // Member function isFull returns true if the stack * // is full, or false otherwise * //*************************************************** bool IntStack::isFull(void) { bool status; if (top == stackSize - 1) status = true; else status = false; return status; }
1400
Contents of IntStack.cpp
//**************************************************** // Member funciton isEmpty returns true if the stack * // is empty, or false otherwise * //**************************************************** bool IntStack::isEmpty(void) { bool status; if (top == -1) status = true; else status = false; return status; }
1401
Program 18-1 // This program demonstrates the IntStack class. #include <iostream.h> #include "intstack.h“ void main(void) { IntStack stack(5); int catchVar; cout << "Pushing 5\n"; stack.push(5); cout << "Pushing 10\n"; stack.push(10); cout << "Pushing 15\n"; stack.push(15); cout << "Pushing 20\n"; stack.push(20); cout << "Pushing 25\n"; stack.push(25);
1402
Program 18-1 (continued) cout << "Popping...\n"; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; }
1403
Program 18-1 (continued) Program Output Pushing 5 Pushing 10 Pushing 15 Pushing 20 Pushing 25 Popping
1404
About Program 18-1 In the program, the constructor is called with the argument 5. This sets up the member variables as shown in Figure Since top is set to –1, the stack is empty
1405
About Program 18-1 Figure 18-5 shows the state of the member variables after the push function is called the first time (with 5 as its argument). The top of the stack is now at element 0.
1406
About Program 18-1 Figure 18-6 shows the state of the member variables after all five calls to the push function. Now the top of the stack is at element 4, and the stack is full.
1407
About Program 18-1 Notice that the pop function uses a reference parameter, num. The value that is popped off the stack is copied into num so it can be used later in the program. Figure 18-7 (on the next slide) depicts the state of the class members, and the num parameter, just after the first value is popped off the stack.
1408
About Program 18-1
1409
Implementing Other Stack Operations
The MathStack class (discussed on pages 1072 – 1075) demonstrates functions for stack-based arithmetic.
1410
18.2 Dynamic Stacks A dynamic stack is built on a linked list instead of an array. A linked list-based stack offers two advantages over an array-based stack. No need to specify the starting size of the stack. A dynamic stack simply starts as an empty linked list, and then expands by one node each time a value is pushed. A dynamic stack will never be full, as long as the system has enough free memory.
1411
Contents of DynIntStack.h
class DynIntStack { private: struct StackNode { int value; StackNode *next; }; StackNode *top; public: DynIntStack(void) { top = NULL; } void push(int); void pop(int &); bool isEmpty(void); };
1412
Contents of DynIntStack.cpp
#include <iostream.h> #include "dynintstack.h“ //************************************************ // Member function push pushes the argument onto * // the stack * //************************************************ void DynIntStack::push(int num) { stackNode *newNode; // Allocate a new node & store Num newNode = new stackNode; newNode->value = num;
1413
Contents of DynIntStack.cpp
// If there are no nodes in the list // make newNode the first node if (isEmpty()) { top = newNode; newNode->next = NULL; } else // Otherwise, insert NewNode before top { newNode->next = top; top = newNode; } } //**************************************************** // Member function pop pops the value at the top * // of the stack off, and copies it into the variable * // passed as an argument * //****************************************************
1414
Contents of DynIntStack.cpp
void DynIntStack::pop(int &num) { stackNode *temp; if (isEmpty()) { cout << "The stack is empty.\n"; } else // pop value off top of stack { num = top->value; temp = top->next; delete top; top = temp; } }
1415
Contents of DynIntStack.cpp
//**************************************************** // Member funciton isEmpty returns true if the stack * // is empty, or false otherwise * //**************************************************** bool DynIntStack::isEmpty(void) { bool status; if (!top) status = true; else status = false; return status; }
1416
Program 18-3 // This program demonstrates the dynamic stack // class DynIntClass. #include <iostream.h> #include "dynintstack.h“ void main(void) { DynIntStack stack; int catchVar; cout << "Pushing 5\n"; stack.push(5); cout << "Pushing 10\n"; stack.push(10); cout << "Pushing 15\n"; stack.push(15);
1417
Program 18-3 (continued) Program Output
cout << "Popping...\n"; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; stack.pop(catchVar); cout << catchVar << endl; cout << "\nAttempting to pop again... "; stack.pop(catchVar); } Program Output Pushing 5 Pushing 10 Pushing 15 Popping Attempting to pop again... The stack is empty.
1418
18.3 The STL stack Container
The STL stack container may be implemented as a vector, a list, or a deque (which you will learn about later in this chapter). Because the stack container is used to adapt these other containers, it is often referred to as a container adapter.
1419
18.3 The STL stack Container
Here are examples of how to declare a stack of ints, implemented as a vector, a list, and a deque. stack< int, vector<int> > iStack; // Vector stack stack< int, list<int> > iStack; // List stack stack< int > iStack; // Default – deque stack
1420
18.3 The STL stack Container
Table 18-3 (pages ) lists and describes many of the stack container’s member functions.
1421
Program 18-4 // This program demonstrates the STL stack // container adapter. #include <iostream.h> #include <vector> #include <stack> using namespace std; void main(void) { int x; stack< int, vector<int> > iStack; for (x = 2; x < 8; x += 2) { cout << "Pushing " << x << endl; iStack.push(x); }
1422
Program 18-4 (continued) cout << "The size of the stack is "; cout << iStack.size() << endl; for (x = 2; x < 8; x += 2) { cout << "Popping " << iStack.top() << endl; iStack.pop(); } } Program Output Pushing 2 Pushing 4 Pushing 6 The size of the stack is 3 Popping 6 Popping 4 Popping 2
1423
18.4 Introduction to the Queue ADT
Like a stack, a queue (pronounced "cue") is a data structure that holds a sequence of elements. A queue, however, provides access to its elements in first-in, first-out (FIFO) order. The elements in a queue are processed like customers standing in a grocery check-out line: the first customer in line is the first one served.
1424
Example Applications of Queues
In a multi-user system, a queue is used to hold print jobs submitted by users , while the printer services those jobs one at a time. Communications software also uses queues to hold information received over networks and dial-up connections. Sometimes information is transmitted to a system faster than it can be processed, so it is placed in a queue when it is received.
1425
Static and Dynamic Queues
Just as stacks are implemented as arrays or linked lists, so are queues. Dynamic queues offer the same advantages over static queues that dynamic stacks offer over static stacks.
1426
Queue Operations Think of queues as having a front and a rear. This is illustrated in Figure 18-8.
1427
Queue Operations The two primary queue operations are enqueuing and dequeuing. To enqueue means to insert an element at te rear of a queue. To dequeue means to remove an element from the front of a queue.
1428
Queue Operations Suppose we have an empty static integer queue that is capable of holding a maximum of three values. With that queue we execute the following enqueue operations. Enqueue(3); Enqueue(6); Enqueue(9);
1429
Queue Operations Figure 18-9 illustrates the state of the queue after each of the enqueue operations.
1430
Queue Operations Now let's see how dequeue operations are performed. Figure illustrates the state of the queue after each of three consecutive dequeue operations
1431
Queue Operations When the last deqeue operation is performed in the illustration, the queue is empty. An empty queue can be signified by setting both front and rear indices to –1. Pages discuss the inefficiency of this algorithm, and its solution: implement the queue as a circular array.
1432
Contents of IntQueue.h class IntQueue { private: int *queueArray; int queueSize; int front; int rear; int numItems; public: IntQueue(int); ~IntQueue(void); void enqueue(int); void dequeue(int &); bool isEmpty(void); bool isFull(void); void clear(void); };
1433
Contents of IntQueue.cpp
#include <iostream.h> #include "IntQueue.h“ //************************* // Constructor * //************************* IntQueue::IntQueue(int s) { queueArray = new int[s]; queueSize = s; front = 0; rear = 0; numItems = 0; }
1434
Contents of IntQueue.cpp
//************************* // Destructor * //************************* IntQueue::~IntQueue(void) { delete [] queueArray; }
1435
Contents of IntQueue.cpp
//******************************************** // Function enqueue inserts the value in num * // at the rear of the queue * //******************************************** void IntQueue::enqueue(int num) { if (isFull()) cout << "The queue is full.\n"; else { // Calculate the new rear position rear = (rear + 1) % queueSize; // Insert new item queueArray[rear] = num; // Update item count numItems++; } }
1436
Contents of IntQueue.cpp
//********************************************* // Function dequeue removes the value at the * // front of the queue, and copies t into num. * //********************************************* void IntQueue::dequeue(int &num) { if (isEmpty()) cout << "The queue is empty.\n"; else { // Move front front = (front + 1) % queueSize; // Retrieve the front item num = queueArray[front]; // Update item count numItems--; } }
1437
Contents of IntQueue.cpp
//********************************************* // Function isEmpty returns true if the queue * // is empty, and false otherwise * //********************************************* bool IntQueue::isEmpty(void) { bool status; if (numItems) status = false; else status = true; return status; }
1438
Contents of IntQueue.cpp
//******************************************** // Function isFull returns true if the queue * // is full, and false otherwise * //******************************************** bool IntQueue::isFull(void) { bool status; if (numItems < queueSize) status = false; else status = true; return status; }
1439
Contents of IntQueue.cpp
//******************************************* // Function clear resets the front and rear * // indices, and sets numItems to * //******************************************* void IntQueue::clear(void) { front = queueSize - 1; rear = queueSize - 1; numItems = 0; }
1440
Program 18-5 // This program demonstrates the IntQeue class #include <iostream.h> #include "intqueue.h“ void main(void) { IntQueue iQueue(5); cout << "Enqueuing 5 items...\n"; // Enqueue 5 items. for (int x = 0; x < 5; x++) iQueue.enqueue(x); // Attempt to enqueue a 6th item. cout << "Now attempting to enqueue again...\n"; iQueue.enqueue(5);
1441
Program 18-5 (continued) Program Output
// Deqeue and retrieve all items in the queue cout << "The values in the queue were:\n"; while (!iQueue.isEmpty()) { int value; iQueue.dequeue(value); cout << value << endl; } } Program Output Enqueuing 5 items... Now attempting to enqueue again... The queue is full. The values in the queue were: 0
1442
18.5 Dynamic Queues A dynamic queue starts as an empty linked list.
With the first enqueue operation, a node is added, which is pointed to by front and rear pointers. As each new item is added to the queue, a new node is added to the rear of the list, and the rear pointer is updated to point to the new node. As each item is dequeued, the node pointed to by the front pointer is deleted, and front is made to point to the next node in the list.
1443
Dynamic Queues Figure shows the structure of a dynamic queue.
1444
Contents of DynIntQueue.h
class DynIntQueue { private: struct QueueNode { int value; QueueNode *next; }; QueueNode *front; QueueNode *rear; int numItems; public: DynIntQueue(void); ~DynIntQueue(void); void enqueue(int); void dequeue(int &); bool isEmpty(void); void clear(void); };
1445
Contents of DynIntQueue.cpp
#include <iostream.h> #include "dynintqueue.h“ //************************ // Constructor * //************************ DynIntQueue::DynIntQueue(void) { front = NULL; rear = NULL; numItems = 0; } //************************ // Destructor * //************************ DynIntQueue::~DynIntQueue(void) { clear(); }
1446
Contents of DynIntQueue.cpp
//******************************************** // Function enqueue inserts the value in num * // at the rear of the queue * //******************************************** void DynIntQueue::enqueue(int num) { QueueNode *newNode; newNode = new QueueNode; newNode->value = num; newNode->next = NULL; if (isEmpty()) { front = newNode; rear = newNode; } else { rear->next = newNode; rear = newNode; } numItems++; }
1447
Contents of DynIntQueue.cpp
//********************************************** // Function dequeue removes the value at the * // front of the queue, and copies it into num. * //********************************************** void DynIntQueue::dequeue(int &num) { QueueNode *temp; if (isEmpty()) cout << "The queue is empty.\n"; else { num = front->value; temp = front->next; delete front; front = temp; numItems--; } }
1448
Contents of DynIntQueue.cpp
//********************************************* // Function isEmpty returns true if the queue * // is empty, and false otherwise * //********************************************* bool DynIntQueue::isEmpty(void) { bool status; if (numItems) status = false; else status = true; return status; }
1449
Contents of DynIntQueue.cpp
//******************************************** // Function clear dequeues all the elements * // in the queue * //******************************************** void DynIntQueue::clear(void) { int value; // Dummy variable for dequeue while(!isEmpty()) dequeue(value); }
1450
Program 18-6 // This program demonstrates the DynIntQeue class #include <iostream.h> #include "dynintqueue.h“ void main(void) { DynIntQueue iQueue; cout << "Enqueuing 5 items...\n"; // Enqueue 5 items. for (int x = 0; x < 5; x++) iQueue.enqueue(x); // Deqeue and retrieve all items in the queue cout << "The values in the queue were:\n"; while (!iQueue.isEmpty()) { int value; iQueue.dequeue(value); cout << value << endl; } }
1451
Program 18-6 (continued) Program Ouput
Enqueuing 5 items... The values in the queue were:
1452
The STL deque and queue Containers
A deque (pronounced "deck" or "deek") is a double-ended queue. It similar to a vector, but allows efficient access to values at both the front and the rear. The queue ADT is like the the stack ADT: it is actually a container adapter.
1453
The deque Container Programs that use the deque ADT must include the deque header file. The push_back, pop_front, and front member functions are described in Table 18-4 (page 1094).
1454
Program 18-7 // This program demonstrates the STL deque // container. #include <iostream.h> #include <deque> using namespace std; void main(void) { int x; deque<int> iDeque; cout << "I will now enqueue items...\n"; for (x = 2; x < 8; x += 2) { cout << "Pushing " << x << endl; iDeque.push_back(x); } cout << "I will now dequeue items...\n"; for (x = 2; x < 8; x += 2) { cout << "Popping " << iDeque.front() << endl; iDeque.pop_front(); } }
1455
Program 18-7 (continued) Program Output I will now enqueue items...
I will now enqueue items... Pushing 2 Pushing 4 Pushing 6 I will now dequeue items... Popping 2 Popping 4 Popping 6
1456
The queue Container Adapter
The queue container adapter can be built upon vectors, lists, or deques. By default, it uses deque as its base.
1457
The queue Container Adapter
The queue insertion and removal operations are the same as those supported by the stack ADT: push, pop, and top. The queue version of push always inserts an element at the rear of the queue. The queue version of pop always removes an element from the structure's front. The top function returns the value of the element at the front of the queue.
1458
Program 18-8 // This program demonstrates the STL queue // container adapter. #include <iostream.h> #include <queue> using namespace std; void main(void) { int x; queue<int> iQueue; cout << "I will now enqueue items...\n"; for (x = 2; x < 8; x += 2) { cout << "Pushing " << x << endl; iQueue.push(x); } cout << "I will now dequeue items...\n"; for (x = 2; x < 8; x += 2) { cout << "Popping " << iQueue.front() << endl; iQueue.pop(); } }
1459
Program 18-8 (continued) Program Output I will now enqueue items...
Pushing 2 Pushing 4 Pushing 6 I will now dequeue items... Popping 2 Popping 4 Popping 6
1460
Chapter 19 Recursion
1461
19.1 Introduction to Recursion
A recursive function is one that calls itself. void message(void) { cout << "This is a recursive function.\n"; message(); } The function above displays the string "This is a recursive function.\n", and then calls itself. Can you see a problem with the function?
1462
Recursion The function is like an infinite loop because there is no code to stop it from repeating. Like a loop, a recursive function must have some algorithm to control the number of times it repeats.
1463
Recursion Like a loop, a recursive function must have some algorithm to control the number of times it repeats. Shown below is a modification of the message function. It passes an integer argument, which holds the number of times the function is to call itself. void message(int times) { if (times > 0) { cout << "This is a recursive function.\n"; message(times ‑ 1); } return; }
1464
Recursion The function contains an if/else statement that controls the repetition. As long as the times argument is greater than zero, it will display the message and call itself again. Each time it calls itself, it passes times - 1 as the argument.
1465
Recursion For example, let's say a program calls the function with the following statement: Message(5); The argument, 5, will cause the function to call itself 5 times. The first time the function is called, the if statement will display the message and then call itself with 4 as the argument. Figure 19-1 (on the next slide) illustrates this.
1466
Figure 19-1 Each time the function is called, a new instance of the times parameter is created. In the first call to the function, times is set to 5. 1st call of the function Value of times: 5 When the function calls itself, a new instance of times is created with the value 4. 2nd call of the function Value of times: 4
1467
Figure 19-1 1st call of the function Value of times: 5 This cycle repeats itself until 0 is passed to to the function. 2nd call of the function Value of times: 4 3rd call of the function Value of times: 3 4th call of the function Value of times: 2 5th call of the function Value of times: 1 Depth of recursion: 6 6th call of the function Value of times: 0
1468
Program 19-1 // This program demonstrates a simple recursive function. #include <iostream.h> // Function prototype void message(int); void main(void) { message(5); }
1469
Program 19-1 (continued) //*********************************************************** // Definition of function Message. If the value in times is * // greater than 0, the message is displayed and the * // function is recursively called with the argument * // times * //*********************************************************** void message(int times) { if (times > 0) { cout << "This is a recursive function.\n"; message(times - 1); } return; }
1470
Program 19-1 (continued) Program Output
This is a recursive function. This is a recursive function. This is a recursive function. This is a recursive function. This is a recursive function.
1471
Program 19-2 // This program demonstrates a simple recursive function. #include <iostream.h> // Function prototype void message(int); void main(void) { message(5); }
1472
Program 19-2 (continued) //*********************************************************** // Definition of function Message. If the value in times is * // greater than 0, the message is displayed and the * // function is recursively called with the argument * // times * //*********************************************************** void message(int times) { cout << "Message called with " << times << " in times.\n"; if (times > 0) { cout << "This is a recursive function.\n"; message(times - 1); } cout << "Message returning with " << times; cout << " in times.\n"; }
1473
Program 19-2 (continued) Program Output
Message called with 5 in Times. This is a recursive function. Message called with 4 in Times. This is a recursive function. Message called with 3 in Times. This is a recursive function. Message called with 2 in Times. This is a recursive function. Message called with 1 in Times. This is a recursive function. Message called with 0 in Times. Message returning with 0 in Times. Message returning with 1 in Times. Message returning with 2 in Times. Message returning with 3 in Times. Message returning with 4 in Times. Message returning with 5 in Times.
1474
Recursion The role of recursive functions in programming is to break complex problems down to a solvable problem. The solvable problem is known as the base case. A recursive function is designed to terminate when it reaches its base case.
1475
The numChars function The function's parameters are:
int numChars(char search, char str[], int subscript) { if (str[subscript] == '\0') return 0; else { if (str[subscript] == search) return 1 + numChars(search, str, subscript+1); else return numChars(search, str, subscript+1); } } The function's parameters are: search: The character to be searched for and counted. str: An array containing the string to be searched. subscript: The starting subscript for the search.
1476
The numChars function The first if statement determines if the end of the string has been reached: if (str[subscript] == '\0') If so, the function returns 0, indicating there are no more characters to count. Otherwise, the following if/else statement is executed: if (str[subscript] == search) return 1 + numChars(search, str, subscript+1); else return numChars(search, str, subscript+1); If str[subscript] contains the search character, the function performs a recursive call. The return statement returns 1 + the number of times the search character appears in the string, starting at subscript + 1. If str[subscript] does not contain the search character, a recursive call is made to search the remainder of the string.
1477
Program 19-3 // This program demonstrates a recursive function for // counting the number of times a character appears // in a string. #include <iostream.h> int numChars(char, char [], int); void main(void) { char array[] = "abcddddef"; cout << "The letter d appears “ << numChars('d', array, 0) << " times\n"; }
1478
Program 19-3 (continued) //************************************************ // Function numChars. This recursive function * // counts the number of times the character * // search appears in the string str. The search * // begins at the subscript stored in subscript. * //************************************************ int numChars(char search, char str[], int subscript) { if (str[subscript] == '\0') return 0; else { if (str[subscript] == search) return 1 + numChars(search, str, subscript+1); else return numChars(search, str, subscript+1); } }
1479
Program 19-3 (continued) Program Output The letter d appears 4 times.
1480
Direct and Indirect Recursion
These examples show recursive functions that directly call themselves. This is known as direct recursion. There is also the possibility of creating indirect recursion in a program. This occurs when function A calls function B, which in turn calls function A.
1481
19.2 The Recursive Factorial Function
In mathematics, the notation n! represents the factorial of the number n. The factorial of a number is defined as: n! = 1 * 2 * 3 * ... * n if n > 0 1 if n = 0
1482
The Recursive Factorial Function
Another way of defining the factorial of a number, using recursion, is: Factorial(n) = n * Factorial(n - 1) if n > if n = 0 The following C++ function implements the recursive definition shown above: int factorial(int num) { if (num > 0) return num * factorial(num - 1); else return 1; }
1483
Program 19-4 // This program demonstrates a recursive function to // calculate the factorial of a number. #include <iostream.h> // Function prototype int factorial(int); void main(void) { int number; cout << "Enter an integer value and I will display\n"; cout << "its factorial: "; cin >> number; cout << "The factorial of " << number << " is "; cout << factorial(number) << endl; }
1484
Program 19-4 //************************************************************** // Definition of factorial. A recursive function to calculate * // the factorial of the parameter, num * //************************************************************** int factorial(int num) { if (num > 0) return num * factorial(num - 1); else return 1; }
1485
Program 19-4 Program Output with Example Input
Enter an integer value and I will display its factorial: 4 The factorial of 4 is 24
1486
19.3 The Recursive gcd Function
Our next example of recursion is the calculation of the greatest common divisor, or GCD, of two numbers. Using Euclid's Algorithm, the GCD of two positive integers, x and y, is: GCD(x, y) = y; if y divides x evenly GCD(y, remainder of y/x) The definition above states that the GCD of x and y is y if x/y has no remainder. Otherwise, the answer is the GCD of y and the remainder of x/y. This is demonstrated in Program 19-5.
1487
Program 19-5 // This program demonstrates a recursive function to calculate // the greatest common divisor (gcd) of two numbers. #include <iostream.h> // Function prototype int gcd(int, int); void main(void) { int num1, num2; cout << "Enter two integers: "; cin >> num1 >> num2; cout << "The greatest common divisor of " << num1; cout << " and " << num2 << " is "; cout << gcd(num1, num2) << endl; }
1488
Program 19-5 Program Output with Example Input
//********************************************************* // Definition of gcd. This function uses recursion to * // calculate the greatest common divisor of two integers, * // passed into the parameters x and y * //********************************************************* int gcd(int x, int y) { if (x % y == 0) return y; else return gcd(y, x % y); } Program Output with Example Input Enter two integers: The greatest common divisor of 49 and 28 is 7
1489
19.4 Solving Recursively Defined Problems
Some mathematical problems are designed to be solved recursively. One example is the calculation of Fibonacci numbers, which are the following sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, …
1490
Solving Recursively Defined Problems
The Fibonacci series can be defined as: F0 = 0, F1 = 1, FN = FN-1 + FN-2 for N 2.
1491
Solving Recursively Defined Problems
A recursive C++ function to calculate the nth number in the Fibonacci series is shown below . int fib(int n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fib(n - 1) + fib(n - 2); }
1492
Program 19-6 // This programs demonstrates a recursive function // that calculates Fibonacci numbers. #include <iostream.h> // Function prototype int fib(int); void main(void) { cout << "The first 10 Fibonacci numbers are:\n"; for (int x = 0; x < 10; x++) cout << fib(x) << " "; cout << endl; }
1493
Program 19-6 (continued) //***************************************** // Function fib. Accepts an int argument * // in n. This function returns the nth * // Fibonacci number * //***************************************** int fib(int n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fib(n - 1) + fib(n - 2); }
1494
Program 19-6 (continued) Program Output
The first 10 Fibonacci numbers are:
1495
19.5 Recursive Linked List Operations
Recursion may be used in some operations on linked lists. We will look at functions that: Count the number of nodes in a list, and Display the value of the list nodes in reverse order. We will use the FloatList class developed in Chapter 17.
1496
Counting the Nodes in the List
int FloatList::countNodes(ListNode *nodePtr) { if (nodePtr != NULL) return 1 + countNodes(nodePtr->next); else return 0; } The base case for the function is nodePtr being equal to NULL.
1497
Counting the Nodes in the List
The function's recursive logic can be expressed as: If the current node has a value Return 1 + the number of the remaining nodes. Else Return 0. end If.
1498
Program 19-7 Program Output The number of nodes is 10
#include <iostream.h> #include "FloatList2.h“ void main(void) { FloatList list; for (int x = 0; x < 10; x++) list.insertNode(x); cout << "The number of nodes is “ << list.numNodes() << endl; } Program Output The number of nodes is 10
1499
Displaying the List Nodes in Reverse Order
void FloatList::showReverse(ListNode *nodePtr) { if (nodePtr != NULL) { showReverse(nodePtr->next); cout << nodePtr->value << " "; } } The base case for the function is nodePtr being equal to NULL.
1500
Program 19-8 // This program demonstrates the FloatList class's // recursive function for displaying the list's nodes // in reverse. #include <iostream.h> #include "FloatList2.h“ void main(void) { FloatList list; for (float x = 1.5; x < 15; x += 1.1) list.appendNode(x); cout << "Here are the values in the list:\n"; list.displayList(); cout << "Here are the values in reverse order:\n"; list.displayBackwards(); }
1501
Program 19-8 (continued) Program Output Here are the values in the list: Here are the values in reverse order:
1502
19.6 A Recursive Binary Search Function
The binary search algorithm, which you learned about in Chapter 8, can be implemented recursively. For example, the procedure can be expressed as: If array[middle] equals the search value, then the value is found. Else, if array[middle] is less than the search value, perform a binary search on the upper half of the array. Else, if array[middle] is greater than the search value, perform a binary search on the lower half of the array.
1503
A Recursive Binary Search Function
A recursive binary search function is shown below. int binarySearch(int array[], int first, int last, int value) { int middle; // Mid point of search if (first > last) return -1; middle = (first + last) / 2; if (array[middle] == value) return middle; if (array[middle] < value) return binarySearch(array, middle+1,last,value); else return binarySearch(array, first,middle-1,value); }
1504
A Recursive Binary Search Function
int binarySearch(int array[], int first, int last, int value) The 1st parameter, array, is the array to be searched. The 2nd parameter, first, holds the subscript of the first element in the search range (the portion of the array to be searched). The 3rd parameter, last, holds the subscript of the last element in the search range. The 4th parameter, value, holds the value to be searched for. This function returns the subscript of the value if it is found, or -1 if the value is not found.
1505
Program 19-9 // This program demonstrates the recursive binarySearch function, which // performs a binary search on an integer array. #include <iostream.h> // Function prototype int binarySearch(int [], int, int, int); const int arrSize = 20; void main(void) { int tests[arrSize] = {101, 142, 147, 189, 199, 207, 222, , 289, 296, 310, 319, 388, 394, , 429, 447, 521, 536, 600}; int results, empID; cout << "Enter the Employee ID you wish to search for: "; cin >> empID;
1506
Program 19-9 (continued) results = binarySearch(tests, 0, arrSize - 1, empID); if (results == -1) cout << "That number does not exist in the array.\n"; else { cout << "That ID is found at element " << results; cout << " in the array\n"; } } //*************************************************************** // The binarySearch function performs a recursive binary search * // on a range of elements of an integer array passed into the * // parameter array.The parameter first holds the subscript of * // the range's starting element, and last holds the subscript * // of the ranges's last element. The paramter value holds the * // the search value. If the search value is found, its array * // subscript is returned. Otherwise, -1 is returned indicating * // the value was not in the array * //***************************************************************
1507
Program 19-9 int binarySearch(int array[], int first, int last, int value) { int middle; // Mid point of search if (first > last) return -1; middle = (first + last)/2; if (array[middle]==value) return middle; if (array[middle]<value) return binarySearch(array, middle+1,last,value); else return binarySearch(array, first,middle-1,value); } Program Output with Example Input Shown in Bold Enter the Employee ID you wish to search for: 521 [Enter] That ID is found at element 17 in the array
1508
The QuickSort Algorithm
Can be used to sort lists stored in arrays or linear linked lists. It sorts a list by dividing it into two sublists. Between the sublists is a selected value known as the pivot. This is illustrated in Figure 19-4.
1509
The QuickSort Algorithm
Once a pivot value has been selected, the algorithm exchanges the other values in the list until all the elements in sublist 1 are less than the pivot, and all the elements in sublist 2 are greater than the pivot. Once this is done, the algorithm repeats the procedure on sublist 1, and then on sublist 2. The recursion stops when there is only one element in a sublist. At that point the original list is completely sorted.
1510
The QuickSort Algorithm
The algorithm is coded primarily in two functions: QuickSort and Partition. QuickSort is a recursive function. Its pseudocode is shown below. QuickSort: If Starting Index < Ending Index Partition the List around a Pivot. QuickSort Sublist 1. QuickSort Sublist 2. end If.
1511
The QuickSort Algorithm
The C++ Code: void quickSort(int set[], int start, int end) { int pivotPoint; if (start < end) { // Get the pivot point. pivotPoint = partition(set, start, end); // Sort the first sub list. quickSort(set, start, pivotPoint - 1); // Sort the second sub list. quickSort(set, pivotPoint + 1, end); } }
1512
The QuickSort Algorithm
The partition Function: int partition(int set[], int start, int end) { int pivotValue, pivotIndex, mid; mid = (start + end) / 2; exchange(set[start], set[mid]); pivotIndex = start; pivotValue = set[start]; for (int scan = start + 1; scan <= end; scan++) { if (set[scan] < pivotValue) { pivotIndex++; exchange(set[pivotIndex], set[scan]); } } exchange(set[start], set[pivotIndex]); return pivotIndex; }
1513
The QuickSort Algorithm
The exchange Function: void exchange(int &value1, int &value2) { int temp = value1; value1 = value2; value2 = temp; }
1514
Program 19-10 // This program demonstrates the QuickSort Algorithm #include <iostream.h> // Function prototypes void quickSort(int [], int, int); int partition(int [], int, int); void exchange(int &, int &); void main(void) { int array[10] = {7, 3, 9, 2, 0, 1, 8, 4, 6, 5}; int x; // Counter for (x = 0; x < 10; x++) cout << array[x] << " "; cout << endl; quickSort(array, 0, 9); for (x = 0; x < 10; x++) cout << array[x] << " "; cout << endl; } The code for the remainder of the program was previously shown…
1515
Program 19-10 Program Output
1516
19.8 Exhaustive Algorithms
An exhaustive algorithm is one that finds a best combination of items by looking at all the possible combinations.
1517
Exhaustive Algorithms
For example, consider all the different ways you can make change for $1.00 using our system of coins: 1 dollar piece, or 2 fifty-cent pieces, or 4 quarters, or 1 fifty-cent piece and 2 quarters, or 3 quarters, 2 dimes, and 1 nickel, or … there are many more possibilities.
1518
Exhaustive Algorithms
Although there are many ways to make change for $1.00, some ways are better than others. For example, you would probably rather give a single dollar piece instead of 100 pennies. An algorithm that looks at all the possible combinations of items in order to find the best combination of items is called an exhaustive algorithm.
1519
Program 19-11 // This program demonstrates a recursive function that exhaustively // searches through all possible combinations of coin values to find // the best way to make change for a specified amount. #include <iostream.h> // Constants const int maxCoinsChange = 100; // Maximum number of coins to give in change const int maxCoinValues = 6; // Maximum number of coin values const int noSolution = ; // Indicates no solution // Function prototype void makeChange(int, int, int[], int); // coinValues - global array of coin values to choose from int coinValues[maxCoinValues] = {100, 50, 25, 10, 5, 1 }; // bestCoins - global array of best coins to make change with int bestCoins[maxCoinsChange]; // Global variables int numBestCoins = noSolution, // Number of coins in bestCoins numSolutions = 0, // Number of ways to make change numCoins; // Number of allowable coins
1520
Program (continued) void main(void) { int coinsUsed[maxCoinsChange], // List of coins used numCoinsUsed = 0, // The number coins used amount; // The amount to make change for // Display the possible coin values. cout << "Here are the valid coin values, in cents: "; for (int index = 0; index < 5; index++) cout << coinValues[index] << " "; cout << endl; // Get input from the user. cout << "Enter the amount of cents (as an integer) to make change for: "; cin >> amount; cout << "What is the maximum number of coins to give as change? "; cin >> numCoins; // Call the recursive function. makeChange(numCoins, amount, coinsUsed, numCoinsUsed);
1521
Program (continued) // Display the results. cout << "Number of possible combinations: " << numSolutions << endl; cout << "Best combination of coins:\n"; if (numBestCoins == noSolution) cout << "\tNo solution\n"; else { for (int count = 0; count < numBestCoins; count++) cout << bestCoins[count] << " "; } cout << endl; } //********************************************************************** // Function makeChange. This function uses the following parameters: * // coinsLeft - The number of coins left to choose from * // amount - The amount to make change for * // coinsUsed - An array that contains the coin values used so far. * // numCoinsUsed - The number of values in the coinsUsed array * // * // This recursive function finds all the possible ways to make change * // for the value in amount. The best combination of coins is stored in * // the array bestCoins * //**********************************************************************
1522
Program 19-11 void makeChange(int coinsLeft, int amount, int coinsUsed[], int numCoinsUsed) { int coinPos, // To calculate array position of coin being used count; // Loop counter if (coinsLeft == 0) // If no more coins are left return; else if (amount < 0) // If amount to make change for is negative return; else if (amount == 0) // If solution is found { // Store as bestCoins if best if (numCoinsUsed < numBestCoins) { for (count = 0; count < numCoinsUsed; count++) bestCoins[count] = coinsUsed[count]; numBestCoins = numCoinsUsed; } numSolutions++; return; }
1523
Program 19-11 Program Output with Example Input Shown in Bold
// Find the other combinations using the coin coinPos = numCoins - coinsLeft; coinsUsed[numCoinsUsed] = coinValues[coinPos]; numCoinsUsed++; makeChange(coinsLeft, amount - coinValues[coinPos], coinsUsed, numCoinsUsed); // Find the other combinations not using the coin numCoinsUsed--; makeChange(coinsLeft - 1, amount, coinsUsed, numCoinsUsed); } Program Output with Example Input Shown in Bold Here are the valid coin values, in cents: Enter the amount of cents (as an integer) to make change for: 62 [Enter] What is the maximum number of coins to give as change? 6 [Enter] Number of possible combinations: 77 Best combination of coins:
1524
Chapter 20 Binary Trees
1525
20.1 Definition and Applications of Binary Trees
A binary tree is a non-linear linked list where each node may point to two other nodes.
1526
Definition and Applications of Binary Trees
It is anchored at the top by a tree pointer, which is like the head pointer in a linked list. The first node in the list is called the root node. The root node has pointers to two other nodes, which are called children, or child nodes.
1527
Definition and Applications of Binary Trees
A node that has no children is called a leaf node. All pointers that do not point to a node are set to NULL.
1528
Definition and Applications of Binary Trees
Binary trees can be divided into subtrees. A subtree is an entire branch of the tree, from one particular node down.
1529
Definition and Applications of Binary Trees
Binary trees are excellent data structures for searching large amounts of information. They are commonly used in database applications to organize key values that index database records. When used to facilitate searches, a binary tree is called a binary search tree.
1530
Definition and Applications of Binary Trees
Information is stored in binary search trees in a way that makes a binary search simple. For example, look at Figure 20-3. Values are stored in a binary tree so that a node's left child holds data whose value is less than the node's data, and the node's right child holds data whose value is greater tan the node's data.
1531
Definition and Applications of Binary Trees
It is also true that all the nodes to the left of a node hold values less than the node's value. Likewise, all the nodes to the right of a node hold values that are greater than the node's data. When an application is searching a binary tree, it starts at the root node. If the root node does not hold the search value, the application branches either to the left or right child, depending on whether the search value is less than or grater than the value at the root node.
1532
Definition and Applications of Binary Trees
This process continues until the value is found. Figure 20-4 illustrates the search pattern for finding the value P in the binary tree.
1533
20.2 Binary Search Tree Operations
Creating a Node: We will demonstrate binary tree operations using the IntBinaryTree class. The basis of our binary tree node is the following struct declaration: struct TreeNode { int value; TreeNode *left; TreeNode *right; }; The struct is implemented in the class shown next…
1534
IntBinaryTree.h class IntBinaryTree { public: struct TreeNode { int value; TreeNode *left; TreeNode *right; }; TreeNode *root; void destroySubTree(TreeNode *); void deleteNode(int, TreeNode *&); void makeDeletion(TreeNode *&); void displayInOrder(TreeNode *); void displayPreOrder(TreeNode *); void displayPostOrder(TreeNode *);
1535
IntBinaryTree.h (continued)
public: IntBinaryTree() // Constructor { root = NULL; } ~IntBinaryTree() // Destructor { destroySubTree(root); } void insertNode(int); bool searchNode(int); void remove(int); void showNodesInOrder(void) { displayInOrder(root); } void showNodesPreOrder() { displayPreOrder(root); } void showNodesPostOrder() { displayPostOrder(root); } };
1536
20.2 Binary Search Tree Operations
Inserting a Node:First, a new node is allocated and its value member is initialized with the new value. The left and right child pointers are set to NULL, because all nodes must be inserted as leaf nodes. Next, we determine if the tree is empty. If so, we simply make root point to it, and there is nothing else to be done. But, if there are nodes in the tree, we must find the new node's proper insertion point.
1537
20.2 Binary Search Tree Operations
If the new value is less than the root node's value, we know it will be inserted somewhere in the left subtree. Otherwise, the value will be inserted into the right subtree. We simply traverse the subtree, comparing each node along the way with the new node's value, and deciding if we should continue to the left or the right. When we reach a child pointer that is set to NULL, we have found out insertion point.
1538
The insertNode Member Function
void IntBinaryTree::insertNode(int num) { TreeNode *newNode, // Pointer to a new node *nodePtr; // Pointer to traverse the tree // Create a new node newNode = new TreeNode; newNode->value = num; newNode->left = newNode->right = NULL; if (!root) // Is the tree empty? root = newNode; else { nodePtr = root;
1539
The insertNode Member Function
while (nodePtr != NULL) { if (num < nodePtr->value) { if (nodePtr->left) nodePtr = nodePtr->left; else { nodePtr->left = newNode; break; } }
1540
The insertNode Member Function
else if (num > nodePtr->value) { if (nodePtr->right) nodePtr = nodePtr->right; else { nodePtr->right = newNode; break; } } else { cout << "Duplicate value found in tree.\n"; break; } } } }
1541
Program 20-1 // This program builds a binary tree with 5 nodes. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes. "; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9); cout << "Done.\n"; }
1542
Program 20-1 Figure 20-5 shows the structure of the binary tree built by the program. Note: The shape of the tree is determined by the order in which the values are inserted. The root node in the diagram above holds the value 5 because that was the first value inserted.
1543
Traversing the Tree There are three common methods for traversing a binary tree and processing the value of each node: inorder preorder postorder Each of these methods is best implemented as a recursive function.
1544
Inorder Traversal The node’s left subtree is traversed.
The node’s data is processed. The node’s right subtree is traversed.
1545
Preorder Traversal The node’s data is processed.
The node’s left subtree is traversed. The node’s right subtree is traversed.
1546
Postorder Traversal The node’s left subtree is traversed.
The node’s right subtree is traversed. The node’s data is processed.
1547
The displayInOrder Member Function
void IntBinaryTree::displayInOrder(TreeNode *nodePtr) { if (nodePtr) { displayInOrder(nodePtr->left); cout << nodePtr->value << endl; displayInOrder(nodePtr->right); } }
1548
The displayPreOrder Member Function
void IntBinaryTree::displayPreOrder(TreeNode *nodePtr) { if (nodePtr) { cout << nodePtr->value << endl; displayPreOrder(nodePtr->left); displayPreOrder(nodePtr->right); } }
1549
The displayPostOrder Member Function
void IntBinaryTree::displayPostOrder(TreeNode *nodePtr) { if (nodePtr) { displayPostOrder(nodePtr->left); displayPostOrder(nodePtr->right); cout << nodePtr->value << endl; } }
1550
Program 20-2 // This program builds a binary tree with 5 nodes. // The nodes are displayed with inorder, preorder, // and postorder algorithms. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.\n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9);
1551
Program 20-2 (continued) cout << "Inorder traversal:\n"; tree.showNodesInOrder(); cout << "\nPreorder traversal:\n"; tree.showNodesPreOrder(); cout << "\nPostorder traversal:\n"; tree.showNodesPostOrder(); }
1552
Program 20-2 (continued) Program Output Inserting nodes. Inorder traversal: Preorder traversal:
1553
Program 20-2 (continued) Postorder traversal: 3
1554
Searching the Tree The IntBinaryTree class has a public member function, SearchNode, which returns true if a value is found in the tree, or false otherwise. bool IntBinaryTree::searchNode(int num) { TreeNode *nodePtr = root; while (nodePtr) { if (nodePtr->value == num) return true; else if (num < nodePtr->value) nodePtr = nodePtr->left; else nodePtr = nodePtr->right; } return false; }
1555
Program 20-3 // This program builds a binary tree with 5 nodes. // The SearchNode function determines if the // value 3 is in the tree. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.\n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9);
1556
Program 20-3 (continued) if (tree.searchNode(3)) cout << "3 is found in the tree.\n"; else cout << "3 was not found in the tree.\n"; } Program Output Inserting nodes. 3 is found in the tree.
1557
Deleting a Node We simply find its parent and set the child pointer that links to it to NULL, and then free the node's memory. But what if we want to delete a node that has child nodes? We must delete the node while at the same time preserving the subtrees that the node links to.
1558
Deleting a Node There are two possible situations when we are deleting a non-leaf node: A) the node has one child, or B) the node has two children.
1559
Deleting a Node Figure 20-6 illustrates a tree in which we are about to delete a node with one subtree.
1560
Deleting a Node Figure 20-7 shows how we will link the node's subtree with its parent.
1561
Deleting a Node The problem is not as easily solved, however, when the node we are about to delete has two subtrees. For example, look at Figure 20-8.
1562
Deleting a Node We cannot attach both of the node's subtrees to its parent, so there must be an alternative solution. One way is to attach the node's right subtree to the parent, and then find a position in the right subtree to attach the left subtree. The result is shown in Figure 20-9.
1563
Deleting a Node Figure 20-9.
1564
Deleting a Node To delete a node from the IntBinaryTree, call the public member function remove. The argument is the value of the node that is to be deleted. void IntBinaryTree::remove(int num) { deleteNode(num, root); } The remove member function calls the deleteNode member function. It passes the value of the node to delete, and the root pointer.
1565
The deleteNode Member Function
void IntBinaryTree::deleteNode(int num, TreeNode *&nodePtr) { if (num < nodePtr->value) deleteNode(num, nodePtr->left); else if (num > nodePtr->value) deleteNode(num, nodePtr->right); else makeDeletion(nodePtr); } Notice the declaration of the nodePtr parameter: TreeNode *&nodePtr; nodePtr is not simply a pointer to a TreeNode structure, but a reference to a pointer to a TreeNode structure. Any action performed on nodePtr is actually performed on the argument passed into nodePtr.
1566
The deleteNode Member Function
else makeDeletion(nodePtr); The trailing else statement calls the makeDeletion function, passing nodePtr as its argument. The makeDeletion function actually deletes the node from the tree, and must reattach the deleted node’s subtrees. Therefore, it must have access to the actual pointer in the binary tree to the node that is being deleted. This is why the nodePtr parameter in the deleteNode function is a reference.
1567
The makeDeletion Member Function
void IntBinaryTree::makeDeletion(TreeNode *&nodePtr) { TreeNode *tempNodePtr; // Temporary pointer, used in // reattaching the left subtree. if (nodePtr == NULL) cout << "Cannot delete empty node.\n"; else if (nodePtr->right == NULL) { tempNodePtr = nodePtr; nodePtr = nodePtr->left; // Reattach the left child delete tempNodePtr; } else if (nodePtr->left == NULL) { tempNodePtr = nodePtr; nodePtr = nodePtr->right; // Reattach the right child delete tempNodePtr; }
1568
The makeDeletion Member Function (continued)
// If the node has two children. else { // Move one node the right. tempNodePtr = nodePtr->right; // Go to the end left node. while (tempNodePtr->left) tempNodePtr = tempNodePtr->left; // Reattach the left subtree. tempNodePtr->left = nodePtr->left; tempNodePtr = nodePtr; // Reattach the right subtree. nodePtr = nodePtr->right; delete tempNodePtr; } }
1569
Program 20-4 // This program builds a binary tree with 5 nodes. // The DeleteNode function is used to remove two // of them. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.\n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9); cout << "Here are the values in the tree:\n"; tree.showNodesInOrder();
1570
Program 20-4 (continued) cout << "Deleting 8...\n"; tree.remove(8); cout << "Deleting 12...\n"; tree.remove(12); cout << "Now, here are the nodes:\n"; tree.showNodesInOrder(); }
1571
Program 20-4 (continued) Program Output
Inserting nodes. Here are the values in the tree: Deleting 8... Deleting Now, here are the nodes: 3 5 9
1572
Template Considerations for Binary Trees
When designing your template, remember that any data types stored in the binary tree must support the <, >, and == operators. If you use the tree to store class objects, these operators must be overridden.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.