SlideShare a Scribd company logo
20
Most read
25
Most read
36
Most read
PROGRAMACIÓN EN C++
Transparencias del libro Starting out with C++ : early objects, Tony Gaddis, Judy Walters, Godfrey Muganda
Chapter 1: Introduction to Computers and
Programming
Topics
1.1 Why Program?
1.2 Computer Systems: Hardware and
Software
1.3 Programs and Programming Languages
1.4 What Is a Program Made of?
1.5 Input, Processing, and Output
1.6 The Programming Process
1-3
1.1 Why Program?
Computer – programmable machine designed to
follow instructions
Program/Software – instructions in computer
memory to make it do something
Programmer – person who writes instructions
(programs) to make computer perform a task
SO, without programmers, no programs; without
programs, the computer cannot do anything
1-4
1.2 Computer Systems: Hardware and
Software
Hardware – Physical components of a
computer
Main Hardware Component Categories
1. Central Processing Unit (CPU)
2. Main memory (RAM)
3. Secondary storage devices
4. Input Devices
5. Output Devices
1-5
Main Hardware Component Categories
1-6
Central Processing Unit (CPU)
CPU – Hardware
component that runs
programs
Includes
• Control Unit
– Retrieves and decodes
program instructions
– Coordinates computer
operations
• Arithmetic & Logic Unit
(ALU)
– Performs mathematical
operations
1-7
The CPU's Role in Running a Program
Cycle through:
• Fetch: get the next program instruction
from main memory
• Decode: interpret the instruction and
generate a signal
• Execute: route the signal to the
appropriate component to perform an
operation
1-8
Main Memory
• Holds both program instructions and data
• Volatile – erased when program
terminates or computer is turned off
• Also called Random Access Memory
(RAM)
1-9
Main Memory Organization
• Bit
– Smallest piece of memory
– Stands for binary digit
– Has values 0 (off) or 1 (on)
• Byte
– Is 8 consecutive bits
– Has an address
• Word
– Usually 4 consecutive bytes
1-10
0 1 1 0 0 1 1 1
8 bits
1 byte
Secondary Storage
• Non-volatile - data retained when
program is not running or computer is
turned off
• Comes in a variety of media
– magnetic: floppy or hard disk drive,
internal or external
– optical: CD or DVD drive
– flash: USB flash drive
1-11
Input Devices
• Used to send information to the
computer from outside
• Many devices can provide input
– keyboard, mouse, microphone, scanner,
digital camera, disk drive, CD/DVD drive,
USB flash drive
1-12
Output Devices
• Used to send information from the
computer to the outside
• Many devices can be used for output
– Computer screen, printer, speakers, disk
drive, CD/DVD recorder, USB flash drive
1-13
Software Programs That Run on a
Computer
• System software
– programs that manage the computer hardware and the
programs that run on the computer
– Operating Systems
• Controls operation of computer
• Manages connected devices
• Runs programs
– Utility Programs
• Support programs that enhance computer operations
• Examples: anti-virus software, data backup, data compression
– Software development tools
• Used by programmers to create software
• Examples: compilers, integrated development environments
(IDEs)
1-14
1.3 Programs and Programming
Languages
• Program
a set of instructions directing a computer to
perform a task
• Programming Language
a language used to write programs
1-15
Algorithm
Algorithm: a set of steps to perform a task
or to solve a problem
Order is important. Steps must be
performed sequentially
1-16
Programs and Programming Languages
Types of languages
– Low-level: used for communication with
computer hardware directly.
– High-level: closer to human language
1-17
From a High-level Program to an
Executable File
a) Create file containing the program with a
text editor.
b) Run preprocessor to convert source file
directives to source code program
statements.
c) Run compiler to convert source program
statements into machine instructions.
1-18
From a High-level Program to an
Executable File
d) Run linker to connect hardware-specific
library code to machine instructions,
producing an executable file.
Steps b) through d) are often performed by a
single command or button click.
Errors occuring at any step will prevent
execution of the following steps.
1-19
From a High-level Program to an
Executable File
1-20
1.4 What Is a Program Made Of?
Common elements in programming
languages:
– Key Words
– Programmer-Defined Identifiers
– Operators
– Punctuation
– Syntax
1-21
Example Program
#include <iostream>
using namespace std;
int main()
{
double num1 = 5,
num2, sum;
num2 = 12;
sum = num1 + num2;
cout << "The sum is " << sum;
return 0;
}
1-22
Key Words
• Also known as reserved words
• Have a special meaning in C++
• Can not be used for another purpose
• Written using lowercase letters
• Examples in program (shown in green):
using namespace std;
int main()
1-23
Programmer-Defined Identifiers
• Names made up by the programmer
• Not part of the C++ language
• Used to represent various things, such as
variables (memory locations)
• Example in program (shown in green):
double num1
1-24
Operators
• Used to perform operations on data
• Many types of operators
– Arithmetic: +, -, *, /
– Assignment: =
• Examples in program (shown in green):
num2 = 12;
sum = num1 + num2;
1-25
Punctuation
• Characters that mark the end of a
statement, or that separate items in a list
• Example in program (shown in green):
double num1 = 5,
num2, sum;
num2 = 12;
1-26
Lines vs. Statements
In a source file,
A line is all of the characters entered before a
carriage return.
Blank lines improve the readability of a
program.
Here are four sample lines. Line 3 is blank:
1. double num1 = 5, num2, sum;
2. num2 = 12;
3.
4. sum = num1 + num2;
1-27
Lines vs. Statements
In a source file,
A statement is an instruction to the computer to
perform an action.
A statement may contain keywords, operators,
programmer-defined identifiers, and
punctuation.
A statement may fit on one line, or it may
occupy multiple lines.
Here is a single statement that uses two lines:
double num1 = 5,
num2, sum;
1-28
Variables
• A variable is a named location in computer memory (in
RAM)
• It holds a piece of data. The data that it holds may
change while the program is running.
• The name of the variable should reflect its purpose
• It must be defined before it can be used. Variable
definitions indicate the variable name and the type of
data that it can hold.
• Example variable definition:
double num1;
1-29
1.5 Input, Processing, and Output
Three steps that many programs perform
1) Gather input data
- from keyboard
- from files on disk drives
2) Process the input data
3) Display the results as output
- send it to the screen or a printer
- write it to a file
1-30
1.6 The Programming Process
1. Define what the program is to do.
2. Visualize the program running on the
computer.
3. Use design tools to create a model of the
program.
Hierarchy charts, flowcharts, pseudocode, etc.
4. Check the model for logical errors.
5. Write the program source code.
6. Compile the source code.
1-31
The Programming Process (cont.)
7. Correct any errors found during compilation.
8. Link the program to create an executable file.
9. Run the program using test data for input.
10. Correct any errors found while running the
program.
Repeat steps 4 - 10 as many times as necessary.
11. Validate the results of the program.
Does the program do what was defined in step 1?
1-32
Chapter 2: Introduction to C++
Topics
2.1 The Parts of a C++ Program
2.2 The cout Object
2.3 The #include Directive
2.4 Standard and Prestandard C++
2.5 Variables, Literals, and the Assignment
Statement
2.6 Identifiers
2.7 Integer Data Types
2.8 Floating-Point Data Types
2-34
Topics (continued)
2.9 The char Data Type
2.10 The C++ string Class
2.11 The bool Data Type
2.12 Determining the Size of a Data Type
2.13 More on Variable Assignments and
Initialization
2.14 Scope
2.15 Arithmetic Operators
2.16 Comments
2-35
2.1 The Parts of a C++ Program
// sample C++ program
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, there!";
return 0;
}
2-36
comment
preprocessor directive
which namespace to use
beginning of function named main
beginning of block for main
output statement
send 0 back to operating system
end of block for main
2.1 The Parts of a C++ Program
2-37
Statement Purpose
// sample C++ program comment
#include <iostream> preprocessor directive
using namespace std; which namespace to use
int main() beginning of function named main
{ beginning of block for main
cout << "Hello, there!"; output statement
return 0; send 0 back to the operating system
} end of block for main
Special Characters
2-38
Character Name Description
// Double Slash Begins a comment
# Pound Sign Begins preprocessor directive
< > Open, Close Brackets Encloses filename used in
#include directive
( ) Open, Close Parentheses Used when naming function
{ } Open, Close Braces Encloses a group of statements
" " Open, Close Quote Marks Encloses string of characters
; Semicolon Ends a programming statement
Important Details
• C++ is case-sensitive. Uppercase and
lowercase characters are different
characters. ‘Main’ is not the same as
‘main’.
• Every { must have a corresponding }, and
vice-versa.
2-39
2.2 The cout Object
• Displays information on computer screen
• Use << to send information to cout
cout << "Hello, there!";
• Can use << to send multiple items to cout
cout << "Hello, " << "there!";
Or
cout << "Hello, ";
cout << "there!";
2-40
Starting a New Line
• To get multiple lines of output on screen
- Use endl
cout << "Hello, there!" << endl;
- Use n in an output string
cout << "Hello, there!n";
2-41
Escape Sequences – More Control Over
Output
2-42
2.3 The #include Directive
• Inserts the contents of another file into the
program
• Is a preprocessor directive
– Not part of the C++ language
– Not seen by compiler
• Example:
#include <iostream>
2-43
No ; goes
here
2.4 Standard and Prestandard C++
Prestandard (Older-style) C++ programs
• Use .h at end of header files
#include <iostream.h>
• Do not use using namespace convention
• May not use return 0; at the end of function
main
• May not compile with a standard C++ compiler
2-44
2.5 Variables, Literals, and the
Assignment Statement
• Variable
– Has a name and a type of data it can hold
char letter;
– Is used to reference a location in memory where a
value can be stored
– Must be defined before it can be used
– The value that is stored can be changed, i.e., it can
“vary”
2-45
variable
name
data type
Variables
– If a new value is stored in the variable, it
replaces the previous value
– The previous value is overwritten and can no
longer be retrieved
int age;
age = 17; // age is 17
cout << age; // Displays 17
age = 18; // Now age is 18
cout << age; // Displays 18
2-46
Assignment Statement
• Uses the = operator
• Has a single variable on the left side and a
value on the right side
• Copies the value on the right into the
variable on the left
item = 12;
2-47
Constants
Literal
– Data item whose value does not change
during program execution
– Is also called a constant
'A' // character constant
"Hello" // string literal
12 // integer constant
3.14 // floating-point constant
2-48
2.6 Identifiers
• Programmer-chosen names to represent parts of the
program, such as variables
• Name should indicate the use of the identifier
• Cannot use C++ key words as identifiers
• Must begin with alphabetic character or _, followed
by alphabetic, numeric, or _ . Alphabetic characters
may be upper- or lowercase
2-49
Multi-word Variable Names
• Descriptive variable names may include multiple words
• Two conventions to use in naming variables:
– Capitalize all but first letter of first word. Run words together:
quantityOnOrder
totalSales
– Use the underscore _ character as a space:
quantity_on_order
total_sales
• Use one convention consistently throughout program
2-50
Valid and Invalid Identifiers
2-51
IDENTIFIER VALID? REASON IF INVALID
totalSales Yes
total_Sales Yes
total.Sales No Cannot contain period
4thQtrSales No Cannot begin with digit
totalSale$ No Cannot contain $
2.7 Integer Data Types
• Designed to hold whole (non-decimal)
numbers
• Can be signed or unsigned
12 -6 +3
• Available in different sizes (i.e., number of
bytes): short, int, and long
• Size of short ≤ size of int ≤ size of long
2-52
Signed vs. Unsigned Integers
• C++ allocates one bit for the sign of the
number. The rest of the bits are for data.
• If your program will never need negative
numbers, you can declare variables to be
unsigned. All bits in unsigned numbers
are used for data.
• A variable is signed unless the unsigned
keyword is used.
2-53
Defining Variables
• Variables of the same type can be defined
- In separate statements
int length;
int width;
- In the same statement
int length,
width;
• Variables of different types must be defined
in separate statements
2-54
Integral Constants
• To store an integer constant in a long
memory location, put ‘L’ at the end of the
number: 1234L
• Constants that begin with ‘0’ (zero) are
octal, or base 8: 075
• Constants that begin with ‘0x’ are
hexadecimal, or base 16: 0x75A
2-55
2.8 Floating-Point Data Types
• Designed to hold real numbers
12.45 -3.8
• Stored in a form similar to scientific notation
• Numbers are all signed
• Available in different sizes (number of bytes):
float, double, and long double
• Size of float ≤ size of double
≤ size of long double
2-56
Floating-point Constants
• Can be represented in
- Fixed point (decimal) notation:
31.4159 0.0000625
- E notation:
3.14159E1 6.25e-5
• Are double by default
• Can be forced to be float 3.14159F or
long double 0.0000625L
2-57
Assigning Floating-point Values to
Integer Variables
If a floating-point value is assigned to an
integer variable
– The fractional part will be truncated (i.e.,
“chopped off” and discarded)
– The value is not rounded
int rainfall = 3.88;
cout << rainfall; // Displays 3
2-58
2.9 The char Data Type
• Used to hold single characters or very small
integer values
• Usually occupies 1 byte of memory
• A numeric code representing the character
is stored in memory
2-59
SOURCE CODE MEMORY
char letter = 'C'; letter
67
Character Literal
• A character literal is a single character
• When referenced in a program, it is
enclosed in single quotation marks:
cout << 'Y' << endl;
• The quotation marks are not part of the
literal, and are not displayed
2-60
String Literals
• Can be stored as a series of characters in
consecutive memory locations
"Hello"
• Stored with the null terminator, 0,
automatically placed at the end
• Is comprised of characters between the " "
2-61
H e l l o 0
A character or a string literal?
• A character literal is a single character,
enclosed in single quotes:
'C'
• A string literal is a sequence of characters
enclosed in double quotes:
"Hello, there!"
• A single character in double quotes is a
string literal, not a character literal:
"C"
2-62
2.10 The C++ string Class
• Must #include <string> to create and
use string objects
• Can define string variables in programs
string name;
• Can assign values to string variables with the
assignment operator
name = "George";
• Can display them with cout
cout << "My name is " << name;
2-63
2.11 The bool Data Type
• Represents values that are true or false
• bool values are stored as integers
• false is represented by 0, true by 1
bool allDone = true;
bool finished = false;
2-64
allDone finished
1 0
2.12 Determining the Size of a Data Type
The sizeof operator gives the size in
number of bytes of any data type or variable
double amount;
cout << "A float is stored in "
<< sizeof(float) << " bytesn";
cout << "Variable amount is stored in "
<< sizeof(amount) << " bytesn";
2-65
2.13 More on Variable Assignments and
Initialization
Assigning a value to a variable
– Assigns a value to a previously created variable
– A single variable name must appear on left side
of the = symbol
int size;
size = 5; // legal
5 = size; // not legal
2-66
Variable Assignment vs. Initialization
Initializing a variable
– Gives an initial value to a variable at the time
it is created
– Can initialize some or all of the variables
being defined
int length = 12;
int width = 7, height = 5, area;
2-67
2.14 Scope
• The scope of a variable is that part of the
program where the variable may be used
• A variable cannot be used before it is defined
int num1 = 5;
cout >> num1; // legal
cout >> num2; // illegal
int num2 = 12;
2-68
2.15 Arithmetic Operators
• Used for performing numeric calculations
• C++ has unary, binary, and ternary
operators
– unary (1 operand) -5
– binary (2 operands) 13 - 7
– ternary (3 operands) exp1 ? exp2 : exp3
2-69
Binary Arithmetic Operators
2-70
SYMBOL OPERATION EXAMPLE ans
+ addition ans = 7 + 3; 10
- subtraction ans = 7 - 3; 4
* multiplication ans = 7 * 3; 21
/ division ans = 7 / 3; 2
% modulus ans = 7 % 3; 1
/ Operator
• C++ division operator (/)performs integer
division if both operands are integers
cout << 13 / 5; // displays 2
cout << 2 / 4; // displays 0
• If either operand is floating-point, the result
is floating-point
cout << 13 / 5.0; // displays 2.6
cout << 2.0 / 4; // displays 0.5
2-71
% Operator
• C++ modulus operator (%) computes the
remainder resulting from integer division
cout << 9 % 2; // displays 1
• % requires integers for both operands
cout << 9 % 2.0; // error
2-72
2.16 Comments
• Are used to document parts of a program
• Are written for persons reading the source
code of the program
– Indicate the purpose of the program
– Describe the use of variables
– Explain complex sections of code
• Are ignored by the compiler
2-73
Single-Line Comments
• Begin with // and continue to the end of line
int length = 12; // length in inches
int width = 15; // width in inches
int area; // calculated area
// Calculate rectangle area
area = length * width;
2-74
Multi-Line Comments
• Begin with /* and end with */
• Can span multiple lines
/*----------------------------
Here's a multi-line comment
----------------------------*/
• Can also be used as single-line
comments
int area; /* Calculated area */
2-75
Chapter 3: Expressions and Interactivity
Topics
3.1 The cin Object
3.2 Mathematical Expressions
3.3 Data Type Conversion and Type Casting
3.4 Overflow and Underflow
3.5 Named Constants
3-77
Topics (continued)
3.6 Multiple and Combined Assignment
3.7 Formatting Output
3.8 Working with Characters and Strings
3.9 Using C-Strings
3.10 More Mathematical Library Functions
3-78
3.1 The cin Object
• Standard input object
• Like cout, requires iostream file
• Used to read input from keyboard
• Often used with cout to display a user
prompt first
• Data is retrieved from cin with >>
• Input data is stored in one or more
variables
3-79
The cin Object
• User input goes from keyboard to the input
buffer, where it is stored as characters
• cin converts the data to the type that
matches the variable
int height;
cout << "How tall is the room? ";
cin >> height;
3-80
The cin Object
• Can be used to input multiple values
cin >> height >> width;
• Multiple values from keyboard must be
separated by spaces or [Enter]
• Must press [Enter] after typing last value
• Multiple values need not all be of the same type
• Order is important; first value entered is stored
in first variable, etc.
3-81
3.2 Mathematical Expressions
• An expression can be a constant, a
variable, or a combination of constants
and variables combined with operators
• Can create complex expressions using
multiple mathematical operators
• Examples of mathematical expressions:
2
height
a + b / c
3-82
Using Mathematical Expressions
• Can be used in assignment statements, with
cout, and in other types of statements
• Examples:
area = 2 * PI * radius;
cout << "border is: " << (2*(l+w));
3-83
This is an
expression
These are
expressions
Order of Operations
• In an expression with > 1 operator,
evaluate in this order
( ) expressions in parentheses
- (unary negation) in order, left to right
* / % in order, left to right
+ - in order, left to right
• In the expression 2 + 2 * 2 – 2 ,
3-84
Do first:
Do next:
Do next:
Evaluate
1st
Evaluate
2nd
Evaluate
3rd
Do last:
Associativity of Operators
• - (unary negation) associates right to left
• * / % + - all associate left to right
• parentheses ( ) can be used to override the
order of operations
2 + 2 * 2 – 2 = 4
(2 + 2) * 2 – 2 = 6
2 + 2 * (2 – 2) = 2
(2 + 2) * (2 – 2) = 0
3-85
Algebraic Expressions
• Multiplication requires an operator
Area = lw is written as Area = l * w;
• There is no exponentiation operator
Area = s2 is written as Area = pow(s, 2);
(note: pow requires the cmath header file)
• Parentheses may be needed to maintain order of
operations
is written as
m = (y2-y1)/(x2-x1);
3-86
1
2
1
2
x
x
y
y
m
−
−
=
3.3 Data Type Conversion
and Type Casting
• Operations are performed between
operands of the same type
• If operands do not have the same type,
C++ will automatically convert one to be
the type of the other
• This can impact the results of calculations
3-87
Hierarchy of Data Types
• Highest
• Lowest
• Ranked by largest number they can hold
3-88
long double
double
float
unsigned long
long
unsigned int
int
Type Coercion
• Coercion: automatic conversion of an
operand to another data type
• Promotion: converts to a higher type
• Demotion: converts to a lower type
3-89
Coercion Rules
1) char, short, unsigned short are
automatically promoted to int
2) When operating on values of different
data types, the lower-ranked one is
promoted to the type of the higher one.
3) When using the = operator, the type of
expression on right will be converted to
the type of variable on left
3-90
Coercion Rules – Important Notes
1) If demotion is required to use the =
operator,
- the stored result may be incorrect if there
is not enough space available in the
receiving variable
- floating-point values are truncated when
assigned to integer variables
2) Coercion affects the value used in a
calculation. It does not change the
type associated with a variable.
3-91
Type Casting
• Used for manual data type conversion
• Format
static_cast<Data Type>(Value)
• Example:
cout << static_cast<int>(4.2);
// Displays 4
3-92
More Type Casting Examples
char ch = 'C';
cout << ch << " is stored as "
<< static_cast<int>(ch);
gallons = static_cast<int>(area/500);
avg = static_cast<double>(sum)/count;
3-93
Older Type Cast Styles
double Volume = 21.58;
int intVol1, intVol2;
intVol1 = (int) Volume; // C-style
// cast
intVol2 = int (Volume); //Prestandard
// C++ style
// cast
C-style cast uses prefix notation
Prestandard C++ cast uses functional notation
static_cast is the current standard
3-94
3.4 Overflow and Underflow
• Occurs when assigning a value that is too
large (overflow) or too small (underflow) to
be held in a variable
• The variable contains a value that is
‘wrapped around’ the set of possible values
3-95
Overflow Example
// Create a short int initialized to
// the largest value it can hold
short int num = 32767;
cout << num; // Displays 32767
num = num + 1;
cout << num; // Displays -32768
3-96
Handling Overflow and Underflow
Different systems handle the problem
differently. They may
– display a warning / error message, or display a
dialog box and ask what to do
– stop the program
– continue execution with the incorrect value
3-97
3.5 Named Constants
• Also called constant variables
• Variables whose content cannot be changed
during program execution
• Used for representing constant values with
descriptive names
const double TAX_RATE = 0.0675;
const int NUM_STATES = 50;
• Often named in uppercase letters
3-98
Benefits of Named Constants
• Makes program code more readable by
documenting the purpose of the constant in
the name:
const double TAX_RATE = 0.0675;
…
salesTax = purchasePrice * TAX_RATE;
• Simplifies program maintenance:
const double TAX_RATE = 0.0725;
3-99
const vs. #define
#define
– C-style of naming constants
#define NUM_STATES 50
– Interpreted by pre-processor rather than
compiler
– Does not occupy a memory location like a
constant variable defined with const
– Instead, causes a text substitution to occur. In
above example, every occurrence in program of
NUM_STATES will be replaced by 50
3-100
no ;
goes here
3.6 Multiple and Combined Assignment
• The assignment operator (=) can be used
multiple times in an expression
x = y = z = 5;
• Associates right to left
x = (y = (z = 5));
3-101
Done Done Done
3rd 2nd 1st
Combined Assignment
• Applies an arithmetic operation to a
variable and assigns the result as the new
value of that variable
• Operators: += -= *= /= %=
• Also called compound operators or
arithmetic assignment operators
• Example:
sum += amt; is short for sum = sum + amt;
3-102
More Examples
x += 5; means x = x + 5;
x -= 5; means x = x – 5;
x *= 5; means x = x * 5;
x /= 5; means x = x / 5;
x %= 5; means x = x % 5;
The right hand side is evaluated before the
combined assignment operation is done.
x *= a + b; means x = x * (a + b);
3-103
3.7 Formatting Output
• Can control how output displays for
numeric and string data
– size
– position
– number of digits
• Requires iomanip header file
3-104
Stream Manipulators
• Used to control features of an output field
• Some affect just the next value displayed
–setw(x): Print in a field at least x spaces
wide. It will use more spaces if specified field
width is not big enough.
3-105
Stream Manipulators
• Some affect values until changed again
– fixed: Use decimal notation (not E-notation) for
floating-point values.
– setprecision(x):
• When used with fixed, print floating-point value using x
digits after the decimal.
• Without fixed, print floating-point value using x significant
digits.
– showpoint: Always print decimal for floating-point
values.
– left, right: left-, right justification of value
3-106
Manipulator Examples
const float e = 2.718;
float price = 18.0; Displays
cout << setw(8) << e << endl; ^^^2.718
cout << left << setw(8) << e
<< endl; 2.718^^^
cout << setprecision(2);
cout << e << endl; 2.7
cout << fixed << e << endl; 2.72
cout << setw(6) << price; ^18.00
3-107
3.8 Working with Characters and Strings
• char: holds a single character
• string: holds a sequence of characters
• Both can be used in assignment statements
• Both can be displayed with cout and <<
3-108
String Input
Reading in a string object
string str;
cin >> str; // Reads in a string
// with no blanks
getline(cin, str); // Reads in a string
// that may contain
// blanks
3-109
Character Input
Reading in a character:
char ch;
cin >> ch; // Reads in any non-blank char
cin.get(ch); // Reads in any char
ch = cin.get;// Reads in any char
cin.ignore();// Skips over next char in
// the input buffer
3-110
String Operators
= Assigns a value to a string
string words;
words = "Tasty ";
+ Joins two strings together
string s1 = "hot", s2 = "dog";
string food = s1 + s2; // food = "hotdog"
+= Concatenates a string onto the end of another one
words += food; // words now = "Tasty hotdog"
3-111
string Member Functions
• length() – the number of characters in a string
string firstPrez="George Washington";
int size=firstPrez.length(); // size is 17
• assign() – put repeated characters in a string.
Can be used for formatting output.
string equals;
equals.assign(80,'=');
…
cout << equals << endl;
cout << "Total: " << total << endl;
3-112
3.9 Using C-Strings
• C-string is stored as an array of characters
• Programmer must indicate maximum number of
characters at definition
const int SIZE = 5;
char temp[SIZE] = "Hot";
• NULL character (0) is placed after final
character to mark the end of the string
• Programmer must make sure array is big enough
for desired use; temp can hold up to 4
characters plus the 0.
3-113
H o t 0
C-String Input
• Reading in a C-string
const int SIZE = 10;
char Cstr[SIZE];
cin >> Cstr; // Reads in a C-string with no
// blanks. Will write past the
// end of the array if input string
// is too long.
cin.getline(Cstr, 10);
// Reads in a C-string that may
// contain blanks. Ensures that <= 9
// chars are read in.
• Can also use setw() and width() to control input field
widths
3-114
C-String Initialization vs. Assignment
• A C-string can be initialized at the time of its
creation, just like a string object
const int SIZE = 10;
char month[SIZE] = "April";
• However, a C-string cannot later be assigned a
value using the = operator; you must use the
strcpy() function
char month[SIZE];
month = "August" // wrong!
strcpy(month, "August"); //correct
3-115
C-String and Keyboard Input
• Must use cin.getline()to put keyboard input
into a C-string
• Note that cin.getline() ≠ getline()
• Must indicate the target C-string and maximum
number of characters to read:
const int SIZE = 25;
char name[SIZE];
cout << "What's your name? ";
cin.getline(name, SIZE);
3-116
3.10 More Mathematical Library
Functions
• These require cmath header file
• Take double arguments and return a
double
• Commonly used functions
3-117
abs Absolute value
sin Sine
cos Cosine
tan Tangent
sqrt Square root
log Natural (e) log
pow Raise to a power
More Mathematical Library Functions
These require cstdlib header file
• rand
– Returns a random number between 0 and the
largest int the computer holds
– Will yield the same sequence of numbers each
time the program is run
• srand(x)
– Initializes random number generator with
unsigned int x. x is the “seed value”.
– Should be called at most once in a program
3-118
More on Random Numbers
• Use time() to generate different seed values
each time that a program runs:
#include <ctime> //needed for time()
…
unsigned seed = time(0);
srand(seed);
• Random numbers can be scaled to a range:
int max=6;
int num;
num = rand() % max + 1;
3-119
Chapter 4: Making Decisions
Topics
4.1 Relational Operators
4.2 The if Statement
4.3 The if/else Statement
4.4 The if/else if Statement
4.5 Menu-Driven Programs
4.6 Nested if Statements
4.7 Logical Operators
4-121
Topics (continued)
4.8 Validating User Input
4.9 More About Block and Scope
4.10 More About Characters and Strings
4.11 The Conditional Operator
4.12 The switch Statement
4.13 Enumerated Data Types
4-122
4.1 Relational Operators
• Used to compare numeric values to
determine relative order
• Operators:
4-123
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
== Equal to
!= Not equal to
Relational Expressions
• Relational expressions are Boolean
(i.e., evaluate to true or false)
• Examples:
12 > 5 is true
7 <= 5 is false
if x is 10, then
x == 10 is true,
x <= 8 is false,
x != 8 is true, and
x == 8 is false
4-124
Relational Expressions
• Can be assigned to a variable
bool result = (x <= y);
• Assigns 0 for false, 1 for true
• Do not confuse = (assignment) and ==
(equal to)
4-125
4.2 The if Statement
• Supports the use of a decision structure
• Allows statements to be conditionally
executed or skipped over
• Models the way we mentally evaluate
situations
“If it is cold outside,
wear a coat and wear a hat.”
4-126
Format of the if Statement
if (condition)
{
statement1;
statement2;
…
statementn;
}
The block inside the braces is called the body
of the if statement. If there is only 1 statement
in the body, the { } may be omitted.
4-127
No
; goes here
; goes here
How the if Statement Works
• If (condition) is true, then the
statement(s) in the body are executed.
• If (condition) is false, then the
statement(s) are skipped.
4-128
if Statement Flow of Control
4-129
condition
1 or more
statements
true false
Example if Statements
if (score >= 60)
cout << "You passed." << endl;
if (score >= 90)
{
grade = 'A';
cout << "Wonderful job!" << endl;
}
4-130
if Statement Notes
• if is a keyword. It must be lowercase
• (condition)must be in ( )
• Do not place ; after (condition)
• Don't forget the { } around a multi-statement
body
4-131
if Statement Style Recommendations
• Place each statement; on a separate
line after (condition)
• Indent each statement in the body
• When using { and } around the body, put {
and } on lines by themselves
4-132
What is true and false?
• An expression whose value is 0 is
considered false.
• An expression whose value is non-zero is
considered true.
• An expression need not be a comparison –
it can be a single variable or a
mathematical expression.
4-133
Flag
• A variable that signals a condition
• Usually implemented as a bool
• Meaning:
– true: the condition exists
– false: the condition does not exist
• The flag value can be both set and tested
with if statements
4-134
Flag Example
Example:
bool validMonths = true;
…
if (months < 0)
validMonths = false;
…
if (validMonths)
moPayment = total / months;
4-135
Integer Flags
• Integer variables can be used as flags
• Remember that 0 means false, any other
value means true
int allDone = 0; // set to false
…
if (count > MAX_STUDENTS)
allDone = 1; // set to true
…
if (allDone)
cout << "Task finished";
4-136
4.3 The if/else Statement
• Allows a choice between statements
depending on whether (condition) is true
or false
• Format: if (condition)
{
statement set 1;
}
else
{
statement set 2;
}
4-137
How the if/else Works
• If (condition) is true, statement
set 1 is executed and statement set 2
is skipped.
• If (condition) is false, statement
set 1 is skipped and statement set 2
is executed.
4-138
if/else Flow of Control
4-139
condition
statement
set 1
true false
statement
set 2
Example if/else Statements
if (score >= 60)
cout << "You passed.n";
else
cout << "You did not pass.n";
if (intRate > 0)
{ interest = loanAmt * intRate;
cout << interest;
}
else
cout << "You owe no interest.n";
4-140
Comparisons with floating-point numbers
• It is difficult to test for equality when
working with floating point numbers.
• It is better to use
– greater than, less than tests, or
– test to see if value is very close to a given
value
4-141
4.4 The if/else if Statement
• Chain of if statements that test in order
until one is found to be true
• Also models thought processes
“If it is raining, take an umbrella,
else, if it is windy, take a hat,
else, if it is sunny, take sunglasses.”
4-142
if/else if Format
if (condition 1)
{ statement set 1;
}
else if (condition 2)
{ statement set 2;
}
…
else if (condition n)
{ statement set n;
}
4-143
Using a Trailing else
• Used with if/else if statement when all
of the conditions are false
• Provides a default statement or action that
is performed when none of the conditions is
true
• Can be used to catch invalid values or
handle other exceptional situations
4-144
Example if/else if with Trailing else
if (age >= 21)
cout << "Adult";
else if (age >= 13)
cout << "Teen";
else if (age >= 2)
cout << "Child";
else
cout << "Baby";
4-145
4.5 Menu-Driven Program
• Menu: list of choices presented to the user
on the computer screen
• Menu-driven program: program execution
controlled by user selecting from a list of
actions
• Menu can be implemented using
if/else if statements
4-146
Menu-driven Program Organization
• Display list of numbered or lettered choices
for actions.
• Input user’s selection of number or letter
• Test user selection in (condition)
– if a match, then execute code to carry out
desired action
– if not, then test with next (condition)
4-147
4.6 Nested if Statements
• An if statement that is part of the if or
else part of another if statement
• Can be used to evaluate > 1 data item or
condition
if (score < 100)
{
if (score > 90)
grade = 'A';
}
4-148
Notes on Coding Nested ifs
• An else matches the nearest previous if
that does not have an else
if (score < 100)
if (score > 90)
grade = 'A';
else ... // goes with second if,
// not first one
• Proper indentation aids comprehension
4-149
4.7 Logical Operators
Used to create relational expressions from
other relational expressions
4-150
Operator Meaning Explanation
&& AND New relational expression is true if both
expressions are true
|| OR New relational expression is true if either
expression is true
! NOT
Reverses the value of an expression; true
expression becomes false, false
expression becomes true
Logical Operator Examples
int x = 12, y = 5, z = -4;
•
(x > y) && (y > z) true
(x > y) && (z > y) false
(x <= z) || (y == z) false
(x <= z) || (y != z) true
!(x >= z) false
4-151
Logical Precedence
Highest !
&&
Lowest ||
Example:
(2 < 3) || (5 > 6) && (7 > 8)
is true because AND is evaluated before OR
4-152
More on Precedence
Example:
8 < 2 + 7 || 5 == 6 is true
4-153
logical operators
Lowest
relational operators
arithmetic operators
Highest
Checking Numeric Ranges with
Logical Operators
• Used to test if a value is within a range
if (grade >= 0 && grade <= 100)
cout << "Valid grade";
• Can also test if a value lies outside a range
if (grade <= 0 || grade >= 100)
cout << "Invalid grade";
• Cannot use mathematical notation
if (0 <= grade <= 100) //Doesn’t
//work!
4-154
4.8 Validating User Input
• Input validation: inspecting input data to
determine if it is acceptable
• Want to avoid accepting bad input
• Can perform various tests
– Range
– Reasonableness
– Valid menu choice
– Zero as a divisor
4-155
4.9 More About Blocks and Scope
• Scope of a variable is the block in which it
is defined, from the point of definition to the
end of the block
• Variables are usually defined at the
beginning of a function
• They may instead be defined close to the
place where they are first used
4-156
More About Blocks and Scope
• Variables defined inside { } have local or
block scope
• When in a block that is nested inside
another block, you can define variables
with the same name as in the outer block.
– When the program is executing in the inner
block, the outer definition is not available
– This is generally not a good idea
4-157
4.10 More About Characters and Strings
• Can use relational operators with characters and
string objects
if (menuChoice == 'A')
if (firstName == "Beth")
• Comparing characters is really comparing ASCII
values of characters
• Comparing string objects is comparing the ASCII
values of the characters in the strings. Comparison
is character-by-character
• Cannot compare C-style strings with relational
operators
4-158
Testing Characters
require cctype header file
FUNCTION MEANING
isalpha true if arg. is a letter, false otherwise
isalnum true if arg. is a letter or digit, false
otherwise
isdigit true if arg. is a digit 0-9, false otherwise
islower true if arg. is lowercase letter, false
otherwise
12-159
Character Testing
require cctype header file
FUNCTION MEANING
isprint true if arg. is a printable character, false
otherwise
ispunct true if arg. is a punctuation character,
false otherwise
isupper true if arg. is an uppercase letter, false
otherwise
isspace true if arg. is a whitespace character, false
otherwise
12-160
4.11 The Conditional Operator
• Can use to create short if/else
statements
• Format: expr ? expr : expr;
4-161
4.12 The switch Statement
• Used to select among statements from
several alternatives
• May sometimes be used instead of
if/else if statements
4-162
switch Statement Format
switch (IntExpression)
{
case exp1: statement set 1;
case exp2: statement set 2;
...
case expn: statement set n;
default: statement set n+1;
}
4-163
switch Statement Requirements
1) IntExpression must be a char or an
integer variable or an expression that
evaluates to an integer value
2) exp1 through expn must be constant
integer type expressions and must be
unique in the switch statement
3) default is optional but recommended
4-164
How the switch Statement Works
1) IntExpression is evaluated
2) The value of intExpression is compared
against exp1 through expn.
3) If IntExpression matches value expi, the
program branches to the statement(s) following
expi and continues to the end of the switch
4) If no matching value is found, the program
branches to the statement after default:
4-165
The break Statement
• Used to stop execution in the current block
• Also used to exit a switch statement
• Useful to execute a single case statement
without executing statements following it
4-166
Example switch Statement
switch (gender)
{
case 'f': cout << "female";
break;
case 'm': cout << "male";
break;
default : cout << "invalid gender";
}
4-167
Using switch with a Menu
switch statement is a natural choice for
menu-driven program
– display menu
– get user input
– use user input as IntExpression in switch
statement
– use menu choices as exp to test against in the
case statements
4-168
4.13 Enumerated Data Types
• Data type created by programmer
• Contains a set of named constant integers
• Format:
enum name {val1, val2, … valn};
• Examples:
enum Fruit {apple, grape, orange};
enum Days {Mon, Tue, Wed, Thur, Fri};
4-169
Enumerated Data Type Variables
• To define variables, use the enumerated
data type name
Fruit snack;
Days workDay, vacationDay;
• Variable may contain any valid value for the
data type
snack = orange; // no quotes
if (workDay == Wed) // none here
4-170
Enumerated Data Type Values
• Enumerated data type values are
associated with integers, starting at 0
enum Fruit {apple, grape, orange};
• Can override default association
enum Fruit {apple = 2, grape = 4,
orange = 5}
4-171
0 1 2
Enumerated Data Type Notes
• Enumerated data types improve the
readability of a program
• Enumerated variables can not be used with
input statements, such as cin
• Will not display the name associated with
the value of an enumerated data type if
used with cout
4-172
Chapter 5: Looping
Topics
5.1 Introduction to Loops: The while Loop
5.2 Using the while loop for Input Validation
5.3 The Increment and Decrement Operators
5.4 Counters
5.5 The do-while loop
5.6 The for loop
5.7 Keeping a Running Total
5-174
Topics (continued)
5.8 Sentinels
5.9 Deciding Which Loop to Use
5.10 Nested Loops
5.11 Breaking Out of a Loop
5.12 Using Files for Data Storage
5.13 Creating Good Test Data
5-175
5.1 Introduction to Loops:
The while Loop
• Loop: part of program that may execute > 1
time (i.e., it repeats)
• while loop format:
while (condition)
{ statement(s);
}
• The {} can be omitted if there is only one
statement in the body of the loop
5-176
No ; here
How the while Loop Works
while (condition)
{ statement(s);
}
condition is evaluated
– if it is true, the statement(s) are executed,
and then condition is evaluated again
– if it is false, the loop is exited
An iteration is an execution of the loop body
5-177
while Loop Flow of Control
5-178
true
statement(s)
false
condition
while Loop Example
int val = 5;
while (val >= 0)
{ cout << val << " ";
val = val - 1;
}
• produces output:
5 4 3 2 1 0
5-179
while Loop is a Pretest Loop
• while is a pretest loop (condition is evaluated
before the loop executes)
• If the condition is initially false, the statement(s) in
the body of the loop are never executed
• If the condition is initially true, the statement(s) in
the body will continue to be executed until the
condition becomes false
5-180
Exiting the Loop
• The loop must contain code to allow
condition to eventually become false
so the loop can be exited
• Otherwise, you have an infinite loop (i.e., a
loop that does not stop)
• Example infinite loop:
x = 5;
while (x > 0) // infinite loop because
cout << x; // x is always > 0
5-181
Common Loop Errors
• Don’t put ; immediately after (condition)
• Don’t forget the { } :
int numEntries = 1;
while (numEntries <=3)
cout << "Still working … ";
numEntries++; // not in the loop body
• Don’t use = when you mean to use ==
while (numEntries = 3) // always true
{
cout << "Still working … ";
numEntries++;
}
5-182
while Loop Programming Style
• Loop body statements should be indented
• Align { and } with the loop header and place
them on lines by themselves
Note: The conventions above make the
program more understandable by someone
who is reading it. They have no effect on how
the the program compiles or executes.
5-183
5.2 Using the while Loop for Input
Validation
Loops are an appropriate structure for
validating user input data
1. Prompt for and read in the data.
2. Use a while loop to test if data is valid.
3. Enter the loop only if data is not valid.
4. Inside the loop, display error message and
prompt the user to re-enter the data.
5. The loop will not be exited until the user
enters valid data.
5-184
Input Validation Loop Example
cout << "Enter a number (1-100) and"
<< " I will guess it. ";
cin >> number;
while (number < 1 || number > 100)
{ cout << "Number must be between 1 and 100."
<< " Re-enter your number. ";
cin >> number;
}
// Code to use the valid number goes here.
5-185
5.3 The Increment and Decrement
Operators
• Increment – increase value in variable
++ adds one to a variable
val++; is the same as val = val + 1;
• Decrement – reduce value in variable
-- subtracts one from a variable
val--; is the same as val = val – 1;
• can be used in prefix mode (before) or
postfix mode (after) a variable
5-186
Prefix Mode
• ++val and --val increment or decrement
the variable, then return the new value of
the variable.
• It is this returned new value of the variable
that is used in any other operations within
the same statement
5-187
Prefix Mode Example
int x = 1, y = 1;
x = ++y; // y is incremented to 2
// Then 2 is assigned to x
cout << x
<< " " << y; // Displays 2 2
x = --y; // y is decremented to 1
// Then 1 is assigned to x
cout << x
<< " " << y; // Displays 1 1
5-188
Postfix Mode
• val++ and val-- return the old value of
the variable, then increment or decrement
the variable
• It is this returned old value of the variable
that is used in any other operations within
the same statement
5-189
Postfix Mode Example
int x = 1, y = 1;
x = y++; // y++ returns a 1
// The 1 is assigned to x
// and y is incremented to 2
cout << x
<< " " << y; // Displays 1 2
x = y--; // y-- returns a 2
// The 2 is assigned to x
// and y is decremented to 1
cout << x
<< " " << y; // Displays 2 1
5-190
Increment & Decrement Notes
• Can be used in arithmetic expressions
result = num1++ + --num2;
• Must be applied to something that has a
location in memory. Cannot have
result = (num1 + num2)++; // Illegal
• Can be used in relational expressions
if (++num > limit)
• Pre- and post-operations will cause different
comparisons
5-191
5.4 Counters
• Counter: variable that is incremented or
decremented each time a loop repeats
• Can be used to control execution of the
loop (loop control variable)
• Must be initialized before entering loop
• May be incremented/decremented either
inside the loop or in the loop test
5-192
Letting the User Control the Loop
• Program can be written so that user input
determines loop repetition
• Can be used when program processes a list
of items, and user knows the number of
items
• User is prompted before loop. Their input is
used to control number of repetitions
5-193
User Controls the Loop Example
int num, limit;
cout << "Table of squaresn";
cout << "How high to go? ";
cin >> limit;
cout << "nnnumber squaren";
num = 1;
while (num <= limit)
{ cout << setw(5) << num << setw(6)
<< num*num << endl;
num++;
}
5-194
5.5 The do-while Loop
• do-while: a post test loop (condition
is evaluated after the loop executes)
• Format:
do
{ 1 or more statements;
} while (condition);
5-195
Notice the
required ;
do-while Flow of Control
5-196
statement(s)
condition
false
true
do-while Loop Notes
• Loop always executes at least once
• Execution continues as long as
condition is true; the loop is exited
when condition becomes false
• { } are required, even if the body contains
a single statement
• ; after (condition) is also required
5-197
do-while and Menu-Driven Programs
• do-while can be used in a menu-driven
program to bring the user back to the
menu to make another choice
• To simplify the processing of user input,
use the toupper (‘to upper’) or tolower
(to lower’) function
5-198
Menu-Driven Program Example
do {
// code to display menu
// and perform actions
cout << "Another choice? (Y/N) ";
} while (choice =='Y'||choice =='y');
The condition could be written as
(toupper(choice) == 'Y');
or as
(tolower(choice) == 'y');
5-199
5.6 The for Loop
• Pretest loop that executes zero or more times
• Useful for counter-controlled loop
• Format:
for( initialization; test; update )
{ 1 or more statements;
}
5-200
No ; goes
here
Required ;
for Loop Mechanics
5-201
for Loop Flow of Control
5-202
true
statement(s)
false
test
initialization
code
update
code
for Loop Example
int sum = 0, num;
for (num = 1; num <= 10; num++)
sum += num;
cout << "Sum of numbers 1 – 10 is "
<< sum << endl;
5-203
for Loop Notes
• If test is false the first time it is evaluated,
the body of the loop will not be executed
• The update expression can increment or
decrement by any amount
• Variables used in the initialization section
should not be modified in the body of the
loop
5-204
for Loop Modifications
• Can define variables in initialization code
– Their scope is the for loop
• Initialization and update code can contain
more than one statement
– Separate the statements with commas
• Example:
for (int sum = 0, num = 1; num <= 10; num++)
sum += num;
5-205
More for Loop Modifications
(These are NOT Recommended)
• Can omit initialization if already done
int sum = 0, num = 1;
for (; num <= 10; num++)
sum += num;
• Can omit update if done in loop
for (sum = 0, num = 1; num <= 10;)
sum += num++;
• Can omit test – may cause an infinite loop
for (sum = 0, num = 1; ; num++)
sum += num;
• Can omit loop body if all work is done in header
5-206
5.7 Keeping a Running Total
• running total: accumulated sum of numbers
from each repetition of loop
• accumulator: variable that holds running total
int sum = 0, num = 1; // sum is the
while (num <= 10) // accumulator
{ sum += num;
num++;
}
cout << "Sum of numbers 1 – 10 is "
<< sum << endl;
5-207
5.8 Sentinels
• sentinel: value in a list of values that
indicates end of the list
• Special value that cannot be confused with
a valid value, e.g., -999 for a test score
• Used to terminate input when user may not
know how many values will be entered
5-208
Sentinel Example
int total = 0;
cout << "Enter points earned "
<< "(or -1 to quit): ";
cin >> points;
while (points != -1) // -1 is the sentinel
{
total += points;
cout << "Enter points earned: ";
cin >> points;
}
5-209
5.9 Deciding Which Loop to Use
• while: pretest loop (loop body may not
be executed at all)
• do-while: post test loop (loop body will
always be executed at least once)
• for: pretest loop (loop body may not be
executed at all); has initialization and
update code; is useful with counters or if
precise number of repetitions is known
5-210
5.10 Nested Loops
• A nested loop is a loop inside the body of
another loop
• Example:
for (row = 1; row <= 3; row++)
{
for (col = 1; col <= 3; col++)
{
cout << row * col << endl;
}
}
5-211
outer loop
inner loop
Notes on Nested Loops
• Inner loop goes through all its repetitions
for each repetition of outer loop
• Inner loop repetitions complete sooner than
outer loop
• Total number of repetitions for inner loop is
product of number of repetitions of the two
loops. In previous example, inner loop
repeats 9 times
5-212
5.11 Breaking Out of a Loop
• Can use break to terminate execution of
a loop
• Use sparingly if at all – makes code harder
to understand
• When used in an inner loop, terminates
that loop only and returns to the outer loop
5-213
The continue Statement
• Can use continue to go to end of loop
and prepare for next repetition
– while and do-while loops go to test and
repeat the loop if test condition is true
– for loop goes to update step, then tests, and
repeats loop if test condition is true
• Use sparingly – like break, can make
program logic hard to follow
5-214
5.12 Using Files for Data Storage
• We can use a file instead of monitor screen
for program output
• Files are stored on secondary storage media,
such as disk
• Files allow data to be retained between
program executions
• We can later use the file instead of a
keyboard for program input
3-215
File Types
• Text file – contains information encoded as
text, such as letters, digits, and punctuation.
Can be viewed with a text editor such as
Notepad.
• Binary file – contains binary (0s and 1s)
information that has not been encoded as
text. It cannot be viewed with a text editor.
3-216
File Access – Ways to Use
the Data in a File
• Sequential access – read the 1st piece of
data, read the 2nd piece of data, …, read the
last piece of data. To access the n-th piece
of data, you have to retrieve the preceding n
pieces first.
• Random (direct) access – retrieve any piece
of data directly, without the need to retrieve
preceding data items.
3-217
What is Needed to Use Files
1. Include the fstream header file
2. Define a file stream object
• ifstream for input from a file
ifstream inFile;
• ofstream for output to a file
ofstream outFile;
3-218
Open the File
3. Open the file
• Use the open member function
inFile.open("inventory.dat");
outFile.open("report.txt");
• Filename may include drive, path info.
• Output file will be created if necessary;
existing output file will be erased first
• Input file must exist for open to work
3-219
Use the File
4. Use the file
• Can use output file object and << to send
data to a file
outFile << "Inventory report";
• Can use input file object and >> to copy
data from file to variables
inFile >> partNum;
inFile >> qtyInStock >> qtyOnOrder;
3-220
Close the File
5. Close the file
• Use the close member function
inFile.close();
outFile.close();
• Don’t wait for operating system to close
files at program end
– There may be limit on number of open files
– There may be buffered output data waiting
to be sent to a file that could be lost
3-221
Can use a file instead of keyboard for program input
Input File – the Read Position
• Read Position – location of the next piece
of data in an input file
• Initially set to the first byte in the file
• Advances for each data item that is read.
Successive reads will retrieve successive
data items.
3-222
Using Loops to Process Files
• A loop can be used to read data from or
write data to a file
• It is not necessary to know how much data
is in the file or will be written to the file
• Several methods exist to test for the end of
the file
5-223
Using the >> Operator to Test for End of
File (EOF) on an Input File
• The stream extraction operator (>>) returns a
true or false value indicating if a read is
successful
• This can be tested to find the end of file since
the read “fails” when there is no more data
• Example:
while (inFile >> score)
sum += score;
5-224
File Open Errors
• An error will occur if an attempt to open a file
for input fails:
– File does not exist
– Filename is misspelled
– File exists, but is in a different place
• The file stream object is set to true if the open
operation succeeded. It can be tested to see
if the file can be used:
if (inFile)
{
// process data from file
} else
cout << "Error on file openn";
5-225
User-Specified Filenames
• Program can prompt user to enter the names
of input and/or output files. This makes the
program more versatile.
• Filenames can be read into string objects. The
C-string representation of the string object can
then be passed to the open function:
cout << "Which input file? ";
cin >> inputFileName;
inFile.open(inputFileName.c_str());
5-226
5.13 Creating Good Test Data
• When testing a program, the quality of the
test data is more important than the
quantity.
• Test data should show how different parts
of the program execute
• Test data should evaluate how program
handles:
– normal data
– data that is at the limits the valid range
– invalid data
5-227
See pr5-09.cpp
Chapter 6: Functions
Topics
6.1 Modular Programming
6.2 Defining and Calling Functions
6.3 Function Prototypes
6.4 Sending Data into a Function
6.5 Passing Data by Value
6.6 The return Statement
6.7 Returning a Value from a Function
6.8 Returning a Boolean Value
6-229
Topics (continued)
6.9 Using Functions in a Menu-Driven Program
6.10 Local and Global Variables
6.11 Static Local Variables
6.12 Default Arguments
6.13 Using Reference Variables as Parameters
6.14 Overloading Functions
6.15 The exit() Function
6.16 Stubs and Drivers
6-230
6.1 Modular Programming
• Modular programming: breaking a program
up into smaller, manageable functions or
modules. Supports the divide-and-conquer
approach to solving a problem.
• Function: a collection of statements to
perform a specific task
• Motivation for modular programming
– Simplifies the process of writing programs
– Improves maintainability of programs
6-231
6.2 Defining and Calling Functions
• Function call: a statement that causes a
function to execute
• Function definition: the statements that
make up a function
6-232
Function Definition
• Definition includes
name: name of the function. Function names
follow same rules as variable names
parameter list: variables that hold the values
passed to the function
body: statements that perform the function’s task
return type: data type of the value the function
returns to the part of the program that called it
6-233
Function Definition
6-234
Function Header
• The function header consists of
– the function return type
– the function name
– the function parameter list
• Example:
int main()
• Note: no ; at the end of the header
6-235
Function Return Type
• If a function returns a value, the type of
the value must be indicated
int main()
• If a function does not return a value, its
return type is void
void printHeading()
{
cout << "tMonthly Salesn";
}
6-236
Calling a Function
• To call a function, use the function name
followed by () and ;
printHeading();
• When a function is called, the program
executes the body of the function
• After the function terminates, execution
resumes in the calling module at the
point of call
6-237
Calling a Function
• main is automatically called when the
program starts
• main can call any number of functions
• Functions can call other functions
6-238
6.3 Function Prototypes
The compiler must know the following
about a function before it is called
– name
– return type
– number of parameters
– data type of each parameter
6-239
Function Prototypes
Ways to notify the compiler about a
function before a call to the function:
– Place function definition before calling
function’s definition
– Use a function prototype (similar to the
heading of the function
• Heading: void printHeading()
• Prototype: void printHeading();
– Function prototype is also called a function
declaration
6-240
Prototype Notes
• Place prototypes near top of program
• Program must include either prototype or
full function definition before any call to the
function, otherwise a compiler error occurs
• When using prototypes, function definitions
can be placed in any order in the source
file. Traditionally, main is placed first.
6-241
6.4 Sending Data into a Function
• Can pass values into a function at time of call
c = sqrt(a*a + b*b);
• Values passed to function are arguments
• Variables in function that hold values passed
as arguments are parameters
• Alternate names:
– argument: actual argument, actual parameter
– parameter: formal argument, formal parameter
6-242
Parameters, Prototypes,
and Function Headings
• For each function argument,
– the prototype must include the data type of each
parameter in its ()
void evenOrOdd(int); //prototype
– the heading must include a declaration, with variable
type and name, for each parameter in its ()
void evenOrOdd(int num) //heading
• The function call for the above function would look
like this: evenOrOdd(val); //call
Note: no data type on argument in call
6-243
Function Call Notes
• Value of argument is copied into parameter
when the function is called
• Function can have > 1 parameter
• There must be a data type listed in the
prototype () and an argument declaration in
the function heading () for each parameter
• Arguments will be promoted/demoted as
necessary to match parameters. Be careful!
6-244
Calling Functions with Multiple Arguments
When calling a function with multiple
arguments
– the number of arguments in the call must
match the function prototype and definition
– the first argument will be copied into the
first parameter, the second argument into
the second parameter, etc.
6-245
Calling Functions with
Multiple Arguments Illustration
displayData(height, weight); // call
void displayData(int h, int w)// heading
{
cout << "Height = " << h << endl;
cout << "Weight = " << w << endl;
}
6-246
6.5 Passing Data by Value
• Pass by value: when an argument is
passed to a function, a copy of its value is
placed in the parameter
• The function cannot access the original
argument
• Changes to the parameter in the function
do not affect the value of the argument in
the calling function
6-247
Passing Data to Parameters by Value
• Example: int val = 5;
evenOrOdd(val);
• evenOrOdd can change variable num, but
it will have no effect on variable val
6-248
5
val
argument in
calling function
5
num
parameter in
evenOrOdd function
6.6 The return Statement
• Used to end execution of a function
• Can be placed anywhere in a function
– Statements that follow the return
statement will not be executed
• Can be used to prevent abnormal
termination of program
• Without a return statement, the
function ends at its last }
6-249
6.7 Returning a Value from a Function
• return statement can be used to return a
value from the function to the module that
made the function call
• Prototype and definition must indicate data
type of return value (not void)
• Calling function should use return value, e.g.,
– assign it to a variable
– send it to cout
– use it in an arithmetic computation
– use it in a relational expression
6-250
Returning a Value – the return
Statement
• Format: return expression;
• expression may be a variable, a literal
value, or an expression.
• expression should be of the same data
type as the declared return type of the
function (will be converted if not)
6-251
6.8 Returning a Boolean Value
• Function can return true or false
• Declare the return type in the function
prototype and heading as bool
• The function body must contain return
statement(s) that return true or false
• The calling function can use the return
value in a relational expression
6-252
Boolean return Example
bool isValid(int); // prototype
bool isValid(int val) // heading
{
int min = 0, max = 100;
if (val >= min && val <= max)
return true;
else
return false;
}
if (isValid(score)) // call
…
6-253
6.9 Using Functions in a Menu-Driven
Program
Functions can be used
• to implement user choices from menu
• to implement general-purpose tasks
- Higher-level functions can call general-purpose
functions
- This minimizes the total number of functions
and speeds program development time
6-254
6.10 Local and Global Variables
• local variable: defined within a function or
block; accessible only within the function or
block
• Other functions and blocks can define
variables with the same name
• When a function is called, local variables in
the calling function are not accessible from
within the called function
6-255
Local Variable Lifetime
• A local variable only exists while its
defining function is executing
• Local variables are destroyed when the
function terminates
• Data cannot be retained in local
variables between calls to the function in
which they are defined
6-256
Local and Global Variables
• global variable: a variable defined
outside all functions; it is accessible to
all functions within its scope
• Easy way to share large amounts of
data between functions
• Scope of a global variable is from its
point of definition to the program end
• Use sparingly
6-257
Initializing Local and Global Variables
• Local variables must be initialized by the
programmer
• Global variables are initialized to 0
(numeric) or NULL (character) when the
variable is defined. These can be
overridden with explicit initial values.
6-258
Global Variables – Why Use Sparingly?
Global variables make:
• Programs that are difficult to debug
• Functions that cannot easily be re-used in
other programs
• Programs that are hard to understand
6-259
Global Constants
• A global constant is a named constant that
can be used by every function in a program
• It is useful if there are unchanging values
that are used throughout the program
• They are safer to use than global variables,
since the value of a constant cannot be
modified during program execution
6-260
Local and Global Variable Names
• Local variables can have same names as
global variables
• When a function contains a local variable
that has the same name as a global
variable, the global variable is unavailable
from within the function. The local definition
"hides" or "shadows" the global definition.
6-261
6.11 Static Local Variables
• Local variables
– Only exist while the function is executing
– Are redefined each time function is called
– Lose their contents when function terminates
• static local variables
– Are defined with key word static
static int counter;
– Are defined and initialized only the first time the
function is executed
– Retain their contents between function calls
6-262
6.12 Default Arguments
• Values passed automatically if arguments
are missing from the function call
• Must be a constant declared in prototype
or header (whichever occurs first)
void evenOrOdd(int = 0);
• Multi-parameter functions may have default
arguments for some or all parameters
int getSum(int, int=0, int=0);
6-263
Default Arguments
• If not all parameters to a function have
default values, the ones without defaults
must be declared first in the parameter list
int getSum(int, int=0, int=0);// OK
int getSum(int, int=0, int); // wrong!
• When an argument is omitted from a function
call, all arguments after it must also be
omitted
sum = getSum(num1, num2); // OK
sum = getSum(num1, , num3); // wrong!
6-264
6.13 Using Reference Variables as
Parameters
• Mechanism that allows a function to work
with the original argument from the
function call, not a copy of the argument
• Allows the function to modify values
stored in the calling environment
• Provides a way for the function to ‘return’
more than 1 value
6-265
Reference Variables
• A reference variable is an alias for
another variable
• It is defined with an ampersand (&) in
the prototype and in the header
void getDimensions(int&, int&);
• Changes to a reference variable are
made to the variable it refers to
• Use reference variables to implement
passing parameters by reference
6-266
Pass by Reference Example
void squareIt(int &); //prototype
void squareIt(int &num)
{
num *= num;
}
int localVar = 5;
squareIt(localVar); // localVar now
// contains 25
6-267
Reference Variable Notes
• Each reference parameter must contain &
• Argument passed to reference parameter must
be a variable. It cannot be an expression or a
constant.
• Use only when appropriate, such as when the
function must input or change the value of the
argument passed to it
• Files (i.e., file stream objects) should be
passed by reference
6-268
6.14 Overloading Functions
• Overloaded functions are two or more
functions that have the same name, but different
parameter lists
• Can be used to create functions that perform the
same task, but take different parameter types or
different number of parameters
• Compiler will determine which version of the
function to call by the argument and parameter
list
6-269
Overloaded Functions Example
If a program has these overloaded functions,
void getDimensions(int); // 1
void getDimensions(int, int); // 2
void getDimensions(int, float); // 3
void getDimensions(double, double);// 4
then the compiler will use them as follows:
int length, width;
double base, height;
getDimensions(length); // 1
getDimensions(length, width); // 2
getDimensions(length, height); // 3
getDimensions(height, base); // 4
6-270
6.15 The exit() Function
• Terminates execution of a program
• Can be called from any function
• Can pass a value to operating system to
indicate status of program execution
• Usually used for abnormal termination of
program
• Requires cstdlib header file
• Use with care
6-271
exit() – Passing Values to Operating
System
• Use an integer value to indicate program
status
• Often, 0 means successful completion,
non-zero indicates a failure condition
• Can use named constants defined in
cstdlib:
– EXIT_SUCCESS and
– EXIT_FAILURE
6-272
6.16 Stubs and Drivers
• Stub: dummy function in place of actual
function
• Usually displays a message indicating it
was called. May also display parameters
• Driver: function that tests a function by
calling it
• Stubs and drivers are useful for testing
and debugging program logic and design
6-273
Chapter 7: Introduction to Classes and
Objects
Topics
7.1 Abstract Data Types
7.2 Object-Oriented Programming
7.3 Introduction to Classes
7.4 Creating and Using Objects
7.5 Defining Member Functions
7.6 Constructors
7.7 Destructors
7.8 Private Member Functions
7-275
Topics (Continued)
7.9 Passing Objects to Functions
7.10 Object Composition
7.11 Separating Class Specification,
Implementation, and Client Code
7.12 Structures
7.14 Introduction to Object-Oriented Analysis and
Design
7.15 Screen Control
7-276
7.1 Abstract Data Types
• Programmer-created data types that
specify
– legal values that can be stored
– operations that can be done on the values
• The user of an abstract data type (ADT)
does not need to know any implementation
details (e.g., how the data is stored or how the
operations on it are carried out)
7-277
Abstraction in Software Development
• Abstraction allows a programmer to design a
solution to a problem and to use data items
without concern for how the data items are
implemented
• This has already been encountered in the book:
– To use the pow function, you need to know what
inputs it expects and what kind of results it
produces
– You do not need to know how it works
7-278
Abstraction and Data Types
• Abstraction: a definition that captures
general characteristics without details
ex: An abstract triangle is a 3-sided polygon. A
specific triangle may be scalene, isosceles, or
equilateral
• Data Type: defines the kind of values that
can be stored and the operations that can
be performed on it
7-279
7.2 Object-Oriented Programming
• Procedural programming uses variables to
store data, and focuses on the processes/
functions that occur in a program. Data
and functions are separate and distinct.
• Object-oriented programming is based on
objects that encapsulate the data and the
functions that operate on it.
7-280
Object-Oriented Programming
Terminology
• object: software entity that combines data
and functions that act on the data in a single
unit
• attributes: the data items of an object,
stored in member variables
• member functions (methods): procedures/
functions that act on the attributes of the
class
7-281
More Object-Oriented Programming
Terminology
• data hiding: restricting access to certain
members of an object. The intent is to
allow only member functions to directly
access and modify the object’s data
• encapsulation: the bundling of an
object’s data and procedures into a single
entity
7-282
Object Example
7-283
Member variables (attributes)
int side;
Member functions
void setSide(int s)
{ side = s; }
int getSide()
{ return side; }
Square
Square object’s data item: side
Square object’s functions: setSide - set the size of the side of the
square, getSide - return the size of the side of the square
Why Hide Data?
• Protection – Member functions provide a
layer of protection against inadvertent or
deliberate data corruption
• Need-to-know – A programmer can use
the data via the provided member
functions. As long as the member
functions return correct information, the
programmer needn’t worry about
implementation details.
7-284
7.3 Introduction to Classes
• Class: a programmer-defined data type
used to define objects
• It is a pattern for creating objects
ex:
string fName, lName;
creates two objects of the string class
7-285
Introduction to Classes
• Class declaration format:
class className
{
declaration;
declaration;
};
7-286
Notice the
required ;
Access Specifiers
• Used to control access to members of the class.
• Each member is declared to be either
public: can be accessed by functions
outside of the class
or
private: can only be called by or accessed
by functions that are members of
the class
7-287
Class Example
class Square
{
private:
int side;
public:
void setSide(int s)
{ side = s; }
int getSide()
{ return side; }
};
7-288
Access
specifiers
More on Access Specifiers
• Can be listed in any order in a class
• Can appear multiple times in a class
• If not specified, the default is private
7-289
7.4 Creating and Using Objects
• An object is an instance of a class
• It is defined just like other variables
Square sq1, sq2;
• It can access members using dot operator
sq1.setSide(5);
cout << sq1.getSide();
7-290
Types of Member Functions
• Acessor, get, getter function: uses but
does not modify a member variable
ex: getSide
• Mutator, set, setter function: modifies a
member variable
ex: setSide
7-291
7.5 Defining Member Functions
• Member functions are part of a class
declaration
• Can place entire function definition inside
the class declaration
or
• Can place just the prototype inside the
class declaration and write the function
definition after the class
7-292
Defining Member Functions Inside the
Class Declaration
• Member functions defined inside the class
declaration are called inline functions
• Only very short functions, like the one
below, should be inline functions
int getSide()
{ return side; }
7-293
Inline Member Function Example
class Square
{
private:
int side;
public:
void setSide(int s)
{ side = s; }
int getSide()
{ return side; }
};
7-294
inline
functions
Defining Member Functions After the
Class Declaration
• Put a function prototype in the class declaration
• In the function definition, precede the function
name with the class name and scope
resolution operator (::)
int Square::getSide()
{
return side;
}
7-295
Conventions and a Suggestion
Conventions:
• Member variables are usually private
• Accessor and mutator functions are usually
public
• Use ‘get’ in the name of accessor functions, ‘set’
in the name of mutator functions
Suggestion: calculate values to be returned in
accessor functions when possible, to minimize
the potential for stale data
7-296
Tradeoffs of Inline vs. Regular Member
Functions
• When a regular function is called, control
passes to the called function
– the compiler stores return address of call,
allocates memory for local variables, etc.
• Code for an inline function is copied into
the program in place of the call when the
program is compiled
– This makes alarger executable program, but
– There is less function call overhead, and
possibly faster execution
7-297
7.6 Constructors
• A constructor is a member function that is
often used to initialize data members of a
class
• Is called automatically when an object of the
class is created
• It must be a public member function
• It must be named the same as the class
• It must have no return type
7-298
Constructor – 2 Examples
Inline:
class Square
{
. . .
public:
Square(int s)
{ side = s; }
. . .
};
Declaration outside the
class:
Square(int); //prototype
//in class
Square::Square(int s)
{
side = s;
}
7-299
Overloading Constructors
• A class can have more than 1 constructor
• Overloaded constructors in a class must
have different parameter lists
Square();
Square(int);
7-300
The Default Constructor
• Constructors can have any number of
parameters, including none
• A default constructor is one that takes
no arguments either due to
– No parameters or
– All parameters have default values
• If a class has any programmer-defined
constructors, it must have a programmer-
defined default constructor
7-301
Default Constructor Example
class Square
{
private:
int side;
public:
Square() // default
{ side = 1; } // constructor
// Other member
// functions go here
};
7-302
Has no
parameters
Another Default Constructor Example
class Square
{
private:
int side;
public:
Square(int s = 1) // default
{ side = s; } // constructor
// Other member
// functions go here
};
7-303
Has parameter
but it has a
default value
Invoking a Constructor
• To create an object using the default
constructor, use no argument list and no ()
Square square1;
• To create an object using a constructor that
has parameters, include an argument list
Square square1(8);
7-304
7.7 Destructors
• Is a public member function automatically
called when an object is destroyed
• The destructor name is ~className, e.g.,
~Square
• It has no return type
• It takes no arguments
• Only 1 destructor is allowed per class
(i.e., it cannot be overloaded)
7-305
7. 8 Private Member Functions
• A private member function can only
be called by another member function of
the same class
• It is used for internal processing by the
class, not for use outside of the class
7-306
7.9 Passing Objects to Functions
• A class object can be passed as an
argument to a function
• When passed by value, function makes a
local copy of object. Original object in
calling environment is unaffected by actions
in function
• When passed by reference, function can
use ‘set’ functions to modify the object.
7-307
7-308
Notes on Passing Objects
• Using a value parameter for an object can
slow down a program and waste space
• Using a reference parameter speeds up
program, but allows the function to modify
data in the parameter
7-309
Notes on Passing Objects
• To save space and time, while protecting
parameter data that should not be changed,
use a const reference parameter
void showData(const Square &s)
// header
• In order to for the showData function to call
Square member functions, those functions must
use const in their prototype and header:
int Square::getSide() const;
7-310
Returning an Object from a Function
• A function can return an object
Square initSquare(); // prototype
s1 = initSquare(); // call
• The function must define a object
– for internal use
– to use with return statement
7-311
Returning an Object Example
Square initSquare()
{
Square s; // local variable
int inputSize;
cout << "Enter the length of side: ";
cin >> inputSize;
s.setSide(inputSize);
return s;
}
7.10 Object Composition
• Occurs when an object is a member
variable of another object.
• It is often used to design complex objects
whose members are simpler objects
• ex. (from book): Define a rectangle class.
Then, define a carpet class and use a
rectangle object as a member of a carpet
object.
7-312
Object Composition, cont.
7-313
7.11 Separating Class Specification,
Implementation, and Client Code
Separating class declaration, member
function definitions, and the program that
uses the class into separate files is
considered good design
7-314
Using Separate Files
• Place class declaration in a header file that serves
as the class specification file. Name the file
classname.h (for example, Square.h)
• Place member function definitions in a class
implementation file. Name the file classname.cpp
(for example, Square.cpp)This file should
#include the class specification file.
• A client program (client code) that uses the class
must #include the class specification file and be
compiled and linked with the class implementation
file.
7-315
Include Guards
• Used to prevent a header file from being included
twice
• Format:
#ifndef symbol_name
#define symbol_name
. . . (normal contents of header file)
#endif
• symbol_name is usually the name of the header
file, in all capital letters:
#ifndef SQUARE_H
#define SQUARE_H
. . .
#endif
7-316
What Should Be Done Inside vs. Outside
the Class
• Class should be designed to provide
functions to store and retrieve data
• In general, input and output (I/O) should be
done by functions that use class objects,
rather than by class member functions
7-317
7-318
7.12 Structures
• Structure: Programmer-defined data type that
allows multiple variables to be grouped
together
• Structure Declaration Format:
struct structure name
{
type1 field1;
type2 field2;
…
typen fieldn;
};
7-319
Example struct Declaration
struct Student
{
int studentID;
string name;
short year;
double gpa;
};
structure name
structure members
Notice the
required
;
7-320
struct Declaration Notes
• struct names commonly begin with an
uppercase letter
• The structure name is also called the tag
• Multiple fields of same type can be in a
comma-separated list
string name,
address;
• Fields in a structure are all public by
default
7-321
Defining Structure Variables
• struct declaration does not allocate
memory or create variables
• To define variables, use structure tag as
type name
Student s1;
studentID
name
year
gpa
s1
7-322
Accessing Structure Members
• Use the dot (.) operator to refer to
members of struct variables
getline(cin, s1.name);
cin >> s1.studentID;
s1.gpa = 3.75;
• Member variables can be used in any
manner appropriate for their data type
7-323
Displaying struct Members
To display the contents of a struct
variable, you must display each field
separately, using the dot operator
Wrong:
cout << s1; // won’t work!
Correct:
cout << s1.studentID << endl;
cout << s1.name << endl;
cout << s1.year << endl;
cout << s1.gpa;
7-324
Comparing struct Members
• Similar to displaying a struct, you
cannot compare two struct variables
directly:
if (s1 >= s2) // won’t work!
• Instead, compare member variables:
if (s1.gpa >= s2.gpa) // better
7-325
Initializing a Structure
Cannot initialize members in the structure
declaration, because no memory has been
allocated yet
struct Student // Illegal
{ // initialization
int studentID = 1145;
string name = "Alex";
short year = 1;
float gpa = 2.95;
};
7-326
Initializing a Structure (continued)
• Structure members are initialized at the time
a structure variable is created
• Can initialize a structure variable’s members
with either
– an initialization list
– a constructor
7-327
Using an Initialization List
An initialization list is an ordered set of
values, separated by commas and
contained in { }, that provides initial values
for a set of data members
{12, 6, 3} // initialization list
// with 3 values
7-328
More on Initialization Lists
• Order of list elements matters: First value
initializes first data member, second value
initializes second data member, etc.
• Elements of an initialization list can be constants,
variables, or expressions
{12, W, L/W + 1} // initialization list
// with 3 items
7-329
Initialization List Example
Structure Declaration Structure Variable
struct Dimensions
{ int length,
width,
height;
};
Dimensions box = {12,6,3};
box
length 12
width 6
height 3
7-330
Partial Initialization
Can initialize just some members, but
cannot skip over members
Dimensions box1 = {12,6}; //OK
Dimensions box2 = {12,,3}; //illegal
7-331
Problems with Initialization List
• Can’t omit a value for a member without
omitting values for all following members
• Does not work on most modern compilers if
the structure contains any string objects
– Will, however, work with C-string members
7-332
Using a Constructor to Initialize
Structure Members
• Similar to a constructor for a class:
– name is the same as the name of the struct
– no return type
– used to initialize data members
• It is normally written inside the struct
declaration
7-333
A Structure with a Constructor
struct Dimensions
{
int length,
width,
height;
// Constructor
Dimensions(int L, int W, int H)
{length = L; width = W; height = H;}
};
7-334
Nested Structures
A structure can have another structure as a
member.
struct PersonInfo
{ string name,
address,
city;
};
struct Student
{ int studentID;
PersonInfo pData;
short year;
double gpa;
};
7-335
Members of Nested Structures
Use the dot operator multiple times to
access fields of nested structures
Student s5;
s5.pData.name = "Joanne";
s5.pData.city = "Tulsa";
7-336
Structures as Function Arguments
• May pass members of struct variables
to functions
computeGPA(s1.gpa);
• May pass entire struct variables to
functions
showData(s5);
• Can use reference parameter if function
needs to modify contents of structure
variable
7-337
Notes on Passing Structures
• Using a value parameter for structure can
slow down a program and waste space
• Using a reference parameter speeds up
program, but allows the function to modify
data in the structure
• To save space and time, while protecting
structure data that should not be changed,
use a const reference parameter
void showData(const Student &s)
// header
7-338
Returning a Structure from a Function
• Function can return a struct
Student getStuData(); // prototype
s1 = getStuData(); // call
• Function must define a local structure
variable
– for internal use
– to use with return statement
7-339
Returning a Structure Example
Student getStuData()
{ Student s; // local variable
cin >> s.studentID;
cin.ignore();
getline(cin, s.pData.name);
getline(cin, s.pData.address);
getline(cin, s.pData.city);
cin >> s.year;
cin >> s.gpa;
return s;
}
7-340
Unions
• Similar to a struct, but
– all members share a single memory location,
which saves space
– only 1 member of the union can be used at a
time
• Declared using key word union
• Otherwise the same as struct
• Variables defined and accessed like
struct variables
7-341
Example union Declaration
union WageInfo
{
double hourlyRate;
float annualSalary;
};
union tag
Notice the
required
;
union members
7.14 Introduction to Object-Oriented
Analysis and Design
• Object-Oriented Analysis: that phase of program
development when the program functionality is
determined from the requirements
• It includes
– identification of objects and classes
– definition of each class's attributes
– identification of each class's behaviors
– definition of the relationship between classes
7-342
Identify Objects and Classes
• Consider the major data elements and the
operations on these elements
• Candidates include
– user-interface components (menus, text boxes, etc.)
– I/O devices
– physical objects
– historical data (employee records, transaction logs,
etc.)
– the roles of human participants
7-343
Define Class Attributes
• Attributes are the data elements of an
object of the class
• They are necessary for the object to work
in its role in the program
7-344
Define Class Behaviors
• For each class,
– Identify what an object of a class should do in
the program
• The behaviors determine some of the
member functions of the class
7-345
Relationships Between Classes
Possible relationships
– Access ("uses-a")
– Ownership/Composition ("has-a")
– Inheritance ("is-a")
7-346
Finding the Classes
Technique:
• Write a description of the problem domain
(objects, events, etc. related to the problem)
• List the nouns, noun phrases, and pronouns.
These are all candidate objects
• Refine the list to include only those objects that
are relevant to the problem
7-347
Determine Class Responsibilities
Class responsibilities:
• What is the class responsible to know?
• What is the class responsible to do?
Use these to define some of the member
functions
7-348
Object Reuse
• A well-defined class can be used to create
objects in multiple programs
• By re-using an object definition, program
development time is shortened
• One goal of object-oriented programming is
to support object reuse
7-349
7.15 Screen Control
• Programs to date have all displayed output
starting at the upper left corner of computer
screen or output window. Output is
displayed left-to-right, line-by-line.
• Computer operating systems are designed
to allow programs to access any part of the
computer screen. Such access is
operating system-specific.
7-350
Screen Control – Concepts
• An output screen can be thought of as a
grid of 25 rows and 80 columns. Row 0 is
at the top of the screen. Column 0 is at the
left edge of the screen.
• The intersection of a row and a column is a
cell. It can display a single character.
• A cell is identified by its row and column
number. These are its coordinates.
7-351
Screen Control – Windows - Specifics
• #include <windows.h> to access the
operating system from a program
• Create a handle to reference the output
screen:
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
• Create a COORD structure to hold the
coordinates of a cell on the screen:
COORD position;
7-352
Screen Control – Windows –
More Specifics
• Assign coordinates where the output
should appear:
position.X = 30; // column
position.Y = 12; // row
• Set the screen cursor to this cell:
SetConsoleCursorPosition(screen, position);
• Send output to the screen:
cout << "Look at me!" << endl;
– be sure to end with endl, not 'n' or nothing
7-353
Chapter 8: Arrays
Topics
8.1 Arrays Hold Multiple Values
8.2 Accessing Array Elements
8.3 Inputting and Displaying Array Contents
8.4 Array Initialization
8.5 Processing Array Contents
8.6 Using Parallel Arrays
8-355
Topics (continued)
8.7 The typedef Statement
8.8 Arrays as Function Arguments
8.9 Two-Dimensional Arrays
8.10 Arrays with Three or More Dimensions
8.11 Vectors
8.12 Arrays of Objects
8-356
8.1 Arrays Hold Multiple Values
• Array: variable that can store multiple
values of the same type
• Values are stored in consecutive memory
locations
• Declared using [] operator
const int ISIZE = 5;
int tests[ISIZE];
8-357
Array Storage in Memory
The definition
int tests[ISIZE]; // ISIZE is 5
allocates the following memory
8-358
Element 0 Element 1 Element 2 Element 3 Element 4
Array Terminology
In the definition int tests[ISIZE];
– int is the data type of the array elements
– tests is the name of the array
– ISIZE, in [ISIZE], is the size declarator. It
shows the number of elements in the array.
– The size of an array is the number of bytes
allocated for it
(number of elements) * (bytes needed for each element)
8-359
Array Terminology Examples
Examples:
Assumes int uses 4 bytes and double uses 8 bytes
const int ISIZE = 5, DSIZE = 10;
int tests[ISIZE]; // holds 5 ints, array
// occupies 20 bytes
double volumes[DSIZE];// holds 10 doubles,
// array occupies
// 80 bytes
8-360
8.2 Accessing Array Elements
• Each array element has a subscript, used
to access the element.
• Subscripts start at 0
8-361
subscripts 0 1 2 3 4
Accessing Array Elements
Array elements (accessed by array name and
subscript) can be used as regular variables
tests[0] = 79;
cout << tests[0];
cin >> tests[1];
tests[4] = tests[0] + tests[1];
cout << tests; // illegal due to
// missing subscript
8-362
0 1 2 3 4
tests
8.3 Inputting and Displaying
Array Contents
cout and cin can be used to display values
from and store values into an array
const int ISIZE = 5;
int tests[ISIZE]; // Define 5-elt. array
cout << "Enter first test score ";
cin >> tests[0];
8-363
Array Subscripts
• Array subscript can be an integer constant,
integer variable, or integer expression
• Examples: Subscript is
cin >> tests[3]; int constant
cout << tests[i]; int variable
cout << tests[i+j]; int expression
8-364
Accessing All Array Elements
To access each element of an array
– Use a loop
– Let the loop control variable be the array
subscript
– A different array element will be referenced
each time through the loop
for (i = 0; i < 5; i++)
cout << tests[i] << endl;
8-365
Getting Array Data from a File
const int ISIZE = 5, sales[ISIZE];
ifstream dataFile;
datafile.open("sales.dat");
if (!dataFile)
cout << "Error opening data filen";
else
{ // Input daily sales
for (int day = 0; day < ISIZE; day++)
dataFile >> sales[day];
dataFile.close();
}
8-366
No Bounds Checking
• There are no checks in C++ that an array
subscript is in range
• An invalid array subscript can cause program
to overwrite other memory
• Example:
const int ISIZE = 3;
int i = 4;
int num[ISIZE];
num[i] = 25;
8-367
num
[0] [1] [2]
25
Off-By-One Errors
• Most often occur when a program accesses
data one position beyond the end of an
array, or misses the first or last element of
an array.
• Don’t confuse the ordinal number of an
array element (first, second, third) with its
subscript (0, 1, 2)
8-368
8.4 Array Initialization
• Can be initialized during program execution
with assignment statements
tests[0] = 79;
tests[1] = 82; // etc.
• Can be initialized at array definition with an
initialization list
const int ISIZE = 5;
int tests[ISIZE] = {79,82,91,77,84};
8-369
Start at element 0 or 1?
• You may choose to declare arrays to be
one larger than needed. This allows you to
use the element with subscript 1 as the
‘first’ element, etc., and may minimize off-
by-one errors.
• The element with subscript 0 is not used.
• This is most often done when working with
ordered data, e.g., months of the year or
days of the week
8-370
Partial Array Initialization
• If array is initialized at definition with fewer values
than the size declarator of the array, remaining
elements will be set to 0 or the empty string
int tests[ISIZE] = {79, 82};
• Initial values used in order; cannot skip over
elements to initialize noncontiguous range
• Cannot have more values in initialization list than
the declared size of the array
8-371
79 82 0 0 0
Implicit Array Sizing
• Can determine array size by the size of the
initialization list
short quizzes[]={12,17,15,11};
• Must use either array size declarator or
initialization list when array is defined
8-372
12 17 15 11
8.5 Processing Array Contents
• Array elements can be
– treated as ordinary variables of the same type
as the array
– used in arithmetic operations, in relational
expressions, etc.
• Example:
if (principalAmt[3] >= 10000)
interest = principalAmt[3] * intRate1;
else
interest = principalAmt[3] * intRate2;
8-373
Using Increment and Decrement
Operators with Array Elements
When using ++ and -- operators, don’t
confuse the element with the subscript
tests[i]++; // adds 1 to tests[i]
tests[i++]; // increments i, but has
// no effect on tests
8-374
Copying One Array to Another
• Cannot copy with an assignment
statement:
tests2 = tests; //won’t work
• Must instead use a loop to copy element-
by-element:
for (int indx=0; indx < ISIZE; indx++)
tests2[indx] = tests[indx];
8-375
Are Two Arrays Equal?
• Like copying, cannot compare in a single
expression:
if (tests2 == tests)
• Use a while loop with a boolean variable:
bool areEqual=true;
int indx=0;
while (areEqual && indx < ISIZE)
{
if(tests[indx] != tests2[indx]
areEqual = false;
}
8-376
Sum, Average of Array Elements
• Use a simple loop to add together array
elements
float average, sum = 0;
for (int tnum=0; tnum< ISIZE; tnum++)
sum += tests[tnum];
• Once summed, average can be computed
average = sum/ISIZE;
8-377
Largest Array Element
• Use a loop to examine each element and find
the largest element (i.e., one with the largest value)
int largest = tests[0];
for (int tnum = 1; tnum < ISIZE; tnum++)
{ if (tests[tnum] > largest)
largest = tests[tnum];
}
cout << "Highest score is " << largest;
• A similar algorithm exists to find the smallest
element
8-378
Partially-Filled Arrays
• The exact amount of data (and, therefore,
array size) may not be known when a
program is written.
• Programmer makes best estimate for
maximum amount of data, sizes arrays
accordingly. A sentinel value can be used
to indicate end-of-data.
• Programmer must also keep track of how
many array elements are actually used
8-379
Using Arrays vs. Using Simple Variables
• An array is probably not needed if the input
data is only processed once:
– Find the sum or average of a set of numbers
– Find the largest or smallest of a set of values
• If the input data must be processed more
than once, an array is probably a good
idea:
– Calculate the average, then determine and display
which values are above the average and which are
below the average
8-380
C-Strings and string Objects
Can be processed using array name
– Entire string at once, or
– One element at a time by using a subscript
string city;
cout << "Enter city name: ";
cin >> city;
8-381
'S' 'a' 'l' 'e' 'm'
city[0] city[1] city[2] city[3] city[4]
8.6 Using Parallel Arrays
• Parallel arrays: two or more arrays that
contain related data
• Subscript is used to relate arrays
– elements at same subscript are related
• The arrays do not have to hold data of the
same type
8-382
Parallel Array Example
const int ISIZE = 5;
string name[ISIZE]; // student name
float average[ISIZE]; // course average
char grade[ISIZE]; // course grade
8-383
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
name average grade
Parallel Array Processing
const int ISIZE = 5;
string name[ISIZE]; // student name
float average[ISIZE]; // course average
char grade[ISIZE]; // course grade
...
for (int i = 0; i < ISIZE; i++)
cout << " Student: " << name[i]
<< " Average: " << average[i]
<< " Grade: " << grade[i]
<< endl;
8-384
8.7 The typedef Statement
• Creates an alias for a simple or structured
data type
• Format:
typedef existingType newName;
• Example:
typedef unsigned int Uint;
Uint tests[ISIZE]; // array of
// unsigned ints
8-385
Uses of typedef
• Used to make code more readable
• Can be used to create alias for an array of
a particular type
// Define yearArray as a data type
// that is an array of 12 ints
typedef int yearArray[MONTHS];
// Create two of these arrays
yearArray highTemps, lowTemps;
8-386
8.8 Arrays as Function Arguments
• Passing a single array element to a function is no
different than passing a regular variable of that
data type
• Function does not need to know that the value it
receives is coming from an array
displayValue(score[i]); // call
void displayValue(int item) // header
{ cout << item << endl;
}
8-387
Passing an Entire Array
• To define a function that has an array parameter,
use empty [] to indicate the array argument
• To pass an array to a function, just use the array
name
// Function prototype
void showScores(int []);
// Function header
void showScores(int tests[])
// Function call
showScores(tests);
8-388
Passing an Entire Array
• Use the array name, without any brackets, as
the argument
• Can also pass the array size so the function
knows how many elements to process
showScores(tests, 5); // call
void showScores(int[], int); // prototype
void showScores(int A[],
int size) // header
8-389
Using typedef with a Passed Array
Can use typedef to simplify function
prototype and heading
// Make intArray an integer array
// of unspecified size
typedef int intArray[];
// Function prototype
void showScores(intArray, int);
// Function header
void showScores(intArray tests,
int size)
8-390
Modifying Arrays in Functions
• Array parameters in functions are similar to
reference variables
• Changes made to array in a function are
made to the actual array in the calling function
• Must be careful that an array is not
inadvertently changed by a function
• Can use const keyword in prototype and
header to prevent changes
8-391
8.9 Two-Dimensional Arrays
• Can define one array for multiple sets of data
• Like a table in a spreadsheet
• Use two size declarators in definition
int exams[4][3];
8-392
Number
of rows
Number
of cols
Two-Dimensional Array Representation
int exams[4][3];
Use two subscripts to access element
exams[2][2] = 86;
8-393
exams[0][0] exams[0][1] exams[0][2]
exams[1][0] exams[1][1] exams[1][2]
exams[2][0] exams[2][1] exams[2][2]
exams[3][0] exams[3][1] exams[3][2]
columns
r
o
w
s
Initialization at Definition
• Two-dimensional arrays are initialized row-
by-row
int exams[2][2] = { {84, 78},
{92, 97} };
• Can omit inner { }
8-394
84 78
92 97
Passing a Two-Dimensional Array to a
Function
• Use array name and number of columns as
arguments in function call
getExams(exams, 2);
• Use empty [] for row and a size declarator for col
in the prototype and header
// Prototype, where NUM_COLS is 2
void getExams(int[][NUM_COLS], int);
// Header
void getExams
(int exams[][NUM_COLS], int rows)
8-395
Using typedef with a
Two-Dimensional Array
Can use typedef for simpler notation
typedef int intExams[][2];
...
// Function prototype
void getExams(intExams, int);
// Function header
void getExams(intExams exams, int rows)
8-396
2D Array Traversal
• Use nested loops, one for row and one for
column, to visit each array element.
• Accumulators can be used to sum the
elements row-by-row, column-by-column,
or over the entire array.
8-397
8.10 Arrays with Three or More
Dimensions
• Can define arrays with any number of
dimensions
short rectSolid(2,3,5);
double timeGrid(3,4,3,4);
• When used as parameter, specify size of
all but 1st dimension
void getRectSolid(short [][3][5]);
8-398
8.11 Vectors
• Holds a set of elements, like an array
• Flexible number of elements - can grow and shrink
– No need to specify size when defined
– Automatically adds more space as needed
• Defined in the Standard Template Library (STL)
– Covered in a later chapter
• Must include vector header file to use vectors
#include <vector>
8-399
Vectors
• Can hold values of any type
– Type is specified when a vector is defined
vector<int> scores;
vector<double> volumes;
• Can use [] to access elements
8-400
Defining Vectors
• Define a vector of integers (starts with 0 elements)
vector<int> scores;
• Define int vector with initial size 30 elements
vector<int> scores(30);
• Define 20-element int vector and initialize all
elements to 0
vector<int> scores(20, 0);
• Define int vector initialized to size and contents of
vector finals
vector<int> scores(finals);
8-401
Growing a Vector’s Size
• Use push_back member function to add
an element to a full array or to an array
that had no defined size
// Add a new element holding a 75
scores.push_back(75);
• Use size member function to determine
number of elements currently in a vector
howbig = scores.size();
8-402
Removing Vector Elements
• Use pop_back member function to remove
last element from vector
scores.pop_back();
• To remove all contents of vector, use
clear member function
scores.clear();
• To determine if vector is empty, use empty
member function
while (!scores.empty()) ...
8-403
8.14 Arrays of Objects
• Objects can also be used as array elements
class Square
{ private:
int side;
public:
Square(int s = 1)
{ side = s; }
int getSide()
{ return side; }
};
Square shapes[10]; // Create array of 10
// Square objects
8-404
Arrays of Objects
• Like an array of structures, use an array
subscript to access a specific object in the
array
• Then use dot operator to access member
methods of that object
for (i = 0; i < 10; i++)
cout << shapes[i].getSide() << endl;
8-405
Initializing Arrays of Objects
• Can use default constructor to perform same
initialization for all objects
• Can use initialization list to supply specific initial
values for each object
Square shapes[5] = {1,2,3,4,5};
• Default constructor is used for the remaining
objects if initialization list is too short
Square boxes[5] = {1,2,3};
8-406
Initializing Arrays of Objects
If an object is initialized with a constructor
that takes > 1 argument, the initialization
list must include a call to the constructor
for that object
Rectangle spaces[3] =
{ Rectangle(2,5),
Rectangle(1,3),
Rectangle(7,7) };
8-407
8-408
Arrays of Structures
• Structures can be used as array elements
struct Student
{
int studentID;
string name;
short year;
double gpa;
};
const int CSIZE = 30;
Student class[CSIZE]; // Holds 30
// Student structures
8-409
Arrays of Structures
• Use array subscript to access a specific
structure in the array
• Then use dot operator to access members of
that structure
cin >> class[25].studentID;
cout << class[i].name << " has GPA "
<< class[i].gpa << endl;
Chapter 9: Searching, Sorting, and
Algorithm Analysis
Topics
9.1 Introduction to Search Algorithms
9.2 Searching an Array of Objects
9.3 Introduction to Sorting Algorithms
9.4 Sorting an Array of Objects
9.5 Sorting and Searching Vectors
9.6 Introduction to Analysis of Algorithms
9-411
9.1 Introduction to Search Algorithms
• Search: to locate a specific item in a list
(array, vector, etc.) of information
• Two algorithms (methods) considered here:
– Linear search (also called Sequential Search)
– Binary search
9-412
Linear Search Algorithm
Set found to false
Set position to –1
Set index to 0
While index < number of elts and found is false
If list [index] is equal to search value
found = true
position = index
End If
Add 1 to index
End While
Return position
9-413
Linear Search Example
• Array numlist contains
• Searching for the the value 11, linear
search examines 17, 23, 5, and 11
• Searching for the the value 7, linear
search examines 17, 23, 5, 11, 2,
29, and 3
9-414
17 23 5 11 2 29 3
Linear Search Tradeoffs
• Benefits
– Easy algorithm to understand and to implement
– Elements in array can be in any order
• Disadvantage
– Inefficient (slow): for array of N elements, it
examines N/2 elements on average for a value
that is found in the array, N elements for a
value that is not in the array
9-415
Binary Search Algorithm
1. Divide a sorted array into three sections:
– middle element
– elements on one side of the middle element
– elements on the other side of the middle element
2. If the middle element is the correct value, done.
Otherwise, go to step 1, using only the half of the
array that may contain the correct value.
3. Continue steps 1 and 2 until either the value is
found or there are no more elements to examine.
9-416
Binary Search Example
• Array numlist2 contains
• Searching for the the value 11, binary
search examines 11 and stops
• Searching for the the value 7, binary
search examines 11, 3, 5, and stops
9-417
2 3 5 11 17 23 29
Binary Search Tradeoffs
• Benefit
– Much more efficient than linear search. For an
array of N elements, it performs at most
log2N comparisons.
• Disadvantage
– Requires that array elements be sorted
9-418
9.2 Searching an Array of Objects
• Search algorithms are not limited to
arrays of integers
• When searching an array of objects or
structures, the value being searched for
is a member of an object or structure,
not the entire object or structure
• Member in object/structure: key field
• Value used in search: search key
9-419
9.3 Introduction to Sorting Algorithms
• Sort: arrange values into an order
– Alphabetical
– Ascending (smallest to largest) numeric
– Descending (largest to smallest) numeric
• Two algorithms considered here
– Bubble sort
– Selection sort
9-420
Bubble Sort Algorithm
1. Compare 1st two elements and exchange them if
they are out of order.
2. Move down one element and compare 2nd and 3rd
elements. Exchange if necessary. Continue until
the end of the array.
3. Pass through the array again, repeating the
process and exchanging as necessary.
4. Repeat until a pass is made with no exchanges.
9-421
Bubble Sort Example
Array numlist3 contains
9-422
First, compare values 17
and 23. In correct order,
so no exchange.
Finally, compare values
23 and 11. Not in correct
order, so exchange them.
17 23 5 11
Then, compare values
23 and 5. Not in correct
order, so exchange them.
Bubble Sort Example (continued)
After first pass, array numlist3 contains
9-423
Compare values 17 and
5. Not in correct order,
so exchange them.
Compare values 17 and
23. In correct order, so
no exchange.
17 5 11 23
Compare values 17 and
11. Not in correct order,
so exchange them.
In order from
previous pass
Bubble Sort Example (continued)
After second pass, array numlist3 contains
9-424
No exchanges, so
array is in order
Compare values 5 and
11. In correct order, so
no exchange.
Compare values 17 and
23. In correct order, so
no exchange.
5 11 17 23
Compare values 11 and
17. In correct order, so
no exchange.
In order from
previous passes
Bubble Sort Tradeoffs
• Benefit
– Easy to understand and to implement
• Disadvantage
– Inefficiency makes it slow for large arrays
9-425
Selection Sort Algorithm
1. Locate smallest element in array and exchange
it with element in position 0.
2. Locate next smallest element in array and
exchange it with element in position 1.
3. Continue until all elements are in order.
9-426
Selection Sort Example
Array numlist contains
Smallest element is 2. Exchange 2 with
element in 1st array position (i.e., element 0).
9-427
11 2 29 3
2 11 29 3
Now in order
Selection Sort – Example (continued)
Next smallest element is 3. Exchange
3 with element in 2nd array position.
Next smallest element is 11. Exchange
11 with element in 3rd array position.
9-428
2 3 29 11
2 3 11 29
Now in order
Now in order
Selection Sort Tradeoffs
• Benefit
– More efficient than Bubble Sort, due to fewer
exchanges
• Disadvantage
– Considered harder than Bubble Sort to
understand and implement
9-429
9.4 Sorting an Array of Objects
• As with searching, arrays to be sorted can
contain objects or structures
• The key field determines how the
structures or objects will be ordered
• When exchanging the contents of array
elements, entire structures or objects must
be exchanged, not just the key fields in the
structures or objects
9-430
9.5 Sorting and Searching Vectors
• Sorting and searching algorithms can be
applied to vectors as well as to arrays
• Need slight modifications to functions to
use vector arguments
– vector <type> & used in prototype
– No need to indicate vector size, as functions
can use size member function to calculate
9-431
9.6 Introduction to Analysis of Algorithms
• Given two algorithms to solve a problem,
what makes one better than the other?
• Efficiency of an algorithm is measured by
– space (computer memory used)
– time (how long to execute the algorithm)
• Analysis of algorithms is a more effective
way to find efficiency than by using
empirical data
9-432
Analysis of Algorithms: Terminology
• Computational Problem: a problem solved
by an algorithm
• Basic step: an operation in the algorithm
that executes in a constant amount of
time
• Examples of basic steps:
– exchange the contents of two variables
– compare two values
9-433
Analysis of Algorithms: Terminology
• Complexity of an algorithm: the number of
basic steps required to execute the
algorithm for an input of size N (N =
number of input values)
• Worst-case complexity of an algorithm: the
number of basic steps for input of size N
that requires the most work
• Average case complexity function: the
complexity for typical, average inputs of
size N
9-434
Complexity Example
Analysis:
Lines 1 and 2 execute once.
The test in line 3 executes n times.
The test in line 4 executes n times.
The assignment in line 6 executes at
most n times.
Due to lines 3 and 4, the algorithm
requires execution time proportional to n.
9-435
Find the largest value in array A of size n
1. biggest = A[0]
2. indx = 0
3. while (indx < n) do
4. if (A[n] > biggest)
5. then
6. biggest = A[n]
7. end if
8. end while
Comparison of Algorithmic Complexity
Given algorithms F and G with complexity
functions f(n) and g(n) for input of size n
• If the ratio approaches a constant value as n
gets large, F and G have equivalent efficiency
• If the ratio gets larger as n gets large,
algorithm G is more efficient than algorithm F
• If the ratio approaches 0 as n gets large,
algorithm F is more efficient than algorithm G
9-436
)
(
)
(
n
g
n
f
)
(
)
(
n
g
n
f
)
(
)
(
n
g
n
f
"Big O" Notation
• Function f(n) is O(g(n)) (“f is big O of g") for some
mathematical function g(n) if the ratio
approaches a positive constant as n gets large
• O(g(n)) defines a complexity class for the function
f(n) and for the algorithm F
• Increasing complexity classes means faster rate
of growth and less efficient algorithms
9-437
)
(
)
(
n
g
n
f
Chapter 10: Pointers
Topics
10.1 Pointers and the Address Operator
10.2 Pointer Variables
10.3 The Relationship Between Arrays
and Pointers
10.4 Pointer Arithmetic
10.5 Initializing Pointers
10.6 Comparing Pointers
10-439
Topics (continued)
10.7 Pointers as Function Parameters
10.8 Pointers to Constants and Constant
Pointers
10.9 Dynamic Memory Allocation
10.10 Returning Pointers from Functions
10.11 Pointers to Class Objects and Structures
10.12 Selecting Members of Objects
10-440
10.1 Pointers and the Address Operator
• Each variable in a program is stored at a
unique location in memory that has an
address
• Use the address operator & to get the address
of a variable:
int num = -23;
cout << &num; // prints address
// in hexadecimal
• The address of a memory location is a pointer
10-441
10.2 Pointer Variables
• Pointer variable (pointer): a variable that
holds an address
• Pointers provide an alternate way to access
memory locations
10-442
Pointer Variables
• Definition:
int *intptr;
• Read as:
“intptr can hold the address of an int” or “the
variable that intptr points to has type int”
• The spacing in the definition does not matter:
int * intptr;
int* intptr;
• * is called the indirection operator
10-443
Pointer Variables
• Assignment:
int num = 25;
int *intptr;
intptr = &num;
• Memory layout:
• Can access num using intptr and indirection
operator *:
cout << intptr; // prints 0x4a00
cout << *intptr; // prints 25
*intptr = 20; // puts 20 in num
10-444
num intptr
25 0x4a00
address of num: 0x4a00
10.3 The Relationship Between
Arrays and Pointers
An array name is the starting address of the
array
int vals[] = {4, 7, 11};
cout << vals; // displays 0x4a00
cout << vals[0]; // displays 4
10-445
4 7 11
starting address of vals: 0x4a00
The Relationship Between Arrays and
Pointers
• An array name can be used as a pointer
constant
int vals[] = {4, 7, 11};
cout << *vals; // displays 4
• A pointer can be used as an array name
int *valptr = vals;
cout << valptr[1]; // displays 7
10-446
Pointers in Expressions
• Given:
int vals[]={4,7,11};
int *valptr = vals;
• What is valptr + 1?
• It means (address in valptr) + (1 * size of an int)
cout << *(valptr+1); // displays 7
cout << *(valptr+2); // displays 11
• Must use ( ) in expression
10-447
Array Access
Array elements can be accessed in many ways
10-448
Array access
method
Example
array name and [ ] vals[2] = 17;
pointer to array and [ ] valptr[2] = 17;
array name and
subscript arithmetic
*(vals+2) = 17;
pointer to array and
subscript arithmetic
*(valptr+2) = 17;
Array Access
• Array notation
vals[i]
is equivalent to the pointer notation
*(vals + i)
• No bounds checking is performed on
array access
10-449
10.4 Pointer Arithmetic
Some arithmetic operators can be used with
pointers:
– Increment and decrement operators ++, --
– Integers can be added to or subtracted from
pointers using the operators +, -, +=, and -=
– One pointer can be subtracted from another by
using the subtraction operator -
10-450
Pointer Arithmetic
Assume the variable definitions
int vals[]={4,7,11};
int *valptr = vals;
Examples of use of ++ and --
valptr++; // points at 7
valptr--; // now points at 4
10-451
10-452
More on Pointer Arithmetic
Assume the variable definitions:
int vals[]={4,7,11};
int *valptr = vals;
Example of the use of + to add an int to
a pointer:
cout << *(valptr + 2)
This statement will print 11
10-453
Assume the variable definitions:
int vals[]={4,7,11};
int *valptr = vals;
Example of use of +=:
valptr = vals; // points at 4
valptr += 2; // points at 11
More on Pointer Arithmetic
10-454
More on Pointer Arithmetic
Assume the variable definitions
int vals[] = {4,7,11};
int *valptr = vals;
Example of pointer subtraction
valptr += 2;
cout << valptr - val;
This statement prints 2: the number of
ints between valptr and val
10.5 Initializing Pointers
• Can initialize to NULL or 0 (zero)
int *ptr = NULL;
• Can initialize to addresses of other variables
int num, *numPtr = &num;
int val[ISIZE], *valptr = val;
• Initial value must have correct type
float cost;
int *ptr = &cost; // won't work
10-455
10.6 Comparing Pointers
• Relational operators can be used to
compare addresses in pointers
• Comparing addresses in pointers is not the
same as comparing contents pointed at by
pointers:
if (ptr1 == ptr2) // compares
// addresses
if (*ptr1 == *ptr2) // compares
// contents
10-456
10.7 Pointers as Function Parameters
• A pointer can be a parameter
• It works like a reference parameter to allow
changes to argument from within a function
• A pointer parameter must be explicitly
dereferenced to access the contents at
that address
10-457
Pointers as Function Parameters
Requires:
1) asterisk * on parameter in prototype and
heading
void getNum(int *ptr);
2) asterisk * in body to dereference the pointer
cin >> *ptr;
3) address as argument to the function in the call
getNum(&num);
10-458
Pointers as Function Parameters
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int num1 = 2, num2 = -3;
swap(&num1, &num2); //call
10-459
10.8 Ponters to Constants and Constant
Pointers
• Pointer to a constant: cannot change the
value that is pointed at
• Constant pointer: the address in the
pointer cannot change after the pointer
is initialized
10-460
Ponters to Constant
• Must use const keyword in pointer
definition:
const double taxRates[] =
{0.65, 0.8, 0.75};
const double *ratePtr;
• Use const keyword for pointers in
function headers to protect data from
modification from within function
10-461
Pointer to Constant – What does the
Definition Mean?
10-462
Read as: “rates is a pointer to a constant that is a double.”
Constant Pointers
• Defined with const keyword adjacent to variable
name:
int classSize = 24;
int * const classPtr = &classSize;
• Must be initialized when defined
• Can be used without initialization as a function
parameter
– Initialized by argument when function is called
– Function can receive different arguments on different calls
• While the address in the pointer cannot change, the
data at that address may be changed
10-463
Constant Pointer – What does the
Definition Mean?
10-464
Read as: “pts is a constant pointer to an int.”
Constant Pointer to Constant
• Can combine pointer to constants and constant
pointers:
int size = 10;
const int * const ptr = &size;
• What does it mean?
10-465
10.9 Dynamic Memory Allocation
• Can allocate storage for a variable while
program is running
• Uses new operator to allocate memory
double *dptr;
dptr = new double;
• new returns address of memory location
10-466
Dynamic Memory Allocation
• Can also use new to allocate array
arrayPtr = new double[25];
– Program may terminate if there is not sufficient
memory
• Can then use [ ] or pointer arithmetic to
access array
10-467
Dynamic Memory Example
int *count, *arrayptr;
count = new int;
cout <<"How many students? ";
cin >> *count;
arrayptr = new int[*count];
for (int i=0; i<*count; i++)
{
cout << "Enter score " << i << ": ";
cin >> arrayptr[i];
}
10-468
Releasing Dynamic Memory
• Use delete to free dynamic memory
delete count;
• Use delete [] to free dynamic array
memory
delete [] arrayptr;
• Only use delete with dynamic memory!
10-469
Dangling Pointers and Memory Leaks
• A pointer is dangling if it contains the
address of memory that has been freed by
a call to delete.
– Solution: set such pointers to 0 as soon as
memory is freed.
• A memory leak occurs if no-longer-needed
dynamic memory is not freed. The memory
is unavailable for reuse within the program.
– Solution: free up dynamic memory after use
10-470
10.10 Returning Pointers from Functions
• Pointer can be return type of function
int* newNum();
• The function must not return a pointer to a
local variable in the function
• The function should only return a pointer
– to data that was passed to the function as an
argument
– to dynamically allocated memory
10-471
10.11 Pointers to Class Objects and
Structures
• Can create pointers to objects and structure
variables
struct Student {…};
class Square {…};
Student stu1;
Student *stuPtr = &stu1;
Square sq1[4];
Square *squarePtr = &sq1[0];
• Need to use() when using * and . operators
(*stuPtr).studentID = 12204;
10-472
Structure Pointer Operator
• Simpler notation than (*ptr).member
• Use the form ptr->member:
stuPtr->studentID = 12204;
squarePtr->setSide(14);
in place of the form (*ptr).member:
(*stuPtr).studentID = 12204;
(*squarePtr).setSide(14);
10-473
Dynamic Memory with Objects
• Can allocate dynamic structure variables
and objects using pointers:
stuPtr = new Student;
• Can pass values to constructor:
squarePtr = new Square(17);
• delete causes destructor to be invoked:
delete squarePtr;
10-474
Structure/Object Pointers
as Function Parameters
• Pointers to structures or objects can be
passed as parameters to functions
• Such pointers provide a pass-by-reference
parameter mechanism
• Pointers must be dereferenced in the
function to access the member fields
10-475
Controlling Memory Leaks
• Memory that is allocated with new should
be deallocated with a call to delete as
soon as the memory is no longer needed.
This is best done in the same function as
the one that allocated the memory.
• For dynamically-created objects, new
should be used in the constructor and
delete should be used in the destructor
10-476
10.12 Selecting Members of Objects
Situation: A structure/object contains a pointer as a
member. There is also a pointer to the structure/
object.
Problem: How do we access the pointer member
via the structure/object pointer?
struct GradeList
{ string courseNum;
int * grades;
}
GradeList test1, *testPtr = &test1;
10-477
Selecting Members of Objects
10-478
Expression Meaning
testPtr->grades Access the grades pointer in
test1. This is the same as
(*testPtr).grades
*testPtr->grades Access the value pointed at by
testPtr->grades. This is the
same as *(*testPtr).grades
*test1.grades Access the value pointed at by
test1.grades
Chapter 11: More About Classes and
Object-Oriented Programming
Topics
11.1 The this Pointer and Constant
Member Functions
11.2 Static Members
11.3 Friends of Classes
11.4 Memberwise Assignment
11.5 Copy Constructors
11.6 Operator Overloading
11.7 Type Conversion Operators
11-480
Topics (continued)
11.8 Convert Constructors
11.9 Aggregation and Composition
11.10 Inheritance
11.11 Protected Members and Class Access
11.12 Constructors, Destructors, and
Inheritance
11.13 Overriding Base Class Functions
11-481
11.1 The this Pointer and Constant
Member Functions
• this pointer:
- Implicit parameter passed to a member
function
- points to the object calling the function
• const member function:
- does not modify its calling object
11-482
Using the this Pointer
Can be used to access members that
may be hidden by parameters with the
same name:
class SomeClass
{
private:
int num;
public:
void setNum(int num)
{ this->num = num; }
};
11-483
Constant Member Functions
• Declared with keyword const
• When const appears in the parameter list,
int setNum (const int num)
the function is prevented from modifying the
parameter. The parameter is read-only.
• When const follows the parameter list,
int getX()const
the function is prevented from modifying the object.
11-484
11.2 Static Members
• Static member variable:
– One instance of variable for the entire class
– Shared by all objects of the class
• Static member function:
– Can be used to access static member
variables
– Can be called before any class objects are
created
11-485
Static Member Variables
1) Must be declared in class with keyword
static:
class IntVal
{
public:
intVal(int val = 0)
{ value = val; valCount++ }
int getVal();
void setVal(int);
private:
int value;
static int valCount;
};
11-486
Static Member Variables
2) Must be defined outside of the class:
class IntVal
{
//In-class declaration
static int valCount;
//Other members not shown
};
//Definition outside of class
int IntVal::valCount = 0;
11-487
Static Member Variables
3) Can be accessed or modified by any
object of the class: Modifications by one
object are visible to all objects of the
class:
IntVal val1, val2;
11-488
valCount
val1 val2
2
Static Member Functions
1)Declared with static before return type:
class IntVal
{ public:
static int getValCount()
{ return valCount; }
private:
int value;
static int valCount;
};
11-489
Static Member Functions
2) Can be called independently of class
objects, through the class name:
cout << IntVal::getValCount();
3) Because of item 2 above, the this
pointer cannot be used
4) Can be called before any objects of the
class have been created
5) Used primarily to manipulate static
member variables of the class
11-490
11.3 Friends of Classes
• Friend function: a function that is not a
member of a class, but has access to
private members of the class
• A friend function can be a stand-alone
function or a member function of another
class
• It is declared a friend of a class with the
friend keyword in the function prototype
11-491
Friend Function Declarations
1) Friend function may be a stand-alone
function:
class aClass
{
private:
int x;
friend void fSet(aClass &c, int a);
};
void fSet(aClass &c, int a)
{
c.x = a;
}
11-492
Friend Function Declarations
2) Friend function may be a member of another
class:
class aClass
{ private:
int x;
friend void OtherClass::fSet
(aClass &c, int a);
};
class OtherClass
{ public:
void fSet(aClass &c, int a)
{ c.x = a; }
};
11-493
Friend Class Declaration
3) An entire class can be declared a friend of a
class:
class aClass
{private:
int x;
friend class frClass;
};
class frClass
{public:
void fSet(aClass &c,int a){c.x = a;}
int fGet(aClass c){return c.x;}
};
11-494
Friend Class Declaration
• If frClass is a friend of aClass, then all
member functions of frClass have
unrestricted access to all members of
aClass, including the private members.
• In general, restrict the property of
Friendship to only those functions that must
have access to the private members of a
class.
11-495
11.4 Memberwise Assignment
• Can use = to assign one object to another,
or to initialize an object with an object’s
data
• Examples (assuming class V):
V v1, v2;
… // statements that assign
… // values to members of v1
v2 = v1; // assignment
V v3 = v2; // initialization
11-496
11.5 Copy Constructors
• Special constructor used when a newly
created object is initialized to the data of
another object of same class
• Default copy constructor copies field-to-
field, using memberwise assignment
• The default copy constructor works fine in
most cases
11-497
Copy Constructors
Problems occur when objects contain
pointers to dynamic storage:
class CpClass
{
private:
int *p;
public:
CpClass(int v=0)
{ p = new int; *p = v;}
~CpClass(){delete p;}
};
11-498
Default Constructor Causes Sharing of
Storage
CpClass c1(5);
if (true)
{
CpClass c2=c1;
}
// c1 is corrupted
// when c2 goes
// out of scope and
// its destructor
// executes
11-499
c1
c2
5
Problems of Sharing Dynamic Storage
• Destructor of one object deletes memory
still in use by other objects
• Modification of memory by one object
affects other objects sharing that memory
11-500
Programmer-Defined Copy Constructors
• A copy constructor is one that takes a
reference parameter to another object of
the same class
• The copy constructor uses the data in the
object passed as parameter to initialize the
object being created
• Reference parameter should be const to
avoid potential for data corruption
11-501
Programmer-Defined Copy Constructors
• The copy constructor avoids problems
caused by memory sharing
• Can allocate separate memory to hold new
object’s dynamic member data
• Can make new object’s pointer point to this
memory
• Copies the data, not the pointer, from the
original object to the new object
11-502
Copy Constructor Example
class CpClass
{
int *p;
public:
CpClass(const CpClass &obj)
{ p = new int; *p = *obj.p; }
CpClass(int v=0)
{ p = new int; *p = v; }
~CpClass(){delete p;}
};
11-503
Copy Constructor – When Is It Used?
A copy constructor is called when
• An object is initialized from an object of the same
class
• An object is passed by value to a function
• An object is returned using a return statement
from a function
11-504
11.6 Operator Overloading
• Operators such as =, +, and others can be
redefined for use with objects of a class
• The name of the function for the overloaded
operator is operator followed by the
operator symbol, e.g.,
operator+ is the overloaded + operator and
operator= is the overloaded = operator
11-505
Operator Overloading
• Operators can be overloaded as
- instance member functions, or as
- friend functions
• The overloaded operator must have the
same number of parameters as the
standard version. For example,
operator= must have two parameters,
since the standard = operator takes two
parameters.
11-506
Overloading Operators as Instance
Members
A binary operator that is overloaded as an
instance member needs only one parameter,
which represents the operand on the right:
class OpClass
{
private:
int x;
public:
OpClass operator+(OpClass right);
};
11-507
Overloading Operators as Instance
Members
• The left operand of the overloaded binary
operator is the calling object
• The implicit left parameter is accessed
through the this pointer
OpClass OpClass::operator+(OpClass r)
{ OpClass sum;
sum.x = this->x + r.x;
return sum;
}
11-508
Invoking an Overloaded Operator
• Operator can be invoked as a member
function:
OpClass a, b, s;
s = a.operator+(b);
• It can also be invoked in the more
conventional manner:
OpClass a, b, s;
s = a + b;
11-509
Overloading Assignment
• Overloading the assignment operator solves
problems with object assignment when an
object contains pointer to dynamic memory.
• Assignment operator is most naturally
overloaded as an instance member function
• It needs to return a value of the assigned
object to allow cascaded assignments such
as
a = b = c;
11-510
Overloading Assignment
Assignment overloaded as a member function:
class CpClass
{
int *p;
public:
CpClass(int v=0)
{ p = new int; *p = v;
~CpClass(){delete p;}
CpClass operator=(CpClass);
};
11-511
Overloading Assignment
Implementation returns a value:
CpClass CpClass::operator=(CpClass r)
{
*p = *r.p;
return *this;
};
Invoking the assignment operator:
CpClass a, x(45);
a.operator=(x); // either of these
a = x; // lines can be used
11-512
Notes on Overloaded Operators
• Overloading can change the entire
meaning of an operator
• Most operators can be overloaded
• Cannot change the number of operands of
the operator
• Cannot overload the following operators:
?: . .* sizeof
11-513
Overloading Types of Operators
• ++, -- operators overloaded differently
for prefix vs. postfix notation
• Overloaded relational operators should
return a bool value
• Overloaded stream operators >>, <<
must return istream, ostream objects
and take istream, ostream objects as
parameters
11-514
Overloaded [] Operator
• Can be used to create classes that
behave like arrays, providing bounds-
checking on subscripts
• Overloaded [] returns a reference to
object, not an object itself
11-515
11.7 Type Conversion Operators
• Conversion Operators are member
functions that tell the compiler how to
convert an object of the class type to a
value of another type
• The conversion information provided by
the conversion operators is automatically
used by the compiler in assignments,
initializations, and parameter passing
11-516
Syntax of Conversion Operators
• Conversion operator must be a member
function of the class you are converting from
• The name of the operator is the name of the
type you are converting to
• The operator does not specify a return type
11-517
Conversion Operator Example
• To convert from a class IntVal to an integer:
class IntVal
{
int x;
public:
IntVal(int a = 0){x = a;}
operator int(){return x;}
};
• Automatic conversion during assignment:
IntVal obj(15); int i;
i = obj; cout << i; // prints 15
11-518
11.8 Convert Constructors
Convert constructors are constructors that take
a single parameter of a type other than the
class in which they are defined
class CCClass
{ int x;
public:
CCClass() //default
CCClass(int a, int b);
CCClass(int a); //convert
CCClass(string s); //convert
};
11-519
Example of a Convert Constructor
The C++ string class has a convert
constructor that converts from C-strings:
class string
{
public:
string(char *); //convert
…
};
11-520
Uses of Convert Constructors
• They are automatically invoked by the
compiler to create an object from the value
passed as parameter:
string s("hello"); //convert C-string
CCClass obj(24); //convert int
• The compiler allows convert constructors to
be invoked with assignment-like notation:
string s = "hello"; //convert C-string
CCClass obj = 24; //convert int
11-521
Uses of Convert Constructors
• Convert constructors allow functions that
take the class type as parameter to take
parameters of other types:
void myFun(string s); // needs string
// object
myFun("hello"); // accepts C-string
void myFun(CCClass c);
myFun(34); // accepts int
11-522
11.9 Aggregation and Composition
• Class aggregation: An object of one
class owns an object of another class
• Class composition: A form of aggregation
where the enclosing class controls the
lifetime of the objects of the enclosed
class
• Supports the modeling of ‘has-a’
relationship between classes – enclosing
class ‘has a(n)’ instance of the enclosed
class
11-523
Object Composition
class StudentInfo
{
private:
string firstName, LastName;
string address, city, state, zip;
...
};
class Student
{
private:
StudentInfo personalData;
...
};
11-524
Member Initialization Lists
• Used in constructors for classes involved in
aggregation.
• Allows constructor for enclosing class to pass
arguments to the constructor of the enclosed
class
• Notation:
owner_class(parameters):owned_class(parameters);
11-525
Member Initialization Lists
Use:
class StudentInfo
{
...
};
class Student
{
private:
StudentInfo personalData;
public:
Student(string fname, lname):
StudentInfo(fname, lname);
};
11-526
Member Initialization Lists
• Member Initialization lists can be used to
simplify the coding of constructors
• Should keep the entries in the initialization
list in the same order as they are declared in
the class
11-527
Aggregation Through Pointers
• A ‘has-a’ relationship can be implemented
by owning a pointer to an object
• Can be used when multiple objects of a
class may ‘have’ the same attribute for a
member
– ex: students who may have the same city/state/
zipcode
• Using pointers minimizes data duplication
and saves space
11-528
Aggregation, Composition, and Object
Lifetimes
• Aggregation represents the owner/owned
relationship between objects.
• Composition is a form of aggregation in
which the lifetime of the owned object is the
same as that of the owner object
• Owned object is usually created as part of
the owning object’s constructor, destroyed
as part of owning object’s destructor
11-529
11.10 Inheritance
• Inheritance is a way of creating a new class
by starting with an existing class and
adding new members
• The new class can replace or extend the
functionality of the existing class
• Inheritance models the 'is-a' relationship
between classes
11-530
Inheritance - Terminology
• The existing class is called the base class
– Alternates: parent class, superclass
• The new class is called the derived class
– Alternates: child class, subclass
11-531
Inheritance Syntax and Notation
// Existing class
class Base
{
};
// Derived class
class Derived : public Base
{
};
Inheritance Class
Diagram
11-532
Base Class
Derived Class
Inheritance of Members
class Parent
{
int a;
void bf();
};
class Child : public
Parent
{
int c;
void df();
};
Objects of Parent have
members
int a; void bf();
Objects of Child have
members
int a; void bf();
int c; void df();
11-533
11.11 Protected Members and Class
Access
• protected member access specification: A
class member labeled protected is
accessible to member functions of derived
classes as well as to member functions of
the same class
• Like private, except accessible to
members functions of derived classes
11-534
Base Class Access Specification
Base class access specification determines
how private, protected, and public
members of base class can be accessed
by derived classes
11-535
Base Class Access
C++ supports three inheritance modes, also
called base class access modes:
- public inheritance
class Child : public Parent { };
- protected inheritance
class Child : protected Parent{ };
- private inheritance
class Child : private Parent{ };
11-536
Base Class Access vs. Member
Access Specification
Base class access is not the same as
member access specification:
– Base class access: determine access for
inherited members
– Member access specification: determine
access for members defined in the class
11-537
Member Access Specification
Specified using the keywords
private, protected, public
class MyClass
{
private: int a;
protected: int b; void fun();
public: void fun2();
};
11-538
Base Class Access Specification
class Child : public Parent
{
protected:
int a;
public:
Child();
};
11-539
member access
base access
Base Class Access Specifiers
1) public – object of derived class can be
treated as object of base class (not vice-
versa)
2) protected – more restrictive than public,
but allows derived classes to know some of
the details of parents
3) private – prevents objects of derived class
from being treated as objects of base class.
11-540
Effect of Base Access
11-541
private: x
protected: y
public: z
private: x
protected: y
public: z
private: x
protected: y
public: z
Base class members
x inaccessible
private: y
private: z
x inaccessible
protected: y
protected: z
x inaccessible
protected: y
public: z
How base class members
appear in derived class
private
base class
protected
base class
public
base class
11.12 Constructors,Destructors and
Inheritance
• By inheriting every member of the base
class, a derived class object contains a
base class object
• The derived class constructor can specify
which base class constructor should be
used to initialize the base class object
11-542
Order of Execution
• When an object of a derived class is
created, the base class’s constructor is
executed first, followed by the derived
class’s constructor
• When an object of a derived class is
destroyed, its destructor is called first, then
that of the base class
11-543
Order of Execution
// Student – base class
// UnderGrad – derived class
// Both have constructors, destructors
int main()
{
UnderGrad u1;
...
return 0;
}// end main
11-544
Execute Student
constructor, then
execute
UnderGrad
constructor
Execute UnderGrad
destructor, then
execute Student
destructor
Passing Arguments to Base Class
Constructor
• Allows selection between multiple base
class constructors
• Specify arguments to base constructor on
derived constructor heading
• Can also be done with inline constructors
• Must be done if base class has no default
constructor
11-545
Passing Arguments to Base Class
Constructor
class Parent {
int x, y;
public: Parent(int,int);
};
class Child : public Parent {
int z
public:
Child(int a): Parent(a,a*a)
{z = a;}
};
11-546
11.13 Overriding Base Class Functions
• Overriding: function in a derived class that
has the same name and parameter list as a
function in the base class
• Typically used to replace a function in base
class with different actions in derived class
• Not the same as overloading – with
overloading, the parameter lists must be
different
11-547
Access to Overridden Function
• When a function is overridden, all objects of
derived class use the overriding function.
• If necessary to access the overridden
version of the function, it can be done using
the scope resolution operator with the name
of the base class and the name of the
function:
Student::getName();
11-548
Chapter 12: More on C-Strings
and the string Class
Topics
12.1 C-Strings
12.2 Library Functions for Working with
C-Strings
12.3 Conversions Between Numbers and
Strings
12.4 Writing Your Own C-String Handling
Functions
12.5 More About the C++ string Class
12.6 Creating Your Own String Class
12-550
12.1 C-Strings
• C-string: sequence of characters stored in
adjacent memory locations and terminated
by NULL character
• The C-string
"Hi there!"
would be stored in memory as shown:
12-551
H i t h e r e ! 0
What is NULL?
• The null character is used to indicate the
end of a string
• It can be specified as
– the character '0'
– the int value 0
– the named constant NULL
12-552
Representation of C-strings
As a string literal
"Hi There!"
As a pointer to char
char *p;
As an array of characters
char str[20];
All three representations are pointers to
char
12-553
String Literals
• A string literal is stored as a null-terminated
array of char
• Compiler uses the address of the first
character of the array as the value of the
string
• String literal is a pointer to char
12-554
h i 0
value of "hi" is the
address of this array
Array of char
• An array of char can be defined and initialized to
a C-string
char str1[20] = "hi";
• An array of char can be defined and later have a
string copied into it using strcpy or
cin.getline
char str2[20], str3[20];
strcpy(str2, "hi");
cout << "Enter your name: ";
cin.getline(str3, 20);
12-555
Array of char
• The name of an array of char is used as
a pointer to char
• Unlike a string literal, a C-string defined
as an array can be referred to in other
parts of the program by using the array
name
12-556
Pointer to char
• Defined as
char *pStr;
• Does not itself allocate memory
• Useful in repeatedly referring to C-
strings defined as a string literal
pStr = "Hi there";
cout << pStr << " "
<< pStr;
12-557
Pointer to char
• Pointer to char can also refer to C-strings
defined as arrays of char
char str[20] = "hi";
char *pStr = str;
cout << pStr; // prints hi
• Can dynamically allocate memory to be
used for C-string using new
12-558
12.2 Library Functions for Working with
C-Strings
• Require cstring header file
• Functions take one or more C-strings as
arguments. Argument can be:
– Name of an array of char
– pointer to char
– string literal
12-559
Library Functions for
Working with C-Strings
int strlen(char *str)
Returns length of a C-string:
cout << strlen("hello");
Prints: 5
Note: This is the number of characters in
the string, NOT the size of the array that
contains it
12-560
strcat
strcat(char *dest, char *source)
• Takes two C-strings as input. It adds the contents
of the second string to the end of the first string:
char str1[15] = "Good ";
char str2[30] = "Morning!";
strcat(str1, str2);
cout << str1; // prints: Good Morning!
• No automatic bounds checking: programmer must
ensure that 1st string has enough room for result
12-561
strcpy
strcpy(char *dest, char *source)
• Copies a string from a source address to a
destination address
char name[15];
strcpy(name, "Deborah");
cout << name; // prints Deborah
• Again, no automatic bounds checking
12-562
strcmp
int strcmp(char *str1, char*str2)
• Compares strings stored at two addresses to
determine their relative alphabetic order:
• Returns a value:
less than 0 if str1 precedes str2
equal to 0 if str1 equals str2
greater than 0 if str1 succeeds str2
12-563
strcmp
• Often used to test for equality
if(strcmp(str1, str2) == 0)
cout << "equal";
else
cout << "not equal";
• Also used to determine ordering of C-strings in
sorting applications
• Note:
– Comparisons are case-sensitive: "Hi" != "hi"
– C-strings cannot be compared using == (compares
addresses of C-strings, not contents)
12-564
strstr
char *strstr(char *str1,char *str2)
• Searches for the occurrence of str2 within
str1.
• Returns a pointer to the occurrence of str2
within str1 if found, and returns NULL otherwise
char s[15] = "Abracadabra";
char *found = strstr(s,"dab");
cout << found; // prints dabra
12-565
12.3 Conversions Between Numbers
and Strings
• "1416" is a string; 1416 without quotes is
an int
• There are classes that can be used to
convert between string and numeric forms
of numbers
• Need to include sstream header file
12-566
Conversion Classes
• istringstream:
– contains a string to be converted to numeric values
where necessary
– Use str(s) to initialize string to contents of s
– Use the stream extraction operator >> to read from the
string
• ostringstream:
– collects a string in which numeric data is converted as
necessary
– Use the stream insertion operator << to add data onto
the string
– Use str() to retrieve converted string
12-567
atoi and atol
• atoi converts alphanumeric to int
• atol converts alphanumeric to long
int atoi(char *numericStr)
long atol(char *numericStr)
• Examples:
int number; long lnumber;
number = atoi("57");
lnumber = atol("50000");
12-568
atof
• atof converts a numeric string to a
floating point number, actually a
double
double atof(char *numericStr)
• Example:
double dnumber;
dnumber = atof("3.14159");
12-569
atoi, atol, atof
• if C-string being converted contains non-
digits, results are undefined
– function may return result of conversion up
to first non-digit
– function may return 0
• All functions require cstdlib
12-570
itoa
• itoa converts an int to an alphanumeric string
• Allows user to specify the base of conversion
itoa(int num, char *numStr, int base)
• Example: To convert the number 1200 to a
hexadecimal string
char numStr[10];
itoa(1200, numStr, 16);
• The function performs no bounds-checking on the
array numStr
12-571
12.4 Character Testing
require cctype header file
FUNCTION MEANING
isalpha true if arg. is a letter, false otherwise
isalnum true if arg. is a letter or digit, false
otherwise
isdigit true if arg. is a digit 0-9, false otherwise
islower true if arg. is lowercase letter, false
otherwise
12-572
12.4 Writing Your Own C-String
Handling Functions
When writing C-String Handling Functions:
– can pass arrays or pointers to char
– can perform bounds checking to ensure
enough space for results
– can anticipate unexpected user input
12-573
12.5 More About the C++ string Class
• The string class offers several advantages
over C-style strings:
– large body of member functions
– overloaded operators to simplify expressions
• Need to include the string header file
12-574
string class constructors
• Default constructor string()
• Copy constructor string(string&)
initializes string objects with values of other
string objects
• Convert constructor string(char *)
initializes string objects with values of C-
strings
• Various other constructors
12-575
Overloaded string Operators
OPERATOR MEANING
>> reads whitespace-delimited strings
into string object
<< inserts string object into a stream
= assigns string on right to string
object on left
+= appends string on the right to the
end of contents of string on left
12-576
Overloaded string Operators (continued)
OPERATOR MEANING
+ Returns concatenation of the two
strings
[] references character in string using
array notation
>, >=,
<, <=,
==, !=
relational operators for string
comparison. Return true or false
12-577
Overloaded string Operators
string word1, phrase;
string word2 = " Dog";
cin >> word1; // user enters "Hot"
// word1 has "Hot"
phrase = word1 + word2; // phrase has
// "Hot Dog"
phrase += " on a bun";
for (int i = 0; i < 16; i++)
cout << phrase[i]; // displays
// "Hot Dog on a bun"
12-578
string Member Functions
Categories:
– conversion to C-strings: c_str, data
– modification: append, assign, clear,
copy, erase, insert, replace, swap
– space management: capacity, empty,
length, resize, size
– substrings: find, substr
– comparison: compare
12-579
Conversion to C-strings
• data() and c_str() both return the C-
string equivalent of a string object
• Useful when using a string object with a
function that is expecting a C-string
char greeting[20] = "Have a ";
string str("nice day");
strcat(greeting, str.data());
12-580
Modification of string objects
• str.append(string s)
appends contents of s to end of str
• Convert constructor for string allows a C-
string to be passed in place of s
string str("Have a ");
str.append("nice day");
• append is overloaded for flexibility
12-581
Modification of string objects
• str.insert(int pos, string s)
inserts s at position pos in str
• Convert constructor for string allows a C-
string to be passed in place of s
string str("Have a day");
str.insert(7, "nice ");
• insert is overloaded for flexibility
12-582
12.6 Creating Your Own String Class
• A good way to put OOP skills into practice
• The class allocates dynamic memory, so
has copy constructor, destructor, and
overloaded assignment
• Overloads the stream insertion and
extraction operators, and many other
operators
12-583
Chapter 13: Advanced File and I/O
Operations
Topics
13.1 Input and Output Streams
13.2 More Detailed Error Testing
13.3 Member Functions for Reading and
Writing Files
13.4 Binary Files
13.5 Creating Records with Structures
13.6 Random-Access Files
13.7 Opening a File for Both Input and Output
13-585
13.1 Input and Output Streams
• Input Stream – data stream from which
information can be read
– Ex: cin and the keyboard
– Use istream, ifstream, and istringstream
objects to read data
• Output Stream – data stream to which information
can be written
– Ex: cout and monitor screen
– Use ostream, ofstream, and ostringstream
objects to write data
• Input/Output Stream – data stream that can be
both read from and written to
– Use fstream objects here
13-586
File Stream Classes
• ifstream (open primarily for input), ofstream
(open primarily for output), and fstream (open
for either or both input and output)
• All have open member function to connect the
program to an external file
• All have close member function to disconnect
program from an external file when access is
finished
– Files should be open for as short a time as possible
– Always close files before the program ends
13-587
File Open Modes
• File open modes specify how a file is opened
and what can be done with the file once it is
open
• ios::in and ios::out are examples of file
open modes, also called file mode flag
• File modes can be combined and passed as
second argument of open member function
13-588
The fstream Object
• fstream object can be used for either input or
output
fstream file;
• To use fstream for input, specify ios::in as
the second argument to open
file.open("myfile.dat",ios::in);
• To use fstream for output, specify ios::out
as the second argument to open
file.open("myfile.dat",ios::out);
13-589
File Mode Flags
ios::app create new file, or append to end of
existing file
ios::ate go to end of existing file; write anywhere
ios::binary read/write in binary mode (not text mode)
ios::in open for input
ios::out open for output
13-590
Opening a File for Input and Output
• fstream object can be used for both input and
output at the same time
• Create the fstream object and specify both
ios::in and ios::out as the second
argument to the open member function
fstream file;
file.open("myfile.dat",
ios::in|ios::out);
13-591
File Open Modes
• Not all combinations of file open modes
make sense
• ifstream and ofstream have default file
open modes defined for them, hence the
second parameter to their open member
function is optional
13-592
Opening Files with Constructors
• Stream constructors have overloaded
versions that take the same parameters as
open
• These constructors open the file,
eliminating the need for a separate call to
open
fstream inFile("myfile.dat",
ios::in);
13-593
Default File Open Modes
• ofstream:
– open for output only
– file cannot be read from
– file is created if no file exists
– file contents erased if file exists
• ifstream:
– open for input only
– file cannot be written to
– open fails if the file does not exist
13-594
Output Formatting with I/O Manipulators
• Can format with I/O manipulators: they
work with file objects just like they work
with cout
• Can format with formatting member
functions
• The ostringstream class allows
in-memory formatting into a string object
before writing to a file
13-595
I/O Manipulators
left, right left or right justify output
oct, dec,
hex
display output in octal, decimal, or
hexadecimal
endl, flush write newline (endl only) and flush output
showpos,
noshowpos
do, do not show leading + with non-negative
numbers
showpoint,
noshowpoint
do, do not show decimal point and trailing
zeroes
13-596
More I/O Manipulators
fixed,
scientific
use fixed or scientific notation for
floating-point numbers
setw(n) sets minimum field output width to n
setprecision(n) sets floating-point precision to n
setfill(ch) uses ch as fill character
13-597
sstream Formatting
1) To format output into an in-memory
string object, include the sstream
header file and create an
ostringstream object
#include <sstream>
ostringstream outStr;
13-598
sstream Formatting
2) Write to the ostringstream object
using I/O manipulators, all other
stream member functions:
outStr << showpoint << fixed
<< setprecision(2)
<< '$'<< amount;
13-599
sstream Formatting
3) Access the C-string inside the
ostringstream object by calling its
str member function
cout << outStr.str();
13-600
13.2 More Detailed Error Testing
13-601
• Stream objects have error bits (flags)
that are set by every operation to
indicate success or failure of the
operation, and the status of the stream
• Stream member functions report on the
settings of the flags
Error State Bits
Can examine error state bits to determine file
stream status
ios::eofbit set when end of file detected
ios::failbit set when operation failed
ios::hardfail set when an irrecoverable error
occurred
ios::badbit set when invalid operation
attempted
ios::goodbit set when no other bits are set
13-602
Error Bit Reporting Functions
eof() true if eofbit set, false otherwise
fail() true if failbit or hardfail set, false
otherwise
bad() true if badbit set, false otherwise
good() true if goodbit set, false otherwise
clear() clear all flags (no arguments), or clear a
specific flag
13-603
Detecting File Operation Errors
• The file handle is set to true if a file operation
succeeds. It is set to false when a file operation
fails
• Test the status of the stream by testing the file
handle:
inFile.open("myfile");
if (!inFile)
{ cout << "Can't open file";
exit(1);
}
13-604
13.3 Member Functions for Reading
and Writing Files
Unlike the extraction operator >>, these
reading functions do not skip whitespace:
getline: read a line of input
get: reads a single character
seekg: goes to beginning of input file
13-605
getline Member Function
getline(char s[ ],
int max, char stop ='n')
– char s[ ]: Character array to hold input
– int max : 1 more than the maximum
number of characters to read
– char stop: Terminator to stop at if
encountered before max number of
characters is read . Optional, default is 'n'
13-606
Single Character Input
get(char &ch)
Read a single character from the input stream
and put it in ch. Does not skip whitespace.
ifstream inFile; char ch;
inFile.open("myFile");
inFile.get(ch);
cout << "Got " << ch;
13-607
Single Character Input, Again
get()
Read a single character from the input stream
and return the character. Does not skip
whitespace.
ifstream inFile; char ch;
inFile.open("myFile");
ch = inFile.get();
cout << "Got " << ch;
13-608
Single Character Input, with a Difference
peek()
Read a single character from the input stream
but do not remove the character from the input
stream. Does not skip whitespace.
ifstream inFile; char ch;
inFile.open("myFile");
ch = inFile.peek();
cout << "Got " << ch;
ch = inFile.peek();
cout << "Got " << ch;//same output
13-609
Single Character Output
• put(char ch)
Output a character to a file
• Example
ofstream outFile;
outFile.open("myfile");
outFile.put('G');
13-610
Moving About in Input Files
seekg(offset, place)
Move to a given offset relative to a given
place in the file
– offset: number of bytes from place,
specified as a long
– place: location in file from which to compute offset
ios::beg: beginning of file
ios::end: end of the file
ios::cur: current position in file
13-611
Example of Single Character I/O
To copy an input file to an output file
char ch; infile.get(ch);
while (!infile.fail())
{ outfile.put(ch);
infile.get(ch);
}
infile.close();
outfile.close();
13-612
Rewinding a File
• To move to the beginning of file, seek to an
offset of zero from beginning of file
inFile.seekg(0L, ios::beg);
• Error or eof bits will block seeking to the
beginning of file. Clear bits first:
inFile.clear();
inFile.seekg(0L, ios::beg);
13-613
13.4 Binary Files
• Binary files store data in the same format
that a computer has in main memory
• Text files store data in which numeric
values have been converted into strings of
ASCII characters
• Files are opened in text mode (as text files)
by default
13-614
Using Binary Files
• Pass the ios::binary flag to the open
member function to open a file in binary mode
infile.open("myfile.dat",ios::binary);
• Reading and writing of binary files requires
special read and write member functions
read(char *buffer, int numberBytes)
write(char *buffer, int numberBytes)
13-615
Using read and write
read(char *buffer, int numberBytes)
write(char *buffer, int numberBytes)
• buffer: holds an array of bytes to transfer
between memory and the file
• numberBytes: the number of bytes to transfer
Address of the buffer needs to be cast to
char * using reinterpret_cast <char *>
13-616
Using write
To write an array of 2 doubles to a binary file
ofstream outFile("myfile",ios:binary);
double d[2] = {12.3, 34.5};
outFile.write(
reinterpret_cast<char *>(d),sizeof(d));
13-617
Using read
To read two 2 doubles from a binary file into an array
ifstream inFile("myfile", ios:binary);
const int DSIZE = 10;
double data[DSIZE];
inFile.read(
reinterpret_cast<char *>(data),
2*sizeof(double));
// only data[0] and data[1] contain
// values
13-618
13.5 Creating Records with
Structures
• Can write structures to, read structures
from files
• To work with structures and files,
– use binary file flag upon open
– use read, write member functions
13-619
Creating Records with Structures
struct TestScore
{ int studentId;
float score;
char grade;
};
TestScore test1[20];
...
// write out test1 array to a file
gradeFile.write(
reinterpret_cast<char*>(test1),
sizeof(test1));
13-620
Notes on Structures Written to Files
• Structures to be written to a file must not
contain pointers
• Since string objects use pointers and
dynamic memory internally, structures to
be written to a file must not contain any
string objects
13-621
13.6 Random-Access Files
• Sequential access: start at beginning of
file and go through data the in file, in
order, to the end of the file
– to access 100th entry in file, go through 99
preceding entries first
• Random access: access data in a file in
any order
– can access 100th entry directly
13-622
Random Access Member Functions
• seekg (seek get): used with input files
• seekp (seek put): used with output files
Both are used to go to a specific position
in a file
13-623
Random Access Member Functions
seekg(offset,place)
seekp(offset,place)
offset:long integer specifying number of bytes
to move
place: starting point for the move, specified
by ios:beg, ios::cur or
ios:end
13-624
Random-Access Member Functions
• Examples:
// Set read position 25 bytes
// after beginning of file
inData.seekg(25L, ios::beg);
// Set write position 10 bytes
// before current position
outData.seekp(-10L, ios::cur);
13-625
Random Access Information
• tellg member function: return current
byte position in input file, as a long
long whereAmI;
whereAmI = inFile.tellg();
• tellp member function: return current
byte position in output file, as a long
whereAmI = outFile.tellp();
13-626
13.7 Opening a File for Both
Input and Output
• A file can be open for input and output
simultaneously
• Supports updating a file:
– read data from file into memory
– update data
– write data back to file
• Use fstream for file object definition:
fstream gradeList("grades.dat",
ios::in | ios::out);
13-627
Chapter 14: Recursion
Topics
14.1 Introduction to Recursion
14.2 The Recursive Factorial Function
14.3 The Recursive gcd Function
14.4 Solving Recursively Defined Problems
14.5 A Recursive Binary Search Function
14.6 The QuickSort Algorithm
14.7 The Towers of Hanoi
14.8 Exhaustive and Enumeration Algorithms
14.9 Recursion Versus Iteration
14-629
14.1 Introduction to Recursion
• A recursive function is a function that
calls itself.
• Recursive functions can be useful in
solving problems that can be broken
down into smaller or simpler
subproblems of the same type. A base
case should eventually be reached, at
which time the breaking down
(recursion) will stop.
14-630
Recursive Functions
Consider a function for solving the
count-down problem from some number
num down to 0:
– The base case is when num is already 0:
the problem is solved and we “blast off!”
– If num is greater than 0, we count off num
and then recursively count down from
num-1
14-631
Recursive Functions
A recursive function for counting down to 0:
void countDown(int num)
{
if (num == 0)
cout << "Blastoff!";
else
{
cout << num << ". . .";
countDown(num-1); // recursive
} // call
}
14-632
What Happens When Called?
If a program contains a line like countDown(2);
1. countDown(2) generates the output 2..., then
it calls countDown(1)
2. countDown(1) generates the output 1..., then
it calls countDown(0)
3. countDown(0) generates the output
Blastoff!, then returns to countDown(1)
4. countDown(1) returns to countDown(2)
5. countDown(2)returns to the calling function
14-633
What Happens When Called?
14-634
third call to
countDown
num is 0
countDown(1);
countDown(0);
// no
// recursive
// call
second call to
countDown
num is 1
first call to
countDown
num is 2 OUTPUT:
2...
1...
Blastoff!
Stopping the Recursion
• A recursive function should include a
test for the base cases
• In the sample program, the test is:
if (num == 0)
14-635
Stopping the Recursion
void countDown(int num)
{
if (num == 0) // test
cout << "Blastoff!";
else
{
cout << num << "...n";
countDown(num-1); // recursive
} // call
}
14-636
Stopping the Recursion
• With each recursive call, the parameter
controlling the recursion should move
closer to the base case
• Eventually, the parameter reaches the base
case and the chain of recursive calls
terminates
14-637
Stopping the Recursion
void countDown(int num)
{
if (num == 0) // base case
cout << "Blastoff!";
else
{ cout << num << "...n";
countDown(num-1);
}
}
14-638
Value passed to
recursive call is closer to
base case of num = 0.
What Happens When Called?
• Each time a recursive function is called, a new
copy of the function runs, with new instances of
parameters and local variables being created
• As each copy finishes executing, it returns to
the copy of the function that called it
• When the initial copy finishes executing, it
returns to the part of the program that made the
initial call to the function
14-639
Types of Recursion
• Direct recursion
– a function calls itself
• Indirect recursion
– function A calls function B, and function B calls
function A. Or,
– function A calls function B, which calls …,
which then calls function A
14-640
14.2 The Recursive Factorial Function
• The factorial of a nonnegative integer n is
the product of all positive integers less or
equal to n
• The factorial of n is denoted by n!
• The factorial of 0 is 1
0 ! = 1
n ! = n x (n-1) x … x 2 x 1 if n > 0
14-641
Recursive Factorial Function
• Factorial of n can be expressed in terms of
the factorial of n-1
0 ! = 1
n ! = n x (n-1) !
• Recursive function
int factorial(int n)
{ if (n == 0) return 1;
else
return n *factorial(n-1);
}
14-642
14.3 The Recursive gcd Function
• Greatest common divisor (gcd) of two
integers x and y is the largest number that
divides both x and y
• The Greek mathematician Euclid
discovered that
– If y divides x, then gcd(x, y) is just y
– Otherwise, the gcd(x, y) is the gcd of y and the
remainder of dividing x by y
14-643
The Recursive gcd Function
int gcd(int x, int y)
{
if (x % y == 0) //base case
return y;
else
return gcd(y, x % y);
}
14-644
14.4 Solving Recursively Defined
Problems
• The natural definition of some problems
leads to a recursive solution
• Example: Fibonacci numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, ...
• After the initial 0 and 1, each term is the
sum of the two preceding terms
• Recursive calculation of the nth Fibonacci
number:
fib(n) = fib(n – 1) + fib(n – 2);
• Base cases: n == 0, n == 1
14-645
Recursive Fibonacci Function
int fib(int n)
{
if (n <= 0) // base case
return 0;
else if (n == 1) // base case
return 1;
else
return fib(n – 1) + fib(n – 2);
}
14-646
14.5 A Recursive Binary Search Function
• Assume an array a that is sorted in
ascending order, and an item X to
search for
• We want to write a function that
searches for X within the array a,
returning the index of X if it is found, and
returning -1 if X is not in the array
14-647
Recursive Binary Search
A recursive strategy for searching a portion
of the array from index lo to index hi is to
set m to the index of the middle element of
the array:
14-648
m
lo hi
Recursive Binary Search
If a[m] == X, we found X, so return m
If a[m] > X, recursively search a[lo..m-1]
If a[m] < X, recursively search a[m+1..hi]
14-649
m
lo hi
Recursive Binary Search
int bSearch(int a[],int lo,int hi,int X)
{
int m = (lo + hi) /2;
if(lo > hi) return -1; // base
if(a[m] == X) return m; // base
if(a[m] > X)
return bsearch(a,lo,m-1,X);
else
return bsearch(a,m+1,hi,X);
}
14-650
14.6 The QuickSort Algorithm
• Recursive algorithm that can sort an
array
• First, determine an element to use as
pivot value:
14-651
pivot
sublist 1 sublist 2
The QuickSort Algorithm
• Then, values are shifted so that elements in
sublist1 are < pivot and elements in sublist2
are >= pivot
• Algorithm then recursively sorts sublist1 and
sublist2
• Base case: a sublist has size <=1
14-652
pivot value
sublist 1 sublist 2
14.7 The Towers of Hanoi
• Setup: 3 pegs, one has n disks on it, the other two
pegs empty. The disks are arranged in increasing
diameter, top bottom
• Objective: move the disks from peg 1 to peg 3,
observing these rules:
– only one disk moves at a time
– all remain on pegs except the one being moved
– a larger disk cannot be placed on top of a smaller disk
at any time
14-653
The Towers of Hanoi
How it works:
14-654
n=1 Move disk from peg 1 to peg 3.
Done.
n=2 Move top disk from peg 1 to peg 2.
Move remaining disk from peg 1 to peg 3.
Move disk from peg 2 to peg 3.
Done.
Outline of Recursive Algorithm
If n==0, do nothing (base case)
If n>0, then
a. Move the topmost n-1 disks from peg1 to peg2
b. Move the nth disk from peg1 to peg3
c. Move the n-1 disks from peg2 to peg3
end if
14-655
14.8 Exhaustive and Enumeration
Algorithms
• Enumeration algorithm: generate all
possible combinations
Example: all possible ways to make change for a
certain amount of money
• Exhaustive algorithm: search a set of
combinations to find an optimal one
Example: change for a certain amount of money
that uses the fewest coins
14-656
14.9 Recursion vs. Iteration
• Benefits (+), disadvantages(-) for recursion:
+ Natural formulation of solution to certain
problems
+ Results in shorter, simpler functions
– May not execute very efficiently
• Benefits (+), disadvantages(-) for iteration:
+ Executes more efficiently than recursion
– May not be as natural a method of solution as
recursion for some problems
14-657
Chapter 15: Polymorphism and Virtual
Functions
Topics
15.1 Type Compatibility in Inheritance
Hierarchies
15.2 Polymorphism and Virtual Member
Functions
15.3 Abstract Base Classes and Pure Virtual
Functions
15.4 Composition Versus Inheritance
15-659
15.1 Type Compatibility in Inheritance
Hierarchies
• Classes in a program
may be part of an
inheritance hierarchy
• Classes lower in the
hierarchy are special
cases of those above
15-660
Animal
Cat Dog
Poodle
Type Compatibility in Inheritance
• A pointer to a derived class can be
assigned to a pointer to a base class.
Another way to say this is:
• A base class pointer can point to derived
class objects
Animal *pA = new Cat;
15-661
Type Compatibility in Inheritance
• Assigning a base class pointer to a
derived class pointer requires a cast
Animal *pA = new Cat;
Cat *pC;
pC = static_cast<Cat *>(pA);
• The base class pointer must already
point to a derived class object for this to
work
15-662
Using Type Casts with Base Class
Pointers
• C++ uses the declared type of a pointer to
determine access to the members of the
pointed-to object
• If an object of a derived class is pointed to
by a base class pointer, all members of the
derived class may not be accessible
• Type cast the base class pointer to the
derived class (via static_cast) in order
to access members that are specific to the
derived class
15-663
15.2 Polymorphism and Virtual Member
Functions
• Polymorphic code: Code that behaves
differently when it acts on objects of
different types
• Virtual Member Function: The C++
mechanism for achieving polymorphism
15-664
Polymorphism
Consider the Animal,
Cat, Dog hierarchy
where each class has
its own version of the
member function id( )
15-665
Animal
Cat Dog
Poodle
Polymorphism
class Animal{
public: void id(){cout << "animal";}
}
class Cat : public Animal{
public: void id(){cout << "cat";}
}
class Dog : public Animal{
public: void id(){cout << "dog";}
}
15-666
Polymorphism
• Consider the collection of different Animal
objects
Animal *pA[] = {new Animal, new Dog,
new Cat};
and accompanying code
for(int k=0; k<3; k++)
pA[k]->id();
• Prints: animal animal animal, ignoring the
more specific versions of id() in Dog and Cat
15-667
Polymorphism
• The preceding code is not polymorphic:
it behaves the same way even though
Animal, Dog and Cat have different
types and different id() member
functions
• Polymorphic code would have printed
"animal dog cat" instead of
"animal animal animal"
15-668
Polymorphism
• The code is not polymorphic because in the
expression
pA[k]->id()
the compiler sees only the type of the
pointer pA[k], which is pointer to Animal
• Compiler does not see type of actual object
pointed to, which may be Animal, or Dog,
or Cat
15-669
Virtual Functions
Declaring a function virtual will make
the compiler check the type of each
object to see if it defines a more specific
version of the virtual function
15-670
Virtual Functions
If the member functions id()are declared
virtual, then the code
Animal *pA[] = {new Animal,
new Dog,new Cat};
for(int k=0; k<3; k++)
pA[k]->id();
will print animal dog cat
15-671
Virtual Functions
How to declare a member function virtual:
class Animal{
public: virtual void id(){cout << "animal";}
}
class Cat : public Animal{
public: virtual void id(){cout << "cat";}
}
class Dog : public Animal{
public: virtual void id(){cout << "dog";}
}
15-672
Function Binding
• In pA[k]->id(), Compiler must choose
which version of id() to use: There are
different versions in the Animal, Dog, and Cat
classes
• Function binding is the process of determining
which function definition to use for a particular
function call
• The alternatives are static and dynamic binding
15-673
Static Binding
• Static binding chooses the function in the
class of the base class pointer, ignoring
any versions in the class of the object
actually pointed to
• Static binding is done at compile time
15-674
Dynamic Binding
• Dynamic Binding determines the function to
be invoked at execution time
• Can look at the actual class of the object
pointed to and choose the most specific
version of the function
• Dynamic binding is used to bind virtual
functions
15-675
15.3 Abstract Base Classes and Pure
Virtual Functions
• An abstract class is a class that contains no
objects that are not members of subclasses
(derived classes)
• For example, in real life, Animal is an
abstract class: there are no animals that
are not dogs, or cats, or lions…
15-676
Abstract Base Classes and Pure Virtual
Functions
• Abstract classes are an organizational tool.
They are useful in organizing inheritance
hierarchies
• Abstract classes can be used to specify an
interface that must be implemented by all
subclasses
15-677
Abstract Functions
• The member functions specified in an
abstract class do not have to be
implemented
• The implementation is left to the
subclasses
• In C++, an abstract class is a class with at
least one abstract member function
15-678
Pure Virtual Functions
• In C++, a member function of a class is
declared to be an abstract function by making
it virtual and replacing its body with = 0;
class Animal{
public:
virtual void id()=0;
};
• A virtual function with its body omitted and
replaced with =0 is called a pure virtual
function, or an abstract function
15-679
Abstract Classes
• An abstract class can not be instantiated
• An abstract class can only be inherited
from; that is, you can derive classes
from it
• Classes derived from abstract classes
must override all pure virtual functions
with a concrete member functions before
they can be instantiated.
15-680
15.4 Composition vs. Inheritance
• Inheritance models an 'is a' relation
between classes. An object of a derived
class 'is a(n)' object of the base class
• Example:
– an UnderGrad is a Student
– a Mammal is an Animal
– a Poodle is a Dog
15-681
Composition vs. Inheritance
• When defining a new class:
• Composition is appropriate when the new class
needs to use an object of an existing class
• Inheritance is appropriate when
– objects of the new class are a subset of the objects
of the existing class, or
– objects of the new class will be used in the same
ways as the objects of the existing class
15-682
Chapter 16: Exceptions, Templates, and
the Standard Template Library (STL)
Topics
16.1 Exceptions
16.2 Function Templates
16.3 Class Templates
16.4 Class Templates and Inheritance
16.5 Introduction to the Standard Template
Library
16-684
16.1 Exceptions
• An exception is a value or an object that
indicates that an error has occurred
• When an exception occurs, the program
must either terminate or jump to special
code for handling the exception.
• The special code for handling the exception
is called an exception handler
16-685
Exceptions – Key Words
• throw – followed by an argument, is
used to signal an exception
• try – followed by a block { }, is used to
invoke code that throws an exception
• catch – followed by a block { }, is used
to process exceptions thrown in a
preceding try block. It takes a
parameter that matches the type of
exception thrown
16-686
Throwing an Exception
• Code that detects the exception must pass
information to the exception handler. This is
done using a throw statement:
throw "Emergency!"
throw 12;
• In C++, information thrown by the throw
statement may be a value of any type
16-687
Catching an Exception
• Block of code that handles the exception is
said to catch the exception and is called an
exception handler
• An exception handler is written to catch
exceptions of a given type: For example, the
code
catch(char *str)
{
cout << str;
}
can only catch exceptions of type C-string
16-688
Catching an Exception
Another example of a handler:
catch(int x)
{
cerr << "Error: " << x;
}
This can catch exceptions of type int
16-689
Connecting to the Handler
Every catch block is attached to a try block of code and is
responsible for handling exceptions thrown from that block
try
{
}
catch(char e1)
{
// This code handles exceptions
// of type char that are thrown
// in this block
}
16-690
Execution of Catch Blocks
• The catch block syntax is similar to a that of
a function
• A catch block has a formal parameter that
is initialized to the value of the thrown
exception before the block is executed
16-691
Exception Example
• An example of exception handling is code
that computes the square root of a number.
• It throws an exception in the form of a C-
string if the user enters a negative number
16-692
Example
int main( )
{
try
{
double x;
cout << "Enter a number: ";
cin >> x;
if (x < 0) throw "Bad argument!";
cout << "Square root of " << x << " is " << sqrt(x);
}
catch(char *str)
{
cout << str;
}
return 0;
}
16-693
Flow of Control
1. Computer encounters a throw statement in
a try block
2. The computer evaluates the throw
expression, and immediately exits the try
block
3. The computer selects an attached catch
block that matches the type of the thrown
value, places the value in the catch block’s
formal parameter, and executes the catch
block
16-694
Uncaught Exception
• An exception may be uncaught if
– there is no catch block with a data type that
matches the exception that was thrown, or
– it was not thrown from within a try block
• The program will terminate in either case
16-695
Handling Multiple Exceptions
Multiple catch blocks can be attached to
the same block of code. The catch blocks
should handle exceptions of different types
try{...}
catch(int iEx){ }
catch(char *strEx){ }
catch(double dEx){ }
16-696
Throwing an Exception Class
• An exception class can be defined and
thrown
• A catch block must be designed to catch an
object of the exception class
• The exception class object can pass data
to exception handler via data members
16-697
Exception When Calling new
• If new cannot allocate memory, it throws an
exception of type bad_alloc
• Must #include <new> to use bad_alloc
• Can invoke new from within a try block,
and use a catch block to detect that
memory was not allocated.
16-698
Nested Exception Handling
try blocks can be nested in other try
blocks and even in catch blocks
try
{
try{ } catch(int i){ }
}
catch(char *s)
{ }
16-699
Where to Find an Exception Handler?
• The compiler looks for a suitable handler
attached to an enclosing try block in
the same function
• If there is no matching handler in the
function, it terminates execution of the
function, and continues the search for a
handler starting at the point of the call in
the calling function.
16-700
Unwinding the Stack
• An unhandled exception propagates
backwards into the calling function and
appears to be thrown at the point of the call
• The computer will keep terminating function
calls and tracing backwards along the call
chain until it finds an enclosing try block with
a matching handler, or until the exception
propagates out of main (terminating the
program).
• This process is called unwinding the call stack
16-701
Rethrowing an Exception
• Sometimes an exception handler may need
to do some tasks, then pass the exception
to a handler in the calling environment.
• The statement
throw;
with no parameters can be used within a
catch block to pass the exception to a
handler in the outer block
16-702
16.2 Function Templates
• Function template: A pattern for creating
definitions of functions that differ only in the
type of data they manipulate. It is a generic
function
• They are better than overloaded functions,
since the code defining the algorithm of the
function is only written once
16-703
Example
Two functions that differ only in the type of the
data they manipulate
void swap(int &x, int &y)
{ int temp = x; x = y;
y = temp;
}
void swap(char &x, char &y)
{ char temp = x; x = y;
y = temp;
}
16-704
A swap Template
The logic of both functions can be captured
with one template function definition
template<class T>
void swap(T &x, T &y)
{ T temp = x; x = y;
y = temp;
}
16-705
Using a Template Function
• When a function defined by a template is called,
the compiler creates the actual definition from the
template by inferring the type of the type
parameters from the arguments in the call:
int i = 1, j = 2;
swap(i,j);
• This code makes the compiler instantiate the
template with type int in place of the type
parameter T
16-706
Function Template Notes
• A function template is a pattern
• No actual code is generated until the
function named in the template is called
• A function template uses no memory
• When passing a class object to a function
template, ensure that all operators
referred to in the template are defined or
overloaded in the class definition
16-707
Function Template Notes
• All data types specified in template prefix
must be used in template definition
• Function calls must pass parameters for all
data types specified in the template prefix
• Function templates can be overloaded –
need different parameter lists
• Like regular functions, function templates
must be defined before being called
16-708
Where to Start When Defining
Templates
• Templates are often appropriate for
multiple functions that perform the same
task with different parameter data types
• Develop function using usual data types
first, then convert to a template:
– add template prefix
– convert data type names in the function to a
type parameter (i.e., a T type) in the template
16-709
16.3 Class Templates
• It is possible to define templates for
classes. Such classes define abstract data
types
• Unlike functions, a class template is
instantiated by supplying the type name
(int, float, string, etc.) at object
definition
16-710
Class Template
Consider the following classes
1. Class used to join two integers by adding them:
class Joiner
{ public:
int combine(int x, int y)
{return x + y;}
};
2. Class used to join two strings by concatenating them:
class Joiner
{ public:
string combine(string x, string y)
{return x + y;}
};
16-711
Example class Template
A single class template can capture the logic of
both classes: it is written with a template prefix
that specifies the data type parameters:
template <class T>
class Joiner
{
public:
T combine(T x, T y)
{return x + y;}
};
16-712
Using Class Templates
To create an object of a class defined by a
template, specify the actual parameters for the
formal data types
Joiner<double> jd;
Joiner<string> sd;
cout << jd.combine(3.0, 5.0);
cout << sd.combine("Hi ", "Ho");
Prints 8.0 and Hi Ho
16-713
16.4 Class Templates and Inheritance
• Templates can be combined with
inheritance
• You can derive
– Non template classes from a template class:
instantiate the base class template and then
inherit from it
– Template class from a template class
• Other combinations are possible
16-714
16.5 Introduction to the Standard
Template Library
• Standard Template Library (STL): a library
containing templates for frequently used
data structures and algorithms
• Programs can be developed faster and are
more portable if they use templates from
the STL
16-715
Standard Template Library
Two important types of data structures in
the STL:
– containers: classes that store data and impose
some organization on it
– iterators: like pointers; provides mechanisms
for accessing elements in a container
16-716
Containers
Two types of container classes in STL:
– sequential containers: organize and access
data sequentially, as in an array. These
include vector, dequeue, and list
containers.
– associative containers: use keys to allow
data elements to be quickly accessed.
These include set, multiset, map, and
multimap containers.
16-717
Creating Container Objects
• To create a list of int, write
list<int> mylist;
• To create a vector of string objects,
write
vector<string> myvector;
• Requires the vector header file
16-718
Iterators
• Generalization of pointers, used to
access information in containers
• Many types:
– forward (uses ++)
– bidirectional (uses ++ and -- )
– random-access
– input (can be used with cin and istream
objects)
– output (can be used with cout and
ostream objects)
16-719
Containers and Iterators
• Each container class defines an iterator
type, used to access its contents
• The type of an iterator is determined by
the type of the container:
list<int>::iterator x;
list<string>::iterator y;
x is an iterator for a container of type
list<int>
16-720
Containers and Iterators
Each container class defines functions
that return iterators:
begin(): returns iterator to item at start
end(): returns iterator denoting end of
container
16-721
Containers and Iterators
• Iterators support pointer-like operations. If
iter is an iterator, then
– *iter is the item it points to: this
dereferences the iterator
– iter++ advances to the next item in the
container
– iter-- backs up in the container
• The end() iterator points to past the end:
it should never be dereferenced
16-722
Traversing a Container
Given a vector:
vector<int> v;
for (int k=1; k<= 5; k++)
v.push_back(k*k);
Traverse it using iterators:
vector<int>::iterator iter = v.begin();
while (iter != v.end())
{ cout << *iter << " "; iter++}
Prints 1 4 9 16 25
16-723
Some vector Class Member Functions
Function Description
front(), back() Returns a reference to the first, last element in a vector
size() Returns the number of elements in a vector
capacity() Returns the number of elements that a vector can hold
clear() Removes all elements from a vector
push_back(value) Adds element containing value as the last element in the
vector
pop_back() Removes the last element from the vector
insert(iter, value) Inserts new element containing value just before element
pointed at by iter
16-724
Algorithms
• STL contains algorithms that are
implemented as function templates to
perform operations on containers.
• Requires algorithm header file
• Collection of algorithms includes
16-725
binary_search count
for_each find
max_element min_element
random_shuffle sort
and others
Using STL algorithms
• Many STL algorithms manipulate portions
of STL containers specified by a begin and
end iterator
• max_element(iter1, iter2) finds
max element in the portion of a container
delimited by iter1, iter2
• min_element(iter1, iter2) is similar
to above
16-726
More STL algorithms
• random_shuffle(iter1, iter2)
randomly reorders the portion of the
container in the given range
• sort(iter1, iter2) sorts the portion
of the container specified by the given
range
16-727
random-shuffle Example
The following example stores the
squares 1, 4, 9, 16, 25 in a vector,
shuffles the vector, and then prints it out
16-728
random_shuffle example
int main()
{
vector<int> vec;
for (int k = 1; k <= 5; k++)
vec.push_back(k*k);
random_shuffle(vec.begin(),vec.end());
vector<int>::iterator p = vec.begin();
while (p != vec.end())
{ cout << *p << " "; p++;
}
return 0;
}
16-729
Chapter 17: Linked Lists
Topics
17.1 Introduction to the Linked List ADT
17.2 Linked List Operations
17.3 A Linked List Template
17.4 Recursive Linked List Operations
17.5 Variations of the Linked List
17.6 The STL list Container
17-731
17.1 Introduction to the Linked List ADT
• Linked list: a sequence of data structures (nodes) with
each node containing a pointer to its successor
• The last node in the list has its successor pointer set to
NULL
17-732
NULL
list
head
Linked List Terminology
• The node at the beginning is called the
head of the list
• The entire list is identified by the pointer
to the head node. This pointer is called
the list head.
17-733
Linked Lists
• Nodes can be added or removed from
the linked list during execution
• Addition or removal of nodes can take
place at beginning, end, or middle of the
list
17-734
NULL
list
head Add or delete node
Linked Lists vs. Arrays and Vectors
• Linked lists can grow and shrink as
needed, unlike arrays, which have a fixed
size
• Unlike vectors, insertion or removal of a
node in the middle of the list is very efficient
17-735
NULL
list
head
Node Organization
A node contains:
– data: one or more data fields – may be
organized as structure, object, etc.
– a pointer that can point to another node
17-736
data
pointer
Empty List
• A list with no nodes is called the empty
list
• In this case the list head is set to NULL
17-737
NULL
list
head
Creating an Empty List
• Define a pointer for the head of the list:
ListNode *head = NULL;
• Head pointer initialized to NULL to indicate
an empty list
17-738
NULL
head
C++ Implementation
Implementation of nodes requires a
structure containing a pointer to a structure
of the same type (a self-referential data
structure):
struct ListNode
{
int data;
ListNode *next;
};
17-739
C++ Implementation
Nodes can be equipped with constructors:
struct ListNode
{
int data;
ListNode *next;
ListNode(int d, ListNode* p=NULL)
{data = d; next = p;}
};
17-740
Building a List from a File of Numbers
ListNode *head = NULL;
int val;
while (inFile >> val)
{
// add new nodes at the head
head = new ListNode(val, head);
};
17-741
Traversing a Linked List
• List traversals visit each node in a linked list
to display contents, validate data, etc.
• Basic process of traversal:
set a pointer to the head pointer
while pointer is not NULL
process data
set pointer to the successor of the current node
end while
17-742
Traversing a Linked List
17-743
NULL
list
head
5 13 19
nodePtr
nodePtr points to the node containing 5, then the
node containing 13, then the node containing 19,
then points to NULL, and the list traversal stops
17.2 Linked List Operations
Basic operations:
• add a node to the end of the list
• insert a node within the list
• traverse the linked list
• Delete/remove a node from the list
• delete/destroy the list
17-744
Creating a Node
ListNode *p;
int num = 23;
p = new ListNode(num);
17-745
NULL
23
p
Appending an Item
To add an item to the end of the list:
• If the list is empty, set head to a new node
containing the item
head = new ListNode(num);
• If the list is not empty, move a pointer p to the last
node, then add a new node containing the item
p->next = new ListNode(num);
17-746
Appending an Item
17-747
list
head
5 13 23
p
NULL
List originally has nodes
with 5 and 13.
p locates the last node,
then a node with a new
item, 23, is added
Destroying a Linked List
• Must remove all nodes used in the list
• To do this, use list traversal to visit each
node
• For each node,
– Unlink the node from the list
– Free the node’s memory
• Finally, set the list head to NULL
17-748
Inserting a Node
• Used to insert an item into a sorted list,
keeping the list sorted.
• Two possibilities:
– Insertion is at the head of the list (because
item at head is already greater than item
being inserted, or because list is empty
– Insertion is after an existing node in a non-
empty list
17-749
Inserting a Node at Head of a List
• Test to see if
– head pointer is NULL, or
– node value pointed at by head is greater
than value to be inserted
• Must test in this order: unpredictable
results if second test is attempted on an
empty list
• Create new node, set its next pointer to
head, then point head to it
17-750
Inserting a Node in Body of a List
• Requires two pointers to traverse the list:
– pointer to locate the node with data value
greater than that of node to be inserted
– pointer to 'trail behind' one node, to point to
node before point of insertion
• New node is inserted between the nodes
pointed at by these pointers
17-751
Inserting a Node into a
Linked List
17-752
NULL
list
head
5 13 19
17
nodePtr
previousNode
Correct position located
Item to insert
num
Inserting a Node into a
Linked List
17-753
NULL
list
head
5 13 19
17
nodePtr
previousNode
New node created and inserted in order in the linked list
Removing an Element
• Used to remove a node from a linked list
• Requires two pointers: one to locate the
node to be deleted, one to point to the
node before the node to be deleted
17-754
Deleting a Node
17-755
NULL
list
head
5 13 19
nodePtr
previousNode
Locating the node containing 13
Contents of node to
be deleted: 13
Deleting a Node
17-756
NULL
list
head
5 13 19
nodePtr
previousNode
Adjusting pointer around the node to be deleted
Deleting a Node
17-757
NULL
list
head
5 19
nodePtr
previousNode
Linked list after deleting the node containing 13
17.3 A Linked List Template
• A linked list template can be written by
replacing the type of the data in the node
with a type parameter, say T.
• If defining the linked list as a class
template, then all member functions must
be function templates
• Implementation assumes use with data
types that support comparison: == and <=
17-758
17.4 Recursive Linked List Operations
• A non-empty linked list consists of a
head node followed by the rest of the
nodes
• The rest of the nodes form a linked list
that is called the tail of the original list
17-759
Recursive Linked List Operations
Many linked list operations can be
broken down into the smaller problems
of processing the head of the list and
then recursively operating on the tail of
the list
17-760
Recursive Linked List Operations
To find the length (number of elements) of
a list
– If the list is empty, the length is 0 (base
case)
– If the list is not empty, find the length of the
tail and then add 1 to obtain the length of
the original list
17-761
Recursive Linked List Operations
To find the length of a list:
int length(ListNode *myList)
{
if (myList == NULL) return 0;
else
return 1 + length(myList->next);
}
17-762
Recursive Linked List Operations
Using recursion to display a list:
void displayList(ListNode *myList)
{
if (myList != NULL)
{
cout << myList->data << " ";
displayList(myList->next);
}
}
17-763
Other Recursive Linked List Operations
• Insert and remove operations can be written to
use recursion
• General design considerations:
– Base case is often when the list is empty
– Recursive case often involves the use of the tail of the
list (i.e., the list without the head). Since the tail has
one fewer entry than the list that was passed in to this
call, the recursion eventually stops.
17-764
17.5 Variations of the Linked List
Other linked list organizations:
– doubly-linked list: each node contains two
pointers: one to the next node in the list, one to
the previous node in the list
17-765
NULL
list
head
5 13 19
NULL
Variations of the Linked List
Other linked list organizations:
– circular linked list: the last node in the list
points back to the first node in the list, not to
NULL
17-766
list
head
5 13 19
17.6 The STL list Container
• Template for a doubly linked list
• Member functions for
– locating beginning, end of list: front,
back, end
– adding elements to the list: insert,
merge, push_back, push_front
– removing elements from the list: erase,
pop_back, pop_front, unique
17-767
Chapter 18: Stacks and Queues
Topics
18.1 Introduction to the Stack ADT
18.2 Dynamic Stacks
18.3 The STL stack Container
18.4 Introduction to the Queue ADT
18.5 Dynamic Queues
18.6 The STL deque and queue Containers
18.7 Eliminating Recursion
18-769
18.1 Introduction to the Stack ADT
• Stack: a LIFO (last in, first out) data
structure
• Examples:
– plates in a cafeteria serving area
– return addresses for function calls
18-770
Stack Basics
• Stack is usually implemented as a list,
with additions and removals taking place
at one end of the list
• The active end of the list implementing
the stack is the top of the stack
• Stack types:
– Static – fixed size, often implemented using
an array
– Dynamic – size varies as needed, often
implemented using a linked list
18-771
Stack Operations and Functions
Operations:
– push: add a value at the top of the stack
– pop: remove a value from the top of the stack
Functions:
– isEmpty: true if the stack currently contains no
elements
– isFull: true if the stack is full; only useful for
static stacks
18-772
Static Stack Implementation
• Uses an array of a fixed size
• Bottom of stack is at index 0. A variable called
top tracks the current top of the stack
const int STACK_SIZE = 3;
char s[STACK_SIZE];
int top = 0;
top is where the next item will be added
18-773
Array Implementation Example
This stack has max capacity 3, initially top = 0 and
stack is empty.
K
E
G
K
E
18-774
E
push('E'); push('K'); push('G');
top is 1 top is 2 top is 3
Stack Operations Example
After three pops, top is 0 and the stack is empty
E
18-775
K
E
pop();
(remove G)
pop();
(remove K)
pop();
(remove E)
Array Implementation
char s[STACK_SIZE];
int top=0;
To check if stack is empty:
bool isEmpty()
{
if (top == 0)
return true;
else return false;
}
18-776
Array Implementation
char s[STACK_SIZE];
int top=0;
To check if stack is full:
bool isFull()
{
if (top == STACK_SIZE)
return true;
else return false;
}
18-777
Array Implementation
To add an item to the stack
void push(char x)
{
if (isFull())
{error(); exit(1);}
// or could throw an exception
s[top] = x;
top++;
}
18-778
Array Implementation
To remove an item from the stack
void pop(char &x)
{
if (isEmpty())
{error(); exit(1);}
// or could throw an exception
top--;
x = s[top];
}
18-779
Class Implementation
class STACK
{
private:
char *s;
int capacity, top;
public:
void push(char x);
void pop(char &x);
bool isFull(); bool isEmpty();
STACK(int stackSize);
~STACK()
};
18-780
Exceptions from Stack Operations
• Exception classes can be added to the
stack object definition to handle cases
where an attempt is made to push onto a
full stack (overflow) or to pop from an
empty stack (underflow)
• Programs that use push and pop
operations should do so from within a try
block.
• catch block(s) should follow the try
block, interpret what occurred, and inform
the user.
18-781
18.2 Dynamic Stacks
• Implemented as a linked list
• Can grow and shrink as necessary
• Can't ever be full as long as memory is
available
18-782
Dynamic Linked List Implementation
• Define a class for a dynamic linked list
• Within the class, define a private member
class for dynamic nodes in the list
• Define a pointer to the beginning of the
linked list, which will serve as the top of the
stack
18-783
Linked List Implementation
A linked stack after three push operations:
push('a'); push('b'); push('c');
18-784
NULL
top
a
b
c
Operations on a Linked Stack
Check if stack is empty:
bool isEmpty()
{
if (top == NULL)
return true;
else
return false;
}
18-785
Operations on a Linked Stack
Add a new item to the stack
void push(char x)
{
top = new LNode(x, top);
}
18-786
Operations on a Linked Stack
Remove an item from the stack
void pop(char &x)
{
if (isEmpty())
{ error(); exit(1);}
x = top->value;
LNode *oldTop = top;
top = top->next;
delete oldTop;
}
•
18-787
18.3 The STL stack Container
• Stack template can be implemented as a
vector, list, or a deque
• Implements push, pop, and empty
member functions
• Implements other member functions:
– size: number of elements on the stack
– top: reference to element on top of the stack
(must be used with pop to remove and retrieve
top element)
18-788
Defining an STL-based Stack
• Defining a stack of char, named cstack,
implemented using a vector:
stack< char, vector<char> > cstack;
• Implemented using a list:
stack< char, list<char> > cstack;
• Implemented using a deque (default):
stack< char > cstack;
• Spaces are required between consecutive > >
symbols to distinguish from stream extraction
18-789
18.4 Introduction to the Queue ADT
• Queue: a FIFO (first in, first out) data
structure.
• Examples:
– people in line at the theatre box office
– print requests sent by users to a network printer
• Implementation:
– static: fixed size, implemented as array
– dynamic: variable size, implemented as linked
list
18-790
Queue Locations and Operations
• rear: position where elements are added
• front: position from which elements are
removed
• enqueue: add an element to the rear of
the queue
• dequeue: remove an element from the
front of a queue
18-791
Array Implementation of Queue
An empty queue that can hold char values:
enqueue('E');
E
18-792
front rear
front, rear
Queue Operations - Example
enqueue('K');
enqueue('G');
E K
E K G
18-793
front rear
front rear
Queue Operations - Example
dequeue(); // remove E
dequeue(); // remove K
K G
G
18-794
front rear
front rear
Array Implementation Issues
• In the preceding example, Front never
moves.
• Whenever dequeue is called, all remaining
queue entries move up one position. This
takes time.
• Alternate approach:
– Circular array: front and rear both move
when items are added and removed. Both can
‘wrap around’ from the end of the array to the
front if warranted.
• Other conventions are possible
18-795
Array Implementation Issues
• Variables needed
– const int QSIZE = 100;
– char q[QSIZE];
– int front = -1;
– int rear = -1;
– int number = 0; //how many in queue
• Could make these members of a queue
class, and queue operations would be
member functions
18-796
isEmpty Member Function
Check if queue is empty
bool isEmpty()
{
if (number > 0)
return false;
else
return true;
}
18-797
isFull Member Function
Check if queue is full
bool isFull()
{
if (number < QSIZE)
return false;
else
return true;
}
18-798
enqueue and dequeue
• To enqueue, we need to add an item x to
the rear of the queue
• Queue convention says q[rear] is
already occupied. Execute
if(!isFull)
{ rear = (rear + 1) % QSIZE;
// mod operator for wrap-around
q[rear] = x;
number ++;
}
18-799
enqueue and dequeue
• To dequeue, we need to remove an item x
from the front of the queue
• Queue convention says q[front] has
already been removed. Execute
if(!isEmpty)
{ front = (front + 1) % QSIZE;
x = q[front];
number--;
}
18-800
enqueue and dequeue
• enqueue moves rear to the right as it fills
positions in the array
• dequeue moves front to the right as it empties
positions in the array
• When enqueue gets to the end, it wraps around
to the beginning to use those positions that have
been emptied
• When dequeue gets to the end, it wraps around
to the beginning use those positions that have
been filled
18-801
enqueue and dequeue
• Enqueue wraps around by executing
rear = (rear + 1) % QSIZE;
• Dequeue wraps around by executing
front = (front + 1) % QSIZE;
18-802
Exception Handling in Static Queues
• As presented, the static queue class will encounter
an error if an attempt is made to enqueue an element
to a full queue, or to dequeue an element from an
empty queue
• A better design is to throw an underflow or an
overflow exception and allow the programmer to
determine how to proceed
• Remember to throw exceptions from within a try
block, and to follow the try block with a catch block
18-803
18.5 Dynamic Queues
• Like a stack, a queue can be implemented
using a linked list
• This allows dynamic sizing and avoids the
issue of wrapping indices
18-804
front rear
NULL
Dynamic Queue Implementation Data
Structures
• Define a class for the dynamic queue
• Within the dynamic queue, define a private
member class for a dynamic node in the
queue
• Define pointers to the front and rear of the
queue
18-805
isEmpty Member Function
To check if queue is empty:
bool isEmpty()
{
if (front == NULL)
return true;
else
return false;
}
18-806
enqueue Member Function Details
To add item at rear of queue
if (isEmpty())
{
front = new QNode(x);
rear = front;
}
else
{
rear->next = new QNode(x);
rear = rear->next;
}
18-807
dequeue Member Function
To remove item from front of queue
if (isEmpty())
{
error(); exit(1);
}
x = front->value;
QNode *oldfront = front;
front = front->next;
delete oldfront;
18-808
18.6 The STL deque and queue
Containers
• deque: a double-ended queue (DEC). Has
member functions to enqueue
(push_back) and dequeue (pop_front)
• queue: container ADT that can be used to
provide a queue based on a vector, list,
or deque. Has member functions to
enqueue (push) and dequeue (pop)
18-809
Defining a Queue
• Defining a queue of char, named cQueue, based
on a deque:
deque<char> cQueue;
• Defining a queue with the default base container
queue<char> cQueue;
• Defining a queue based on a list:
queue<char, list<char> > cQueue;
• Spaces are required between consecutive > >
symbols to distinguish from stream extraction
18-810
18.7 Eliminating Recursion
• Recursive solutions to problems are often
elegant but inefficient
• A solution that does not use recursion is
more efficient for larger sizes of inputs
• Eliminating the recursion: re-writing a
recursive algorithm so that it uses other
programming constructs (stacks, loops)
rather than recursive calls
18-811
Chapter 19: Binary Trees
Topics
19.1 Definition and Application of Binary Trees
19.2 Binary Search Tree Operations
19.3 Template Considerations for Binary
Search Trees
19-813
19.1 Definition and Application of Binary
Trees
• Binary tree: a nonlinear data structure in
which each node may point to 0, 1, or
two other nodes
• The nodes that a node
N points to are the
(left or right)
children
of N
19-814
NULL NULL
NULL NULL NULL NULL
Terminology
• If a node N is a child of another node P,
then P is called the parent of N
• A node that has no children is called a
leaf node
• In a binary tree there is a unique node
with no parent. This is the root of the tree
19-815
Binary Tree Terminology
• Root pointer: like a
head pointer for a
linked list, it points to
the root node of the
binary tree
• Root node: the node
with no parent
19-816
NULL NULL
NULL NULL NULL NULL
Binary Tree Terminology
Leaf nodes: nodes
that have no
children
The nodes
containing 7 and
43 are leaf nodes
19-817
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Binary Tree Terminology
Child nodes,
children:
The children of the
node containing 31
are the nodes
containing 19 and
59
19-818
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Binary Tree Terminology
The parent of the
node containing 43
is the node
containing 59
19-819
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Binary Tree Terminology
• A subtree of a binary tree is a part of the
tree from a node N down to the leaf
nodes
• Such a subtree is said to be rooted at N,
and N is called the root of the subtree
19-820
Subtrees of Binary Trees
• A subtree of a binary tree is itself a binary
tree
• A nonempty binary tree consists of a root
node, with the rest of its nodes forming two
subtrees, called the left and right subtree
19-821
Binary Tree Terminology
• The node containing
31 is the root
• The nodes containing
19 and 7 form the left
subtree
• The nodes containing
59 and 43 form the
right subtree
19-822
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Uses of Binary Trees
• Binary search tree: a
binary tree whose data is
organized to simplify
searches
• Left subtree at each node
contains data values less
than the data in the node
• Right subtree at each
node contains values
greater than the data in
the node
•
19-823
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
19.2 Binary Search Tree Operations
• Create a binary search tree
• Insert a node into a binary tree – put node into
tree in its correct position to maintain order
• Find a node in a binary tree – locate a node
with particular data value
• Delete a node from a binary tree – remove a
node and adjust links to preserve the binary tree
and the order
19-824
Binary Search Tree Node
• A node in a binary tree is like a node in a linked
list, except that it has two node pointer fields:
class TreeNode
{
int value;
TreeNode *left;
TreeNode *right;
};
• Define the nodes as class objects. A
constructor can aid in the creation of nodes
19-825
TreeNode Constructor
TreeNode::TreeNode(int val,
TreeNode *l1=NULL,
TreeNode *r1=NULL)
{
value = val;
left = l1;
right = r1;
}
19-826
Creating a New Node
TreeNode *p;
int num = 23;
p = new TreeNode(num);
19-827
NULL
NULL
23
p
Inserting an item into a Binary Search
Tree
1) If the tree is empty, replace the empty tree
with a new binary tree consisting of the
new node as root, with empty left and right
subtrees
2) Otherwise, if the item is less than the root,
recursively insert the item in the left
subtree. If the item is greater than the
root, recursively insert the item into the
right subtree
19-828
Inserting an item into a Binary Search
Tree
19-829
NULL NULL
7
19
31
43
59
root
Step 1: 23 is less than
31. Recursively insert
23 into the left subtree
Step 2: 23 is
greater than 19.
Recursively
insert 23 into the
right subtree
Step 3: Since the right
subtree is NULL, insert
23 here
NULL NULL NULL NULL
value to insert:
23
Traversing a Binary Tree
Three traversal methods:
1) Inorder:
a) Traverse left subtree of node
b) Process data in node
c) Traverse right subtree of node
2) Preorder:
a) Process data in node
b) Traverse left subtree of node
c) Traverse right subtree of node
3) Postorder:
a) Traverse left subtree of node
b) Traverse right subtree of node
c) Process data in node
19-830
Traversing a Binary Tree
19-831
NULL NULL
7
19
31
43
59
TRAVERSAL
METHOD
NODES ARE
VISITED IN
THIS ORDER
Inorder 7, 19, 31,
43, 59
Preorder 31, 19, 7,
59, 43
Postorder 7, 19, 43,
59, 31
NULL NULL NULL NULL
Searching in a Binary Tree
1) Start at root node
2) Examine node data:
a) Is it desired value? Done
b) Else, is desired data <
node data? Repeat step
2 with left subtree
c) Else, is desired data >
node data? Repeat step
2 with right subtree
3) Continue until desired
value found or NULL
pointer reached
19-832
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Searching in a Binary Tree
To locate the node
containing 43,
1. Examine the root node
(31)
2. Since 43 > 31,
examine the right child
of the node containing
31, (59)
3. Since 43 < 59,
examine the left child of
the node containing 59,
(43)
4. The node containing 43
has been found
19-833
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
Deleting a Node from a
Binary Tree – Leaf Node
If node to be deleted is a leaf node, replace
parent node’s pointer to it with a NULL
pointer, then delete the node
19-834
NULL
7
19
NULL NULL
NULL
19
NULL
Deleting node with
7 – before deletion
Deleting node with
7 – after deletion
Deleting a Node from a
Binary Tree – One Child
If node to be deleted has one child node,
adjust pointers so that parent of node to
be deleted points to child of node to be
deleted, then delete the node
19-835
Deleting a Node from a
Binary Tree – One Child
19-836
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
NULL
7
31
43
59
NULL NULL
NULL NULL
Deleting node containing
19 – before deletion
Deleting node containing
19 – after deletion
Deleting a Node from a
Binary Tree – Two Children
• If node to be deleted has left and right children,
– ‘Promote’ one child to take the place of the deleted
node
– Locate correct position for other child in subtree of
promoted child
• Convention in text: “attach" the right subtree to
its parent, then position the left subtree at the
appropriate point in the right subtree
19-837
Deleting a Node from a
Binary Tree – Two Children
19-838
NULL NULL
7
19
31
43
59
NULL NULL NULL NULL
43
59
NULL
NULL
Deleting node with
31 – before deletion
Deleting node with
31 – after deletion
7
19
NULL NULL
NULL
19.3 Template Considerations for
Binary Search Trees
• Binary tree can be implemented as a
template, allowing flexibility in determining
type of data stored
• Implementation must support relational
operators >, <, and == to allow comparison
of nodes
19-839

More Related Content

PDF
SPL 2 | Algorithms, Pseudo-code, and Flowchart
PPTX
INSTRUCTION CYCLE
PDF
22CS201 COA
PDF
Kmap..(karnaugh map)
PPT
Instruction cycle
ODP
D Flip Flop
PPTX
Instruction cycle.pptx
PPTX
Data types in C
SPL 2 | Algorithms, Pseudo-code, and Flowchart
INSTRUCTION CYCLE
22CS201 COA
Kmap..(karnaugh map)
Instruction cycle
D Flip Flop
Instruction cycle.pptx
Data types in C

What's hot (20)

PPT
KMAP
PPTX
Types of flip flops ppt
PPTX
Addressing modes
PPT
Instruction format
PPT
CPU Register Organization.ppt
PPTX
RISC Vs CISC Computer architecture and design
PPTX
Unit 1 data representation and computer arithmetic
PPTX
Flip flop’s state tables & diagrams
PPTX
Booth’s algorithm.(a014& a015)
PPT
Basics of c++ Programming Language
PPTX
PDF
Digital Electronics- Number systems & codes
PPTX
K - Map
PPT
Memory Reference instruction
PPT
Flip-Flop || Digital Electronics
PPTX
Computer data type and Terminologies
PDF
State equationlecture
PPTX
Micro Programmed Control Unit
PPTX
Number system in Digital Electronics
PPT
Logic design and switching theory
KMAP
Types of flip flops ppt
Addressing modes
Instruction format
CPU Register Organization.ppt
RISC Vs CISC Computer architecture and design
Unit 1 data representation and computer arithmetic
Flip flop’s state tables & diagrams
Booth’s algorithm.(a014& a015)
Basics of c++ Programming Language
Digital Electronics- Number systems & codes
K - Map
Memory Reference instruction
Flip-Flop || Digital Electronics
Computer data type and Terminologies
State equationlecture
Micro Programmed Control Unit
Number system in Digital Electronics
Logic design and switching theory
Ad

Similar to C++ advanced PPT.pdf (20)

PPTX
Paksitan Zindabad in ITDevelopment of IT
PPTX
Lec01-02 (Topic 1 C++ Fundamentals).pptx
PPT
Savitch ch 01
PPT
Savitch ch 01
PPTX
lecture Slides - Week 1.programming fundamentals
PPT
Savitch Ch 01
PPTX
Whole c++ lectures ITM1 Th
PPT
Lecture01
PDF
Embedded systems designUNIT 4 PART 2.pdf
PPT
C PLUS PLUS FOR BS ELECTRICAL 2ND SEMSTERLecture01.ppt
PDF
chapter1-161229182113 (1).pdf
PDF
Prog1-L1.pdf
PPTX
Computer and programing basics.pptx
PPTX
l1-introduction_to_computers_and_c_programming.pptx
PDF
PPS Unit-1.pdf
PPTX
Lecture 1
PDF
C with lab
PPTX
Programming Fundamentals IDE's Lec3.pptx
PPTX
lec 1.pptx
PPT
Book ppt
Paksitan Zindabad in ITDevelopment of IT
Lec01-02 (Topic 1 C++ Fundamentals).pptx
Savitch ch 01
Savitch ch 01
lecture Slides - Week 1.programming fundamentals
Savitch Ch 01
Whole c++ lectures ITM1 Th
Lecture01
Embedded systems designUNIT 4 PART 2.pdf
C PLUS PLUS FOR BS ELECTRICAL 2ND SEMSTERLecture01.ppt
chapter1-161229182113 (1).pdf
Prog1-L1.pdf
Computer and programing basics.pptx
l1-introduction_to_computers_and_c_programming.pptx
PPS Unit-1.pdf
Lecture 1
C with lab
Programming Fundamentals IDE's Lec3.pptx
lec 1.pptx
Book ppt
Ad

Recently uploaded (20)

PPTX
CHAPTER IV. MAN AND BIOSPHERE AND ITS TOTALITY.pptx
PPTX
Tissue processing ( HISTOPATHOLOGICAL TECHNIQUE
PDF
A systematic review of self-coping strategies used by university students to ...
DOC
Soft-furnishing-By-Architect-A.F.M.Mohiuddin-Akhand.doc
PDF
Classroom Observation Tools for Teachers
PDF
medical_surgical_nursing_10th_edition_ignatavicius_TEST_BANK_pdf.pdf
PPTX
Onco Emergencies - Spinal cord compression Superior vena cava syndrome Febr...
PPTX
Chinmaya Tiranga Azadi Quiz (Class 7-8 )
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
SOIL: Factor, Horizon, Process, Classification, Degradation, Conservation
PDF
advance database management system book.pdf
PDF
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PPTX
Introduction to Building Materials
PPTX
A powerpoint presentation on the Revised K-10 Science Shaping Paper
PDF
Paper A Mock Exam 9_ Attempt review.pdf.
PDF
Complications of Minimal Access Surgery at WLH
PPTX
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx
PDF
Computing-Curriculum for Schools in Ghana
PDF
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE
CHAPTER IV. MAN AND BIOSPHERE AND ITS TOTALITY.pptx
Tissue processing ( HISTOPATHOLOGICAL TECHNIQUE
A systematic review of self-coping strategies used by university students to ...
Soft-furnishing-By-Architect-A.F.M.Mohiuddin-Akhand.doc
Classroom Observation Tools for Teachers
medical_surgical_nursing_10th_edition_ignatavicius_TEST_BANK_pdf.pdf
Onco Emergencies - Spinal cord compression Superior vena cava syndrome Febr...
Chinmaya Tiranga Azadi Quiz (Class 7-8 )
Final Presentation General Medicine 03-08-2024.pptx
SOIL: Factor, Horizon, Process, Classification, Degradation, Conservation
advance database management system book.pdf
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
Introduction to Building Materials
A powerpoint presentation on the Revised K-10 Science Shaping Paper
Paper A Mock Exam 9_ Attempt review.pdf.
Complications of Minimal Access Surgery at WLH
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx
Computing-Curriculum for Schools in Ghana
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE

C++ advanced PPT.pdf

  • 1. PROGRAMACIÓN EN C++ Transparencias del libro Starting out with C++ : early objects, Tony Gaddis, Judy Walters, Godfrey Muganda
  • 2. Chapter 1: Introduction to Computers and Programming
  • 3. Topics 1.1 Why Program? 1.2 Computer Systems: Hardware and Software 1.3 Programs and Programming Languages 1.4 What Is a Program Made of? 1.5 Input, Processing, and Output 1.6 The Programming Process 1-3
  • 4. 1.1 Why Program? Computer – programmable machine designed to follow instructions Program/Software – instructions in computer memory to make it do something Programmer – person who writes instructions (programs) to make computer perform a task SO, without programmers, no programs; without programs, the computer cannot do anything 1-4
  • 5. 1.2 Computer Systems: Hardware and Software Hardware – Physical components of a computer Main Hardware Component Categories 1. Central Processing Unit (CPU) 2. Main memory (RAM) 3. Secondary storage devices 4. Input Devices 5. Output Devices 1-5
  • 6. Main Hardware Component Categories 1-6
  • 7. Central Processing Unit (CPU) CPU – Hardware component that runs programs Includes • Control Unit – Retrieves and decodes program instructions – Coordinates computer operations • Arithmetic & Logic Unit (ALU) – Performs mathematical operations 1-7
  • 8. The CPU's Role in Running a Program Cycle through: • Fetch: get the next program instruction from main memory • Decode: interpret the instruction and generate a signal • Execute: route the signal to the appropriate component to perform an operation 1-8
  • 9. Main Memory • Holds both program instructions and data • Volatile – erased when program terminates or computer is turned off • Also called Random Access Memory (RAM) 1-9
  • 10. Main Memory Organization • Bit – Smallest piece of memory – Stands for binary digit – Has values 0 (off) or 1 (on) • Byte – Is 8 consecutive bits – Has an address • Word – Usually 4 consecutive bytes 1-10 0 1 1 0 0 1 1 1 8 bits 1 byte
  • 11. Secondary Storage • Non-volatile - data retained when program is not running or computer is turned off • Comes in a variety of media – magnetic: floppy or hard disk drive, internal or external – optical: CD or DVD drive – flash: USB flash drive 1-11
  • 12. Input Devices • Used to send information to the computer from outside • Many devices can provide input – keyboard, mouse, microphone, scanner, digital camera, disk drive, CD/DVD drive, USB flash drive 1-12
  • 13. Output Devices • Used to send information from the computer to the outside • Many devices can be used for output – Computer screen, printer, speakers, disk drive, CD/DVD recorder, USB flash drive 1-13
  • 14. Software Programs That Run on a Computer • System software – programs that manage the computer hardware and the programs that run on the computer – Operating Systems • Controls operation of computer • Manages connected devices • Runs programs – Utility Programs • Support programs that enhance computer operations • Examples: anti-virus software, data backup, data compression – Software development tools • Used by programmers to create software • Examples: compilers, integrated development environments (IDEs) 1-14
  • 15. 1.3 Programs and Programming Languages • Program a set of instructions directing a computer to perform a task • Programming Language a language used to write programs 1-15
  • 16. Algorithm Algorithm: a set of steps to perform a task or to solve a problem Order is important. Steps must be performed sequentially 1-16
  • 17. Programs and Programming Languages Types of languages – Low-level: used for communication with computer hardware directly. – High-level: closer to human language 1-17
  • 18. From a High-level Program to an Executable File a) Create file containing the program with a text editor. b) Run preprocessor to convert source file directives to source code program statements. c) Run compiler to convert source program statements into machine instructions. 1-18
  • 19. From a High-level Program to an Executable File d) Run linker to connect hardware-specific library code to machine instructions, producing an executable file. Steps b) through d) are often performed by a single command or button click. Errors occuring at any step will prevent execution of the following steps. 1-19
  • 20. From a High-level Program to an Executable File 1-20
  • 21. 1.4 What Is a Program Made Of? Common elements in programming languages: – Key Words – Programmer-Defined Identifiers – Operators – Punctuation – Syntax 1-21
  • 22. Example Program #include <iostream> using namespace std; int main() { double num1 = 5, num2, sum; num2 = 12; sum = num1 + num2; cout << "The sum is " << sum; return 0; } 1-22
  • 23. Key Words • Also known as reserved words • Have a special meaning in C++ • Can not be used for another purpose • Written using lowercase letters • Examples in program (shown in green): using namespace std; int main() 1-23
  • 24. Programmer-Defined Identifiers • Names made up by the programmer • Not part of the C++ language • Used to represent various things, such as variables (memory locations) • Example in program (shown in green): double num1 1-24
  • 25. Operators • Used to perform operations on data • Many types of operators – Arithmetic: +, -, *, / – Assignment: = • Examples in program (shown in green): num2 = 12; sum = num1 + num2; 1-25
  • 26. Punctuation • Characters that mark the end of a statement, or that separate items in a list • Example in program (shown in green): double num1 = 5, num2, sum; num2 = 12; 1-26
  • 27. Lines vs. Statements In a source file, A line is all of the characters entered before a carriage return. Blank lines improve the readability of a program. Here are four sample lines. Line 3 is blank: 1. double num1 = 5, num2, sum; 2. num2 = 12; 3. 4. sum = num1 + num2; 1-27
  • 28. Lines vs. Statements In a source file, A statement is an instruction to the computer to perform an action. A statement may contain keywords, operators, programmer-defined identifiers, and punctuation. A statement may fit on one line, or it may occupy multiple lines. Here is a single statement that uses two lines: double num1 = 5, num2, sum; 1-28
  • 29. Variables • A variable is a named location in computer memory (in RAM) • It holds a piece of data. The data that it holds may change while the program is running. • The name of the variable should reflect its purpose • It must be defined before it can be used. Variable definitions indicate the variable name and the type of data that it can hold. • Example variable definition: double num1; 1-29
  • 30. 1.5 Input, Processing, and Output Three steps that many programs perform 1) Gather input data - from keyboard - from files on disk drives 2) Process the input data 3) Display the results as output - send it to the screen or a printer - write it to a file 1-30
  • 31. 1.6 The Programming Process 1. Define what the program is to do. 2. Visualize the program running on the computer. 3. Use design tools to create a model of the program. Hierarchy charts, flowcharts, pseudocode, etc. 4. Check the model for logical errors. 5. Write the program source code. 6. Compile the source code. 1-31
  • 32. The Programming Process (cont.) 7. Correct any errors found during compilation. 8. Link the program to create an executable file. 9. Run the program using test data for input. 10. Correct any errors found while running the program. Repeat steps 4 - 10 as many times as necessary. 11. Validate the results of the program. Does the program do what was defined in step 1? 1-32
  • 34. Topics 2.1 The Parts of a C++ Program 2.2 The cout Object 2.3 The #include Directive 2.4 Standard and Prestandard C++ 2.5 Variables, Literals, and the Assignment Statement 2.6 Identifiers 2.7 Integer Data Types 2.8 Floating-Point Data Types 2-34
  • 35. Topics (continued) 2.9 The char Data Type 2.10 The C++ string Class 2.11 The bool Data Type 2.12 Determining the Size of a Data Type 2.13 More on Variable Assignments and Initialization 2.14 Scope 2.15 Arithmetic Operators 2.16 Comments 2-35
  • 36. 2.1 The Parts of a C++ Program // sample C++ program #include <iostream> using namespace std; int main() { cout << "Hello, there!"; return 0; } 2-36 comment preprocessor directive which namespace to use beginning of function named main beginning of block for main output statement send 0 back to operating system end of block for main
  • 37. 2.1 The Parts of a C++ Program 2-37 Statement Purpose // sample C++ program comment #include <iostream> preprocessor directive using namespace std; which namespace to use int main() beginning of function named main { beginning of block for main cout << "Hello, there!"; output statement return 0; send 0 back to the operating system } end of block for main
  • 38. Special Characters 2-38 Character Name Description // Double Slash Begins a comment # Pound Sign Begins preprocessor directive < > Open, Close Brackets Encloses filename used in #include directive ( ) Open, Close Parentheses Used when naming function { } Open, Close Braces Encloses a group of statements " " Open, Close Quote Marks Encloses string of characters ; Semicolon Ends a programming statement
  • 39. Important Details • C++ is case-sensitive. Uppercase and lowercase characters are different characters. ‘Main’ is not the same as ‘main’. • Every { must have a corresponding }, and vice-versa. 2-39
  • 40. 2.2 The cout Object • Displays information on computer screen • Use << to send information to cout cout << "Hello, there!"; • Can use << to send multiple items to cout cout << "Hello, " << "there!"; Or cout << "Hello, "; cout << "there!"; 2-40
  • 41. Starting a New Line • To get multiple lines of output on screen - Use endl cout << "Hello, there!" << endl; - Use n in an output string cout << "Hello, there!n"; 2-41
  • 42. Escape Sequences – More Control Over Output 2-42
  • 43. 2.3 The #include Directive • Inserts the contents of another file into the program • Is a preprocessor directive – Not part of the C++ language – Not seen by compiler • Example: #include <iostream> 2-43 No ; goes here
  • 44. 2.4 Standard and Prestandard C++ Prestandard (Older-style) C++ programs • Use .h at end of header files #include <iostream.h> • Do not use using namespace convention • May not use return 0; at the end of function main • May not compile with a standard C++ compiler 2-44
  • 45. 2.5 Variables, Literals, and the Assignment Statement • Variable – Has a name and a type of data it can hold char letter; – Is used to reference a location in memory where a value can be stored – Must be defined before it can be used – The value that is stored can be changed, i.e., it can “vary” 2-45 variable name data type
  • 46. Variables – If a new value is stored in the variable, it replaces the previous value – The previous value is overwritten and can no longer be retrieved int age; age = 17; // age is 17 cout << age; // Displays 17 age = 18; // Now age is 18 cout << age; // Displays 18 2-46
  • 47. Assignment Statement • Uses the = operator • Has a single variable on the left side and a value on the right side • Copies the value on the right into the variable on the left item = 12; 2-47
  • 48. Constants Literal – Data item whose value does not change during program execution – Is also called a constant 'A' // character constant "Hello" // string literal 12 // integer constant 3.14 // floating-point constant 2-48
  • 49. 2.6 Identifiers • Programmer-chosen names to represent parts of the program, such as variables • Name should indicate the use of the identifier • Cannot use C++ key words as identifiers • Must begin with alphabetic character or _, followed by alphabetic, numeric, or _ . Alphabetic characters may be upper- or lowercase 2-49
  • 50. Multi-word Variable Names • Descriptive variable names may include multiple words • Two conventions to use in naming variables: – Capitalize all but first letter of first word. Run words together: quantityOnOrder totalSales – Use the underscore _ character as a space: quantity_on_order total_sales • Use one convention consistently throughout program 2-50
  • 51. Valid and Invalid Identifiers 2-51 IDENTIFIER VALID? REASON IF INVALID totalSales Yes total_Sales Yes total.Sales No Cannot contain period 4thQtrSales No Cannot begin with digit totalSale$ No Cannot contain $
  • 52. 2.7 Integer Data Types • Designed to hold whole (non-decimal) numbers • Can be signed or unsigned 12 -6 +3 • Available in different sizes (i.e., number of bytes): short, int, and long • Size of short ≤ size of int ≤ size of long 2-52
  • 53. Signed vs. Unsigned Integers • C++ allocates one bit for the sign of the number. The rest of the bits are for data. • If your program will never need negative numbers, you can declare variables to be unsigned. All bits in unsigned numbers are used for data. • A variable is signed unless the unsigned keyword is used. 2-53
  • 54. Defining Variables • Variables of the same type can be defined - In separate statements int length; int width; - In the same statement int length, width; • Variables of different types must be defined in separate statements 2-54
  • 55. Integral Constants • To store an integer constant in a long memory location, put ‘L’ at the end of the number: 1234L • Constants that begin with ‘0’ (zero) are octal, or base 8: 075 • Constants that begin with ‘0x’ are hexadecimal, or base 16: 0x75A 2-55
  • 56. 2.8 Floating-Point Data Types • Designed to hold real numbers 12.45 -3.8 • Stored in a form similar to scientific notation • Numbers are all signed • Available in different sizes (number of bytes): float, double, and long double • Size of float ≤ size of double ≤ size of long double 2-56
  • 57. Floating-point Constants • Can be represented in - Fixed point (decimal) notation: 31.4159 0.0000625 - E notation: 3.14159E1 6.25e-5 • Are double by default • Can be forced to be float 3.14159F or long double 0.0000625L 2-57
  • 58. Assigning Floating-point Values to Integer Variables If a floating-point value is assigned to an integer variable – The fractional part will be truncated (i.e., “chopped off” and discarded) – The value is not rounded int rainfall = 3.88; cout << rainfall; // Displays 3 2-58
  • 59. 2.9 The char Data Type • Used to hold single characters or very small integer values • Usually occupies 1 byte of memory • A numeric code representing the character is stored in memory 2-59 SOURCE CODE MEMORY char letter = 'C'; letter 67
  • 60. Character Literal • A character literal is a single character • When referenced in a program, it is enclosed in single quotation marks: cout << 'Y' << endl; • The quotation marks are not part of the literal, and are not displayed 2-60
  • 61. String Literals • Can be stored as a series of characters in consecutive memory locations "Hello" • Stored with the null terminator, 0, automatically placed at the end • Is comprised of characters between the " " 2-61 H e l l o 0
  • 62. A character or a string literal? • A character literal is a single character, enclosed in single quotes: 'C' • A string literal is a sequence of characters enclosed in double quotes: "Hello, there!" • A single character in double quotes is a string literal, not a character literal: "C" 2-62
  • 63. 2.10 The C++ string Class • Must #include <string> to create and use string objects • Can define string variables in programs string name; • Can assign values to string variables with the assignment operator name = "George"; • Can display them with cout cout << "My name is " << name; 2-63
  • 64. 2.11 The bool Data Type • Represents values that are true or false • bool values are stored as integers • false is represented by 0, true by 1 bool allDone = true; bool finished = false; 2-64 allDone finished 1 0
  • 65. 2.12 Determining the Size of a Data Type The sizeof operator gives the size in number of bytes of any data type or variable double amount; cout << "A float is stored in " << sizeof(float) << " bytesn"; cout << "Variable amount is stored in " << sizeof(amount) << " bytesn"; 2-65
  • 66. 2.13 More on Variable Assignments and Initialization Assigning a value to a variable – Assigns a value to a previously created variable – A single variable name must appear on left side of the = symbol int size; size = 5; // legal 5 = size; // not legal 2-66
  • 67. Variable Assignment vs. Initialization Initializing a variable – Gives an initial value to a variable at the time it is created – Can initialize some or all of the variables being defined int length = 12; int width = 7, height = 5, area; 2-67
  • 68. 2.14 Scope • The scope of a variable is that part of the program where the variable may be used • A variable cannot be used before it is defined int num1 = 5; cout >> num1; // legal cout >> num2; // illegal int num2 = 12; 2-68
  • 69. 2.15 Arithmetic Operators • Used for performing numeric calculations • C++ has unary, binary, and ternary operators – unary (1 operand) -5 – binary (2 operands) 13 - 7 – ternary (3 operands) exp1 ? exp2 : exp3 2-69
  • 70. Binary Arithmetic Operators 2-70 SYMBOL OPERATION EXAMPLE ans + addition ans = 7 + 3; 10 - subtraction ans = 7 - 3; 4 * multiplication ans = 7 * 3; 21 / division ans = 7 / 3; 2 % modulus ans = 7 % 3; 1
  • 71. / Operator • C++ division operator (/)performs integer division if both operands are integers cout << 13 / 5; // displays 2 cout << 2 / 4; // displays 0 • If either operand is floating-point, the result is floating-point cout << 13 / 5.0; // displays 2.6 cout << 2.0 / 4; // displays 0.5 2-71
  • 72. % Operator • C++ modulus operator (%) computes the remainder resulting from integer division cout << 9 % 2; // displays 1 • % requires integers for both operands cout << 9 % 2.0; // error 2-72
  • 73. 2.16 Comments • Are used to document parts of a program • Are written for persons reading the source code of the program – Indicate the purpose of the program – Describe the use of variables – Explain complex sections of code • Are ignored by the compiler 2-73
  • 74. Single-Line Comments • Begin with // and continue to the end of line int length = 12; // length in inches int width = 15; // width in inches int area; // calculated area // Calculate rectangle area area = length * width; 2-74
  • 75. Multi-Line Comments • Begin with /* and end with */ • Can span multiple lines /*---------------------------- Here's a multi-line comment ----------------------------*/ • Can also be used as single-line comments int area; /* Calculated area */ 2-75
  • 76. Chapter 3: Expressions and Interactivity
  • 77. Topics 3.1 The cin Object 3.2 Mathematical Expressions 3.3 Data Type Conversion and Type Casting 3.4 Overflow and Underflow 3.5 Named Constants 3-77
  • 78. Topics (continued) 3.6 Multiple and Combined Assignment 3.7 Formatting Output 3.8 Working with Characters and Strings 3.9 Using C-Strings 3.10 More Mathematical Library Functions 3-78
  • 79. 3.1 The cin Object • Standard input object • Like cout, requires iostream file • Used to read input from keyboard • Often used with cout to display a user prompt first • Data is retrieved from cin with >> • Input data is stored in one or more variables 3-79
  • 80. The cin Object • User input goes from keyboard to the input buffer, where it is stored as characters • cin converts the data to the type that matches the variable int height; cout << "How tall is the room? "; cin >> height; 3-80
  • 81. The cin Object • Can be used to input multiple values cin >> height >> width; • Multiple values from keyboard must be separated by spaces or [Enter] • Must press [Enter] after typing last value • Multiple values need not all be of the same type • Order is important; first value entered is stored in first variable, etc. 3-81
  • 82. 3.2 Mathematical Expressions • An expression can be a constant, a variable, or a combination of constants and variables combined with operators • Can create complex expressions using multiple mathematical operators • Examples of mathematical expressions: 2 height a + b / c 3-82
  • 83. Using Mathematical Expressions • Can be used in assignment statements, with cout, and in other types of statements • Examples: area = 2 * PI * radius; cout << "border is: " << (2*(l+w)); 3-83 This is an expression These are expressions
  • 84. Order of Operations • In an expression with > 1 operator, evaluate in this order ( ) expressions in parentheses - (unary negation) in order, left to right * / % in order, left to right + - in order, left to right • In the expression 2 + 2 * 2 – 2 , 3-84 Do first: Do next: Do next: Evaluate 1st Evaluate 2nd Evaluate 3rd Do last:
  • 85. Associativity of Operators • - (unary negation) associates right to left • * / % + - all associate left to right • parentheses ( ) can be used to override the order of operations 2 + 2 * 2 – 2 = 4 (2 + 2) * 2 – 2 = 6 2 + 2 * (2 – 2) = 2 (2 + 2) * (2 – 2) = 0 3-85
  • 86. Algebraic Expressions • Multiplication requires an operator Area = lw is written as Area = l * w; • There is no exponentiation operator Area = s2 is written as Area = pow(s, 2); (note: pow requires the cmath header file) • Parentheses may be needed to maintain order of operations is written as m = (y2-y1)/(x2-x1); 3-86 1 2 1 2 x x y y m − − =
  • 87. 3.3 Data Type Conversion and Type Casting • Operations are performed between operands of the same type • If operands do not have the same type, C++ will automatically convert one to be the type of the other • This can impact the results of calculations 3-87
  • 88. Hierarchy of Data Types • Highest • Lowest • Ranked by largest number they can hold 3-88 long double double float unsigned long long unsigned int int
  • 89. Type Coercion • Coercion: automatic conversion of an operand to another data type • Promotion: converts to a higher type • Demotion: converts to a lower type 3-89
  • 90. Coercion Rules 1) char, short, unsigned short are automatically promoted to int 2) When operating on values of different data types, the lower-ranked one is promoted to the type of the higher one. 3) When using the = operator, the type of expression on right will be converted to the type of variable on left 3-90
  • 91. Coercion Rules – Important Notes 1) If demotion is required to use the = operator, - the stored result may be incorrect if there is not enough space available in the receiving variable - floating-point values are truncated when assigned to integer variables 2) Coercion affects the value used in a calculation. It does not change the type associated with a variable. 3-91
  • 92. Type Casting • Used for manual data type conversion • Format static_cast<Data Type>(Value) • Example: cout << static_cast<int>(4.2); // Displays 4 3-92
  • 93. More Type Casting Examples char ch = 'C'; cout << ch << " is stored as " << static_cast<int>(ch); gallons = static_cast<int>(area/500); avg = static_cast<double>(sum)/count; 3-93
  • 94. Older Type Cast Styles double Volume = 21.58; int intVol1, intVol2; intVol1 = (int) Volume; // C-style // cast intVol2 = int (Volume); //Prestandard // C++ style // cast C-style cast uses prefix notation Prestandard C++ cast uses functional notation static_cast is the current standard 3-94
  • 95. 3.4 Overflow and Underflow • Occurs when assigning a value that is too large (overflow) or too small (underflow) to be held in a variable • The variable contains a value that is ‘wrapped around’ the set of possible values 3-95
  • 96. Overflow Example // Create a short int initialized to // the largest value it can hold short int num = 32767; cout << num; // Displays 32767 num = num + 1; cout << num; // Displays -32768 3-96
  • 97. Handling Overflow and Underflow Different systems handle the problem differently. They may – display a warning / error message, or display a dialog box and ask what to do – stop the program – continue execution with the incorrect value 3-97
  • 98. 3.5 Named Constants • Also called constant variables • Variables whose content cannot be changed during program execution • Used for representing constant values with descriptive names const double TAX_RATE = 0.0675; const int NUM_STATES = 50; • Often named in uppercase letters 3-98
  • 99. Benefits of Named Constants • Makes program code more readable by documenting the purpose of the constant in the name: const double TAX_RATE = 0.0675; … salesTax = purchasePrice * TAX_RATE; • Simplifies program maintenance: const double TAX_RATE = 0.0725; 3-99
  • 100. const vs. #define #define – C-style of naming constants #define NUM_STATES 50 – Interpreted by pre-processor rather than compiler – Does not occupy a memory location like a constant variable defined with const – Instead, causes a text substitution to occur. In above example, every occurrence in program of NUM_STATES will be replaced by 50 3-100 no ; goes here
  • 101. 3.6 Multiple and Combined Assignment • The assignment operator (=) can be used multiple times in an expression x = y = z = 5; • Associates right to left x = (y = (z = 5)); 3-101 Done Done Done 3rd 2nd 1st
  • 102. Combined Assignment • Applies an arithmetic operation to a variable and assigns the result as the new value of that variable • Operators: += -= *= /= %= • Also called compound operators or arithmetic assignment operators • Example: sum += amt; is short for sum = sum + amt; 3-102
  • 103. More Examples x += 5; means x = x + 5; x -= 5; means x = x – 5; x *= 5; means x = x * 5; x /= 5; means x = x / 5; x %= 5; means x = x % 5; The right hand side is evaluated before the combined assignment operation is done. x *= a + b; means x = x * (a + b); 3-103
  • 104. 3.7 Formatting Output • Can control how output displays for numeric and string data – size – position – number of digits • Requires iomanip header file 3-104
  • 105. Stream Manipulators • Used to control features of an output field • Some affect just the next value displayed –setw(x): Print in a field at least x spaces wide. It will use more spaces if specified field width is not big enough. 3-105
  • 106. Stream Manipulators • Some affect values until changed again – fixed: Use decimal notation (not E-notation) for floating-point values. – setprecision(x): • When used with fixed, print floating-point value using x digits after the decimal. • Without fixed, print floating-point value using x significant digits. – showpoint: Always print decimal for floating-point values. – left, right: left-, right justification of value 3-106
  • 107. Manipulator Examples const float e = 2.718; float price = 18.0; Displays cout << setw(8) << e << endl; ^^^2.718 cout << left << setw(8) << e << endl; 2.718^^^ cout << setprecision(2); cout << e << endl; 2.7 cout << fixed << e << endl; 2.72 cout << setw(6) << price; ^18.00 3-107
  • 108. 3.8 Working with Characters and Strings • char: holds a single character • string: holds a sequence of characters • Both can be used in assignment statements • Both can be displayed with cout and << 3-108
  • 109. String Input Reading in a string object string str; cin >> str; // Reads in a string // with no blanks getline(cin, str); // Reads in a string // that may contain // blanks 3-109
  • 110. Character Input Reading in a character: char ch; cin >> ch; // Reads in any non-blank char cin.get(ch); // Reads in any char ch = cin.get;// Reads in any char cin.ignore();// Skips over next char in // the input buffer 3-110
  • 111. String Operators = Assigns a value to a string string words; words = "Tasty "; + Joins two strings together string s1 = "hot", s2 = "dog"; string food = s1 + s2; // food = "hotdog" += Concatenates a string onto the end of another one words += food; // words now = "Tasty hotdog" 3-111
  • 112. string Member Functions • length() – the number of characters in a string string firstPrez="George Washington"; int size=firstPrez.length(); // size is 17 • assign() – put repeated characters in a string. Can be used for formatting output. string equals; equals.assign(80,'='); … cout << equals << endl; cout << "Total: " << total << endl; 3-112
  • 113. 3.9 Using C-Strings • C-string is stored as an array of characters • Programmer must indicate maximum number of characters at definition const int SIZE = 5; char temp[SIZE] = "Hot"; • NULL character (0) is placed after final character to mark the end of the string • Programmer must make sure array is big enough for desired use; temp can hold up to 4 characters plus the 0. 3-113 H o t 0
  • 114. C-String Input • Reading in a C-string const int SIZE = 10; char Cstr[SIZE]; cin >> Cstr; // Reads in a C-string with no // blanks. Will write past the // end of the array if input string // is too long. cin.getline(Cstr, 10); // Reads in a C-string that may // contain blanks. Ensures that <= 9 // chars are read in. • Can also use setw() and width() to control input field widths 3-114
  • 115. C-String Initialization vs. Assignment • A C-string can be initialized at the time of its creation, just like a string object const int SIZE = 10; char month[SIZE] = "April"; • However, a C-string cannot later be assigned a value using the = operator; you must use the strcpy() function char month[SIZE]; month = "August" // wrong! strcpy(month, "August"); //correct 3-115
  • 116. C-String and Keyboard Input • Must use cin.getline()to put keyboard input into a C-string • Note that cin.getline() ≠ getline() • Must indicate the target C-string and maximum number of characters to read: const int SIZE = 25; char name[SIZE]; cout << "What's your name? "; cin.getline(name, SIZE); 3-116
  • 117. 3.10 More Mathematical Library Functions • These require cmath header file • Take double arguments and return a double • Commonly used functions 3-117 abs Absolute value sin Sine cos Cosine tan Tangent sqrt Square root log Natural (e) log pow Raise to a power
  • 118. More Mathematical Library Functions These require cstdlib header file • rand – Returns a random number between 0 and the largest int the computer holds – Will yield the same sequence of numbers each time the program is run • srand(x) – Initializes random number generator with unsigned int x. x is the “seed value”. – Should be called at most once in a program 3-118
  • 119. More on Random Numbers • Use time() to generate different seed values each time that a program runs: #include <ctime> //needed for time() … unsigned seed = time(0); srand(seed); • Random numbers can be scaled to a range: int max=6; int num; num = rand() % max + 1; 3-119
  • 120. Chapter 4: Making Decisions
  • 121. Topics 4.1 Relational Operators 4.2 The if Statement 4.3 The if/else Statement 4.4 The if/else if Statement 4.5 Menu-Driven Programs 4.6 Nested if Statements 4.7 Logical Operators 4-121
  • 122. Topics (continued) 4.8 Validating User Input 4.9 More About Block and Scope 4.10 More About Characters and Strings 4.11 The Conditional Operator 4.12 The switch Statement 4.13 Enumerated Data Types 4-122
  • 123. 4.1 Relational Operators • Used to compare numeric values to determine relative order • Operators: 4-123 > Greater than < Less than >= Greater than or equal to <= Less than or equal to == Equal to != Not equal to
  • 124. Relational Expressions • Relational expressions are Boolean (i.e., evaluate to true or false) • Examples: 12 > 5 is true 7 <= 5 is false if x is 10, then x == 10 is true, x <= 8 is false, x != 8 is true, and x == 8 is false 4-124
  • 125. Relational Expressions • Can be assigned to a variable bool result = (x <= y); • Assigns 0 for false, 1 for true • Do not confuse = (assignment) and == (equal to) 4-125
  • 126. 4.2 The if Statement • Supports the use of a decision structure • Allows statements to be conditionally executed or skipped over • Models the way we mentally evaluate situations “If it is cold outside, wear a coat and wear a hat.” 4-126
  • 127. Format of the if Statement if (condition) { statement1; statement2; … statementn; } The block inside the braces is called the body of the if statement. If there is only 1 statement in the body, the { } may be omitted. 4-127 No ; goes here ; goes here
  • 128. How the if Statement Works • If (condition) is true, then the statement(s) in the body are executed. • If (condition) is false, then the statement(s) are skipped. 4-128
  • 129. if Statement Flow of Control 4-129 condition 1 or more statements true false
  • 130. Example if Statements if (score >= 60) cout << "You passed." << endl; if (score >= 90) { grade = 'A'; cout << "Wonderful job!" << endl; } 4-130
  • 131. if Statement Notes • if is a keyword. It must be lowercase • (condition)must be in ( ) • Do not place ; after (condition) • Don't forget the { } around a multi-statement body 4-131
  • 132. if Statement Style Recommendations • Place each statement; on a separate line after (condition) • Indent each statement in the body • When using { and } around the body, put { and } on lines by themselves 4-132
  • 133. What is true and false? • An expression whose value is 0 is considered false. • An expression whose value is non-zero is considered true. • An expression need not be a comparison – it can be a single variable or a mathematical expression. 4-133
  • 134. Flag • A variable that signals a condition • Usually implemented as a bool • Meaning: – true: the condition exists – false: the condition does not exist • The flag value can be both set and tested with if statements 4-134
  • 135. Flag Example Example: bool validMonths = true; … if (months < 0) validMonths = false; … if (validMonths) moPayment = total / months; 4-135
  • 136. Integer Flags • Integer variables can be used as flags • Remember that 0 means false, any other value means true int allDone = 0; // set to false … if (count > MAX_STUDENTS) allDone = 1; // set to true … if (allDone) cout << "Task finished"; 4-136
  • 137. 4.3 The if/else Statement • Allows a choice between statements depending on whether (condition) is true or false • Format: if (condition) { statement set 1; } else { statement set 2; } 4-137
  • 138. How the if/else Works • If (condition) is true, statement set 1 is executed and statement set 2 is skipped. • If (condition) is false, statement set 1 is skipped and statement set 2 is executed. 4-138
  • 139. if/else Flow of Control 4-139 condition statement set 1 true false statement set 2
  • 140. Example if/else Statements if (score >= 60) cout << "You passed.n"; else cout << "You did not pass.n"; if (intRate > 0) { interest = loanAmt * intRate; cout << interest; } else cout << "You owe no interest.n"; 4-140
  • 141. Comparisons with floating-point numbers • It is difficult to test for equality when working with floating point numbers. • It is better to use – greater than, less than tests, or – test to see if value is very close to a given value 4-141
  • 142. 4.4 The if/else if Statement • Chain of if statements that test in order until one is found to be true • Also models thought processes “If it is raining, take an umbrella, else, if it is windy, take a hat, else, if it is sunny, take sunglasses.” 4-142
  • 143. if/else if Format if (condition 1) { statement set 1; } else if (condition 2) { statement set 2; } … else if (condition n) { statement set n; } 4-143
  • 144. Using a Trailing else • Used with if/else if statement when all of the conditions are false • Provides a default statement or action that is performed when none of the conditions is true • Can be used to catch invalid values or handle other exceptional situations 4-144
  • 145. Example if/else if with Trailing else if (age >= 21) cout << "Adult"; else if (age >= 13) cout << "Teen"; else if (age >= 2) cout << "Child"; else cout << "Baby"; 4-145
  • 146. 4.5 Menu-Driven Program • Menu: list of choices presented to the user on the computer screen • Menu-driven program: program execution controlled by user selecting from a list of actions • Menu can be implemented using if/else if statements 4-146
  • 147. Menu-driven Program Organization • Display list of numbered or lettered choices for actions. • Input user’s selection of number or letter • Test user selection in (condition) – if a match, then execute code to carry out desired action – if not, then test with next (condition) 4-147
  • 148. 4.6 Nested if Statements • An if statement that is part of the if or else part of another if statement • Can be used to evaluate > 1 data item or condition if (score < 100) { if (score > 90) grade = 'A'; } 4-148
  • 149. Notes on Coding Nested ifs • An else matches the nearest previous if that does not have an else if (score < 100) if (score > 90) grade = 'A'; else ... // goes with second if, // not first one • Proper indentation aids comprehension 4-149
  • 150. 4.7 Logical Operators Used to create relational expressions from other relational expressions 4-150 Operator Meaning Explanation && AND New relational expression is true if both expressions are true || OR New relational expression is true if either expression is true ! NOT Reverses the value of an expression; true expression becomes false, false expression becomes true
  • 151. Logical Operator Examples int x = 12, y = 5, z = -4; • (x > y) && (y > z) true (x > y) && (z > y) false (x <= z) || (y == z) false (x <= z) || (y != z) true !(x >= z) false 4-151
  • 152. Logical Precedence Highest ! && Lowest || Example: (2 < 3) || (5 > 6) && (7 > 8) is true because AND is evaluated before OR 4-152
  • 153. More on Precedence Example: 8 < 2 + 7 || 5 == 6 is true 4-153 logical operators Lowest relational operators arithmetic operators Highest
  • 154. Checking Numeric Ranges with Logical Operators • Used to test if a value is within a range if (grade >= 0 && grade <= 100) cout << "Valid grade"; • Can also test if a value lies outside a range if (grade <= 0 || grade >= 100) cout << "Invalid grade"; • Cannot use mathematical notation if (0 <= grade <= 100) //Doesn’t //work! 4-154
  • 155. 4.8 Validating User Input • Input validation: inspecting input data to determine if it is acceptable • Want to avoid accepting bad input • Can perform various tests – Range – Reasonableness – Valid menu choice – Zero as a divisor 4-155
  • 156. 4.9 More About Blocks and Scope • Scope of a variable is the block in which it is defined, from the point of definition to the end of the block • Variables are usually defined at the beginning of a function • They may instead be defined close to the place where they are first used 4-156
  • 157. More About Blocks and Scope • Variables defined inside { } have local or block scope • When in a block that is nested inside another block, you can define variables with the same name as in the outer block. – When the program is executing in the inner block, the outer definition is not available – This is generally not a good idea 4-157
  • 158. 4.10 More About Characters and Strings • Can use relational operators with characters and string objects if (menuChoice == 'A') if (firstName == "Beth") • Comparing characters is really comparing ASCII values of characters • Comparing string objects is comparing the ASCII values of the characters in the strings. Comparison is character-by-character • Cannot compare C-style strings with relational operators 4-158
  • 159. Testing Characters require cctype header file FUNCTION MEANING isalpha true if arg. is a letter, false otherwise isalnum true if arg. is a letter or digit, false otherwise isdigit true if arg. is a digit 0-9, false otherwise islower true if arg. is lowercase letter, false otherwise 12-159
  • 160. Character Testing require cctype header file FUNCTION MEANING isprint true if arg. is a printable character, false otherwise ispunct true if arg. is a punctuation character, false otherwise isupper true if arg. is an uppercase letter, false otherwise isspace true if arg. is a whitespace character, false otherwise 12-160
  • 161. 4.11 The Conditional Operator • Can use to create short if/else statements • Format: expr ? expr : expr; 4-161
  • 162. 4.12 The switch Statement • Used to select among statements from several alternatives • May sometimes be used instead of if/else if statements 4-162
  • 163. switch Statement Format switch (IntExpression) { case exp1: statement set 1; case exp2: statement set 2; ... case expn: statement set n; default: statement set n+1; } 4-163
  • 164. switch Statement Requirements 1) IntExpression must be a char or an integer variable or an expression that evaluates to an integer value 2) exp1 through expn must be constant integer type expressions and must be unique in the switch statement 3) default is optional but recommended 4-164
  • 165. How the switch Statement Works 1) IntExpression is evaluated 2) The value of intExpression is compared against exp1 through expn. 3) If IntExpression matches value expi, the program branches to the statement(s) following expi and continues to the end of the switch 4) If no matching value is found, the program branches to the statement after default: 4-165
  • 166. The break Statement • Used to stop execution in the current block • Also used to exit a switch statement • Useful to execute a single case statement without executing statements following it 4-166
  • 167. Example switch Statement switch (gender) { case 'f': cout << "female"; break; case 'm': cout << "male"; break; default : cout << "invalid gender"; } 4-167
  • 168. Using switch with a Menu switch statement is a natural choice for menu-driven program – display menu – get user input – use user input as IntExpression in switch statement – use menu choices as exp to test against in the case statements 4-168
  • 169. 4.13 Enumerated Data Types • Data type created by programmer • Contains a set of named constant integers • Format: enum name {val1, val2, … valn}; • Examples: enum Fruit {apple, grape, orange}; enum Days {Mon, Tue, Wed, Thur, Fri}; 4-169
  • 170. Enumerated Data Type Variables • To define variables, use the enumerated data type name Fruit snack; Days workDay, vacationDay; • Variable may contain any valid value for the data type snack = orange; // no quotes if (workDay == Wed) // none here 4-170
  • 171. Enumerated Data Type Values • Enumerated data type values are associated with integers, starting at 0 enum Fruit {apple, grape, orange}; • Can override default association enum Fruit {apple = 2, grape = 4, orange = 5} 4-171 0 1 2
  • 172. Enumerated Data Type Notes • Enumerated data types improve the readability of a program • Enumerated variables can not be used with input statements, such as cin • Will not display the name associated with the value of an enumerated data type if used with cout 4-172
  • 174. Topics 5.1 Introduction to Loops: The while Loop 5.2 Using the while loop for Input Validation 5.3 The Increment and Decrement Operators 5.4 Counters 5.5 The do-while loop 5.6 The for loop 5.7 Keeping a Running Total 5-174
  • 175. Topics (continued) 5.8 Sentinels 5.9 Deciding Which Loop to Use 5.10 Nested Loops 5.11 Breaking Out of a Loop 5.12 Using Files for Data Storage 5.13 Creating Good Test Data 5-175
  • 176. 5.1 Introduction to Loops: The while Loop • Loop: part of program that may execute > 1 time (i.e., it repeats) • while loop format: while (condition) { statement(s); } • The {} can be omitted if there is only one statement in the body of the loop 5-176 No ; here
  • 177. How the while Loop Works while (condition) { statement(s); } condition is evaluated – if it is true, the statement(s) are executed, and then condition is evaluated again – if it is false, the loop is exited An iteration is an execution of the loop body 5-177
  • 178. while Loop Flow of Control 5-178 true statement(s) false condition
  • 179. while Loop Example int val = 5; while (val >= 0) { cout << val << " "; val = val - 1; } • produces output: 5 4 3 2 1 0 5-179
  • 180. while Loop is a Pretest Loop • while is a pretest loop (condition is evaluated before the loop executes) • If the condition is initially false, the statement(s) in the body of the loop are never executed • If the condition is initially true, the statement(s) in the body will continue to be executed until the condition becomes false 5-180
  • 181. Exiting the Loop • The loop must contain code to allow condition to eventually become false so the loop can be exited • Otherwise, you have an infinite loop (i.e., a loop that does not stop) • Example infinite loop: x = 5; while (x > 0) // infinite loop because cout << x; // x is always > 0 5-181
  • 182. Common Loop Errors • Don’t put ; immediately after (condition) • Don’t forget the { } : int numEntries = 1; while (numEntries <=3) cout << "Still working … "; numEntries++; // not in the loop body • Don’t use = when you mean to use == while (numEntries = 3) // always true { cout << "Still working … "; numEntries++; } 5-182
  • 183. while Loop Programming Style • Loop body statements should be indented • Align { and } with the loop header and place them on lines by themselves Note: The conventions above make the program more understandable by someone who is reading it. They have no effect on how the the program compiles or executes. 5-183
  • 184. 5.2 Using the while Loop for Input Validation Loops are an appropriate structure for validating user input data 1. Prompt for and read in the data. 2. Use a while loop to test if data is valid. 3. Enter the loop only if data is not valid. 4. Inside the loop, display error message and prompt the user to re-enter the data. 5. The loop will not be exited until the user enters valid data. 5-184
  • 185. Input Validation Loop Example cout << "Enter a number (1-100) and" << " I will guess it. "; cin >> number; while (number < 1 || number > 100) { cout << "Number must be between 1 and 100." << " Re-enter your number. "; cin >> number; } // Code to use the valid number goes here. 5-185
  • 186. 5.3 The Increment and Decrement Operators • Increment – increase value in variable ++ adds one to a variable val++; is the same as val = val + 1; • Decrement – reduce value in variable -- subtracts one from a variable val--; is the same as val = val – 1; • can be used in prefix mode (before) or postfix mode (after) a variable 5-186
  • 187. Prefix Mode • ++val and --val increment or decrement the variable, then return the new value of the variable. • It is this returned new value of the variable that is used in any other operations within the same statement 5-187
  • 188. Prefix Mode Example int x = 1, y = 1; x = ++y; // y is incremented to 2 // Then 2 is assigned to x cout << x << " " << y; // Displays 2 2 x = --y; // y is decremented to 1 // Then 1 is assigned to x cout << x << " " << y; // Displays 1 1 5-188
  • 189. Postfix Mode • val++ and val-- return the old value of the variable, then increment or decrement the variable • It is this returned old value of the variable that is used in any other operations within the same statement 5-189
  • 190. Postfix Mode Example int x = 1, y = 1; x = y++; // y++ returns a 1 // The 1 is assigned to x // and y is incremented to 2 cout << x << " " << y; // Displays 1 2 x = y--; // y-- returns a 2 // The 2 is assigned to x // and y is decremented to 1 cout << x << " " << y; // Displays 2 1 5-190
  • 191. Increment & Decrement Notes • Can be used in arithmetic expressions result = num1++ + --num2; • Must be applied to something that has a location in memory. Cannot have result = (num1 + num2)++; // Illegal • Can be used in relational expressions if (++num > limit) • Pre- and post-operations will cause different comparisons 5-191
  • 192. 5.4 Counters • Counter: variable that is incremented or decremented each time a loop repeats • Can be used to control execution of the loop (loop control variable) • Must be initialized before entering loop • May be incremented/decremented either inside the loop or in the loop test 5-192
  • 193. Letting the User Control the Loop • Program can be written so that user input determines loop repetition • Can be used when program processes a list of items, and user knows the number of items • User is prompted before loop. Their input is used to control number of repetitions 5-193
  • 194. User Controls the Loop Example int num, limit; cout << "Table of squaresn"; cout << "How high to go? "; cin >> limit; cout << "nnnumber squaren"; num = 1; while (num <= limit) { cout << setw(5) << num << setw(6) << num*num << endl; num++; } 5-194
  • 195. 5.5 The do-while Loop • do-while: a post test loop (condition is evaluated after the loop executes) • Format: do { 1 or more statements; } while (condition); 5-195 Notice the required ;
  • 196. do-while Flow of Control 5-196 statement(s) condition false true
  • 197. do-while Loop Notes • Loop always executes at least once • Execution continues as long as condition is true; the loop is exited when condition becomes false • { } are required, even if the body contains a single statement • ; after (condition) is also required 5-197
  • 198. do-while and Menu-Driven Programs • do-while can be used in a menu-driven program to bring the user back to the menu to make another choice • To simplify the processing of user input, use the toupper (‘to upper’) or tolower (to lower’) function 5-198
  • 199. Menu-Driven Program Example do { // code to display menu // and perform actions cout << "Another choice? (Y/N) "; } while (choice =='Y'||choice =='y'); The condition could be written as (toupper(choice) == 'Y'); or as (tolower(choice) == 'y'); 5-199
  • 200. 5.6 The for Loop • Pretest loop that executes zero or more times • Useful for counter-controlled loop • Format: for( initialization; test; update ) { 1 or more statements; } 5-200 No ; goes here Required ;
  • 202. for Loop Flow of Control 5-202 true statement(s) false test initialization code update code
  • 203. for Loop Example int sum = 0, num; for (num = 1; num <= 10; num++) sum += num; cout << "Sum of numbers 1 – 10 is " << sum << endl; 5-203
  • 204. for Loop Notes • If test is false the first time it is evaluated, the body of the loop will not be executed • The update expression can increment or decrement by any amount • Variables used in the initialization section should not be modified in the body of the loop 5-204
  • 205. for Loop Modifications • Can define variables in initialization code – Their scope is the for loop • Initialization and update code can contain more than one statement – Separate the statements with commas • Example: for (int sum = 0, num = 1; num <= 10; num++) sum += num; 5-205
  • 206. More for Loop Modifications (These are NOT Recommended) • Can omit initialization if already done int sum = 0, num = 1; for (; num <= 10; num++) sum += num; • Can omit update if done in loop for (sum = 0, num = 1; num <= 10;) sum += num++; • Can omit test – may cause an infinite loop for (sum = 0, num = 1; ; num++) sum += num; • Can omit loop body if all work is done in header 5-206
  • 207. 5.7 Keeping a Running Total • running total: accumulated sum of numbers from each repetition of loop • accumulator: variable that holds running total int sum = 0, num = 1; // sum is the while (num <= 10) // accumulator { sum += num; num++; } cout << "Sum of numbers 1 – 10 is " << sum << endl; 5-207
  • 208. 5.8 Sentinels • sentinel: value in a list of values that indicates end of the list • Special value that cannot be confused with a valid value, e.g., -999 for a test score • Used to terminate input when user may not know how many values will be entered 5-208
  • 209. Sentinel Example int total = 0; cout << "Enter points earned " << "(or -1 to quit): "; cin >> points; while (points != -1) // -1 is the sentinel { total += points; cout << "Enter points earned: "; cin >> points; } 5-209
  • 210. 5.9 Deciding Which Loop to Use • while: pretest loop (loop body may not be executed at all) • do-while: post test loop (loop body will always be executed at least once) • for: pretest loop (loop body may not be executed at all); has initialization and update code; is useful with counters or if precise number of repetitions is known 5-210
  • 211. 5.10 Nested Loops • A nested loop is a loop inside the body of another loop • Example: for (row = 1; row <= 3; row++) { for (col = 1; col <= 3; col++) { cout << row * col << endl; } } 5-211 outer loop inner loop
  • 212. Notes on Nested Loops • Inner loop goes through all its repetitions for each repetition of outer loop • Inner loop repetitions complete sooner than outer loop • Total number of repetitions for inner loop is product of number of repetitions of the two loops. In previous example, inner loop repeats 9 times 5-212
  • 213. 5.11 Breaking Out of a Loop • Can use break to terminate execution of a loop • Use sparingly if at all – makes code harder to understand • When used in an inner loop, terminates that loop only and returns to the outer loop 5-213
  • 214. The continue Statement • Can use continue to go to end of loop and prepare for next repetition – while and do-while loops go to test and repeat the loop if test condition is true – for loop goes to update step, then tests, and repeats loop if test condition is true • Use sparingly – like break, can make program logic hard to follow 5-214
  • 215. 5.12 Using Files for Data Storage • We can use a file instead of monitor screen for program output • Files are stored on secondary storage media, such as disk • Files allow data to be retained between program executions • We can later use the file instead of a keyboard for program input 3-215
  • 216. File Types • Text file – contains information encoded as text, such as letters, digits, and punctuation. Can be viewed with a text editor such as Notepad. • Binary file – contains binary (0s and 1s) information that has not been encoded as text. It cannot be viewed with a text editor. 3-216
  • 217. File Access – Ways to Use the Data in a File • Sequential access – read the 1st piece of data, read the 2nd piece of data, …, read the last piece of data. To access the n-th piece of data, you have to retrieve the preceding n pieces first. • Random (direct) access – retrieve any piece of data directly, without the need to retrieve preceding data items. 3-217
  • 218. What is Needed to Use Files 1. Include the fstream header file 2. Define a file stream object • ifstream for input from a file ifstream inFile; • ofstream for output to a file ofstream outFile; 3-218
  • 219. Open the File 3. Open the file • Use the open member function inFile.open("inventory.dat"); outFile.open("report.txt"); • Filename may include drive, path info. • Output file will be created if necessary; existing output file will be erased first • Input file must exist for open to work 3-219
  • 220. Use the File 4. Use the file • Can use output file object and << to send data to a file outFile << "Inventory report"; • Can use input file object and >> to copy data from file to variables inFile >> partNum; inFile >> qtyInStock >> qtyOnOrder; 3-220
  • 221. Close the File 5. Close the file • Use the close member function inFile.close(); outFile.close(); • Don’t wait for operating system to close files at program end – There may be limit on number of open files – There may be buffered output data waiting to be sent to a file that could be lost 3-221 Can use a file instead of keyboard for program input
  • 222. Input File – the Read Position • Read Position – location of the next piece of data in an input file • Initially set to the first byte in the file • Advances for each data item that is read. Successive reads will retrieve successive data items. 3-222
  • 223. Using Loops to Process Files • A loop can be used to read data from or write data to a file • It is not necessary to know how much data is in the file or will be written to the file • Several methods exist to test for the end of the file 5-223
  • 224. Using the >> Operator to Test for End of File (EOF) on an Input File • The stream extraction operator (>>) returns a true or false value indicating if a read is successful • This can be tested to find the end of file since the read “fails” when there is no more data • Example: while (inFile >> score) sum += score; 5-224
  • 225. File Open Errors • An error will occur if an attempt to open a file for input fails: – File does not exist – Filename is misspelled – File exists, but is in a different place • The file stream object is set to true if the open operation succeeded. It can be tested to see if the file can be used: if (inFile) { // process data from file } else cout << "Error on file openn"; 5-225
  • 226. User-Specified Filenames • Program can prompt user to enter the names of input and/or output files. This makes the program more versatile. • Filenames can be read into string objects. The C-string representation of the string object can then be passed to the open function: cout << "Which input file? "; cin >> inputFileName; inFile.open(inputFileName.c_str()); 5-226
  • 227. 5.13 Creating Good Test Data • When testing a program, the quality of the test data is more important than the quantity. • Test data should show how different parts of the program execute • Test data should evaluate how program handles: – normal data – data that is at the limits the valid range – invalid data 5-227 See pr5-09.cpp
  • 229. Topics 6.1 Modular Programming 6.2 Defining and Calling Functions 6.3 Function Prototypes 6.4 Sending Data into a Function 6.5 Passing Data by Value 6.6 The return Statement 6.7 Returning a Value from a Function 6.8 Returning a Boolean Value 6-229
  • 230. Topics (continued) 6.9 Using Functions in a Menu-Driven Program 6.10 Local and Global Variables 6.11 Static Local Variables 6.12 Default Arguments 6.13 Using Reference Variables as Parameters 6.14 Overloading Functions 6.15 The exit() Function 6.16 Stubs and Drivers 6-230
  • 231. 6.1 Modular Programming • Modular programming: breaking a program up into smaller, manageable functions or modules. Supports the divide-and-conquer approach to solving a problem. • Function: a collection of statements to perform a specific task • Motivation for modular programming – Simplifies the process of writing programs – Improves maintainability of programs 6-231
  • 232. 6.2 Defining and Calling Functions • Function call: a statement that causes a function to execute • Function definition: the statements that make up a function 6-232
  • 233. Function Definition • Definition includes name: name of the function. Function names follow same rules as variable names parameter list: variables that hold the values passed to the function body: statements that perform the function’s task return type: data type of the value the function returns to the part of the program that called it 6-233
  • 235. Function Header • The function header consists of – the function return type – the function name – the function parameter list • Example: int main() • Note: no ; at the end of the header 6-235
  • 236. Function Return Type • If a function returns a value, the type of the value must be indicated int main() • If a function does not return a value, its return type is void void printHeading() { cout << "tMonthly Salesn"; } 6-236
  • 237. Calling a Function • To call a function, use the function name followed by () and ; printHeading(); • When a function is called, the program executes the body of the function • After the function terminates, execution resumes in the calling module at the point of call 6-237
  • 238. Calling a Function • main is automatically called when the program starts • main can call any number of functions • Functions can call other functions 6-238
  • 239. 6.3 Function Prototypes The compiler must know the following about a function before it is called – name – return type – number of parameters – data type of each parameter 6-239
  • 240. Function Prototypes Ways to notify the compiler about a function before a call to the function: – Place function definition before calling function’s definition – Use a function prototype (similar to the heading of the function • Heading: void printHeading() • Prototype: void printHeading(); – Function prototype is also called a function declaration 6-240
  • 241. Prototype Notes • Place prototypes near top of program • Program must include either prototype or full function definition before any call to the function, otherwise a compiler error occurs • When using prototypes, function definitions can be placed in any order in the source file. Traditionally, main is placed first. 6-241
  • 242. 6.4 Sending Data into a Function • Can pass values into a function at time of call c = sqrt(a*a + b*b); • Values passed to function are arguments • Variables in function that hold values passed as arguments are parameters • Alternate names: – argument: actual argument, actual parameter – parameter: formal argument, formal parameter 6-242
  • 243. Parameters, Prototypes, and Function Headings • For each function argument, – the prototype must include the data type of each parameter in its () void evenOrOdd(int); //prototype – the heading must include a declaration, with variable type and name, for each parameter in its () void evenOrOdd(int num) //heading • The function call for the above function would look like this: evenOrOdd(val); //call Note: no data type on argument in call 6-243
  • 244. Function Call Notes • Value of argument is copied into parameter when the function is called • Function can have > 1 parameter • There must be a data type listed in the prototype () and an argument declaration in the function heading () for each parameter • Arguments will be promoted/demoted as necessary to match parameters. Be careful! 6-244
  • 245. Calling Functions with Multiple Arguments When calling a function with multiple arguments – the number of arguments in the call must match the function prototype and definition – the first argument will be copied into the first parameter, the second argument into the second parameter, etc. 6-245
  • 246. Calling Functions with Multiple Arguments Illustration displayData(height, weight); // call void displayData(int h, int w)// heading { cout << "Height = " << h << endl; cout << "Weight = " << w << endl; } 6-246
  • 247. 6.5 Passing Data by Value • Pass by value: when an argument is passed to a function, a copy of its value is placed in the parameter • The function cannot access the original argument • Changes to the parameter in the function do not affect the value of the argument in the calling function 6-247
  • 248. Passing Data to Parameters by Value • Example: int val = 5; evenOrOdd(val); • evenOrOdd can change variable num, but it will have no effect on variable val 6-248 5 val argument in calling function 5 num parameter in evenOrOdd function
  • 249. 6.6 The return Statement • Used to end execution of a function • Can be placed anywhere in a function – Statements that follow the return statement will not be executed • Can be used to prevent abnormal termination of program • Without a return statement, the function ends at its last } 6-249
  • 250. 6.7 Returning a Value from a Function • return statement can be used to return a value from the function to the module that made the function call • Prototype and definition must indicate data type of return value (not void) • Calling function should use return value, e.g., – assign it to a variable – send it to cout – use it in an arithmetic computation – use it in a relational expression 6-250
  • 251. Returning a Value – the return Statement • Format: return expression; • expression may be a variable, a literal value, or an expression. • expression should be of the same data type as the declared return type of the function (will be converted if not) 6-251
  • 252. 6.8 Returning a Boolean Value • Function can return true or false • Declare the return type in the function prototype and heading as bool • The function body must contain return statement(s) that return true or false • The calling function can use the return value in a relational expression 6-252
  • 253. Boolean return Example bool isValid(int); // prototype bool isValid(int val) // heading { int min = 0, max = 100; if (val >= min && val <= max) return true; else return false; } if (isValid(score)) // call … 6-253
  • 254. 6.9 Using Functions in a Menu-Driven Program Functions can be used • to implement user choices from menu • to implement general-purpose tasks - Higher-level functions can call general-purpose functions - This minimizes the total number of functions and speeds program development time 6-254
  • 255. 6.10 Local and Global Variables • local variable: defined within a function or block; accessible only within the function or block • Other functions and blocks can define variables with the same name • When a function is called, local variables in the calling function are not accessible from within the called function 6-255
  • 256. Local Variable Lifetime • A local variable only exists while its defining function is executing • Local variables are destroyed when the function terminates • Data cannot be retained in local variables between calls to the function in which they are defined 6-256
  • 257. Local and Global Variables • global variable: a variable defined outside all functions; it is accessible to all functions within its scope • Easy way to share large amounts of data between functions • Scope of a global variable is from its point of definition to the program end • Use sparingly 6-257
  • 258. Initializing Local and Global Variables • Local variables must be initialized by the programmer • Global variables are initialized to 0 (numeric) or NULL (character) when the variable is defined. These can be overridden with explicit initial values. 6-258
  • 259. Global Variables – Why Use Sparingly? Global variables make: • Programs that are difficult to debug • Functions that cannot easily be re-used in other programs • Programs that are hard to understand 6-259
  • 260. Global Constants • A global constant is a named constant that can be used by every function in a program • It is useful if there are unchanging values that are used throughout the program • They are safer to use than global variables, since the value of a constant cannot be modified during program execution 6-260
  • 261. Local and Global Variable Names • Local variables can have same names as global variables • When a function contains a local variable that has the same name as a global variable, the global variable is unavailable from within the function. The local definition "hides" or "shadows" the global definition. 6-261
  • 262. 6.11 Static Local Variables • Local variables – Only exist while the function is executing – Are redefined each time function is called – Lose their contents when function terminates • static local variables – Are defined with key word static static int counter; – Are defined and initialized only the first time the function is executed – Retain their contents between function calls 6-262
  • 263. 6.12 Default Arguments • Values passed automatically if arguments are missing from the function call • Must be a constant declared in prototype or header (whichever occurs first) void evenOrOdd(int = 0); • Multi-parameter functions may have default arguments for some or all parameters int getSum(int, int=0, int=0); 6-263
  • 264. Default Arguments • If not all parameters to a function have default values, the ones without defaults must be declared first in the parameter list int getSum(int, int=0, int=0);// OK int getSum(int, int=0, int); // wrong! • When an argument is omitted from a function call, all arguments after it must also be omitted sum = getSum(num1, num2); // OK sum = getSum(num1, , num3); // wrong! 6-264
  • 265. 6.13 Using Reference Variables as Parameters • Mechanism that allows a function to work with the original argument from the function call, not a copy of the argument • Allows the function to modify values stored in the calling environment • Provides a way for the function to ‘return’ more than 1 value 6-265
  • 266. Reference Variables • A reference variable is an alias for another variable • It is defined with an ampersand (&) in the prototype and in the header void getDimensions(int&, int&); • Changes to a reference variable are made to the variable it refers to • Use reference variables to implement passing parameters by reference 6-266
  • 267. Pass by Reference Example void squareIt(int &); //prototype void squareIt(int &num) { num *= num; } int localVar = 5; squareIt(localVar); // localVar now // contains 25 6-267
  • 268. Reference Variable Notes • Each reference parameter must contain & • Argument passed to reference parameter must be a variable. It cannot be an expression or a constant. • Use only when appropriate, such as when the function must input or change the value of the argument passed to it • Files (i.e., file stream objects) should be passed by reference 6-268
  • 269. 6.14 Overloading Functions • Overloaded functions are two or more functions that have the same name, but different parameter lists • Can be used to create functions that perform the same task, but take different parameter types or different number of parameters • Compiler will determine which version of the function to call by the argument and parameter list 6-269
  • 270. Overloaded Functions Example If a program has these overloaded functions, void getDimensions(int); // 1 void getDimensions(int, int); // 2 void getDimensions(int, float); // 3 void getDimensions(double, double);// 4 then the compiler will use them as follows: int length, width; double base, height; getDimensions(length); // 1 getDimensions(length, width); // 2 getDimensions(length, height); // 3 getDimensions(height, base); // 4 6-270
  • 271. 6.15 The exit() Function • Terminates execution of a program • Can be called from any function • Can pass a value to operating system to indicate status of program execution • Usually used for abnormal termination of program • Requires cstdlib header file • Use with care 6-271
  • 272. exit() – Passing Values to Operating System • Use an integer value to indicate program status • Often, 0 means successful completion, non-zero indicates a failure condition • Can use named constants defined in cstdlib: – EXIT_SUCCESS and – EXIT_FAILURE 6-272
  • 273. 6.16 Stubs and Drivers • Stub: dummy function in place of actual function • Usually displays a message indicating it was called. May also display parameters • Driver: function that tests a function by calling it • Stubs and drivers are useful for testing and debugging program logic and design 6-273
  • 274. Chapter 7: Introduction to Classes and Objects
  • 275. Topics 7.1 Abstract Data Types 7.2 Object-Oriented Programming 7.3 Introduction to Classes 7.4 Creating and Using Objects 7.5 Defining Member Functions 7.6 Constructors 7.7 Destructors 7.8 Private Member Functions 7-275
  • 276. Topics (Continued) 7.9 Passing Objects to Functions 7.10 Object Composition 7.11 Separating Class Specification, Implementation, and Client Code 7.12 Structures 7.14 Introduction to Object-Oriented Analysis and Design 7.15 Screen Control 7-276
  • 277. 7.1 Abstract Data Types • Programmer-created data types that specify – legal values that can be stored – operations that can be done on the values • The user of an abstract data type (ADT) does not need to know any implementation details (e.g., how the data is stored or how the operations on it are carried out) 7-277
  • 278. Abstraction in Software Development • Abstraction allows a programmer to design a solution to a problem and to use data items without concern for how the data items are implemented • This has already been encountered in the book: – To use the pow function, you need to know what inputs it expects and what kind of results it produces – You do not need to know how it works 7-278
  • 279. Abstraction and Data Types • Abstraction: a definition that captures general characteristics without details ex: An abstract triangle is a 3-sided polygon. A specific triangle may be scalene, isosceles, or equilateral • Data Type: defines the kind of values that can be stored and the operations that can be performed on it 7-279
  • 280. 7.2 Object-Oriented Programming • Procedural programming uses variables to store data, and focuses on the processes/ functions that occur in a program. Data and functions are separate and distinct. • Object-oriented programming is based on objects that encapsulate the data and the functions that operate on it. 7-280
  • 281. Object-Oriented Programming Terminology • object: software entity that combines data and functions that act on the data in a single unit • attributes: the data items of an object, stored in member variables • member functions (methods): procedures/ functions that act on the attributes of the class 7-281
  • 282. More Object-Oriented Programming Terminology • data hiding: restricting access to certain members of an object. The intent is to allow only member functions to directly access and modify the object’s data • encapsulation: the bundling of an object’s data and procedures into a single entity 7-282
  • 283. Object Example 7-283 Member variables (attributes) int side; Member functions void setSide(int s) { side = s; } int getSide() { return side; } Square Square object’s data item: side Square object’s functions: setSide - set the size of the side of the square, getSide - return the size of the side of the square
  • 284. Why Hide Data? • Protection – Member functions provide a layer of protection against inadvertent or deliberate data corruption • Need-to-know – A programmer can use the data via the provided member functions. As long as the member functions return correct information, the programmer needn’t worry about implementation details. 7-284
  • 285. 7.3 Introduction to Classes • Class: a programmer-defined data type used to define objects • It is a pattern for creating objects ex: string fName, lName; creates two objects of the string class 7-285
  • 286. Introduction to Classes • Class declaration format: class className { declaration; declaration; }; 7-286 Notice the required ;
  • 287. Access Specifiers • Used to control access to members of the class. • Each member is declared to be either public: can be accessed by functions outside of the class or private: can only be called by or accessed by functions that are members of the class 7-287
  • 288. Class Example class Square { private: int side; public: void setSide(int s) { side = s; } int getSide() { return side; } }; 7-288 Access specifiers
  • 289. More on Access Specifiers • Can be listed in any order in a class • Can appear multiple times in a class • If not specified, the default is private 7-289
  • 290. 7.4 Creating and Using Objects • An object is an instance of a class • It is defined just like other variables Square sq1, sq2; • It can access members using dot operator sq1.setSide(5); cout << sq1.getSide(); 7-290
  • 291. Types of Member Functions • Acessor, get, getter function: uses but does not modify a member variable ex: getSide • Mutator, set, setter function: modifies a member variable ex: setSide 7-291
  • 292. 7.5 Defining Member Functions • Member functions are part of a class declaration • Can place entire function definition inside the class declaration or • Can place just the prototype inside the class declaration and write the function definition after the class 7-292
  • 293. Defining Member Functions Inside the Class Declaration • Member functions defined inside the class declaration are called inline functions • Only very short functions, like the one below, should be inline functions int getSide() { return side; } 7-293
  • 294. Inline Member Function Example class Square { private: int side; public: void setSide(int s) { side = s; } int getSide() { return side; } }; 7-294 inline functions
  • 295. Defining Member Functions After the Class Declaration • Put a function prototype in the class declaration • In the function definition, precede the function name with the class name and scope resolution operator (::) int Square::getSide() { return side; } 7-295
  • 296. Conventions and a Suggestion Conventions: • Member variables are usually private • Accessor and mutator functions are usually public • Use ‘get’ in the name of accessor functions, ‘set’ in the name of mutator functions Suggestion: calculate values to be returned in accessor functions when possible, to minimize the potential for stale data 7-296
  • 297. Tradeoffs of Inline vs. Regular Member Functions • When a regular function is called, control passes to the called function – the compiler stores return address of call, allocates memory for local variables, etc. • Code for an inline function is copied into the program in place of the call when the program is compiled – This makes alarger executable program, but – There is less function call overhead, and possibly faster execution 7-297
  • 298. 7.6 Constructors • A constructor is a member function that is often used to initialize data members of a class • Is called automatically when an object of the class is created • It must be a public member function • It must be named the same as the class • It must have no return type 7-298
  • 299. Constructor – 2 Examples Inline: class Square { . . . public: Square(int s) { side = s; } . . . }; Declaration outside the class: Square(int); //prototype //in class Square::Square(int s) { side = s; } 7-299
  • 300. Overloading Constructors • A class can have more than 1 constructor • Overloaded constructors in a class must have different parameter lists Square(); Square(int); 7-300
  • 301. The Default Constructor • Constructors can have any number of parameters, including none • A default constructor is one that takes no arguments either due to – No parameters or – All parameters have default values • If a class has any programmer-defined constructors, it must have a programmer- defined default constructor 7-301
  • 302. Default Constructor Example class Square { private: int side; public: Square() // default { side = 1; } // constructor // Other member // functions go here }; 7-302 Has no parameters
  • 303. Another Default Constructor Example class Square { private: int side; public: Square(int s = 1) // default { side = s; } // constructor // Other member // functions go here }; 7-303 Has parameter but it has a default value
  • 304. Invoking a Constructor • To create an object using the default constructor, use no argument list and no () Square square1; • To create an object using a constructor that has parameters, include an argument list Square square1(8); 7-304
  • 305. 7.7 Destructors • Is a public member function automatically called when an object is destroyed • The destructor name is ~className, e.g., ~Square • It has no return type • It takes no arguments • Only 1 destructor is allowed per class (i.e., it cannot be overloaded) 7-305
  • 306. 7. 8 Private Member Functions • A private member function can only be called by another member function of the same class • It is used for internal processing by the class, not for use outside of the class 7-306
  • 307. 7.9 Passing Objects to Functions • A class object can be passed as an argument to a function • When passed by value, function makes a local copy of object. Original object in calling environment is unaffected by actions in function • When passed by reference, function can use ‘set’ functions to modify the object. 7-307
  • 308. 7-308 Notes on Passing Objects • Using a value parameter for an object can slow down a program and waste space • Using a reference parameter speeds up program, but allows the function to modify data in the parameter
  • 309. 7-309 Notes on Passing Objects • To save space and time, while protecting parameter data that should not be changed, use a const reference parameter void showData(const Square &s) // header • In order to for the showData function to call Square member functions, those functions must use const in their prototype and header: int Square::getSide() const;
  • 310. 7-310 Returning an Object from a Function • A function can return an object Square initSquare(); // prototype s1 = initSquare(); // call • The function must define a object – for internal use – to use with return statement
  • 311. 7-311 Returning an Object Example Square initSquare() { Square s; // local variable int inputSize; cout << "Enter the length of side: "; cin >> inputSize; s.setSide(inputSize); return s; }
  • 312. 7.10 Object Composition • Occurs when an object is a member variable of another object. • It is often used to design complex objects whose members are simpler objects • ex. (from book): Define a rectangle class. Then, define a carpet class and use a rectangle object as a member of a carpet object. 7-312
  • 314. 7.11 Separating Class Specification, Implementation, and Client Code Separating class declaration, member function definitions, and the program that uses the class into separate files is considered good design 7-314
  • 315. Using Separate Files • Place class declaration in a header file that serves as the class specification file. Name the file classname.h (for example, Square.h) • Place member function definitions in a class implementation file. Name the file classname.cpp (for example, Square.cpp)This file should #include the class specification file. • A client program (client code) that uses the class must #include the class specification file and be compiled and linked with the class implementation file. 7-315
  • 316. Include Guards • Used to prevent a header file from being included twice • Format: #ifndef symbol_name #define symbol_name . . . (normal contents of header file) #endif • symbol_name is usually the name of the header file, in all capital letters: #ifndef SQUARE_H #define SQUARE_H . . . #endif 7-316
  • 317. What Should Be Done Inside vs. Outside the Class • Class should be designed to provide functions to store and retrieve data • In general, input and output (I/O) should be done by functions that use class objects, rather than by class member functions 7-317
  • 318. 7-318 7.12 Structures • Structure: Programmer-defined data type that allows multiple variables to be grouped together • Structure Declaration Format: struct structure name { type1 field1; type2 field2; … typen fieldn; };
  • 319. 7-319 Example struct Declaration struct Student { int studentID; string name; short year; double gpa; }; structure name structure members Notice the required ;
  • 320. 7-320 struct Declaration Notes • struct names commonly begin with an uppercase letter • The structure name is also called the tag • Multiple fields of same type can be in a comma-separated list string name, address; • Fields in a structure are all public by default
  • 321. 7-321 Defining Structure Variables • struct declaration does not allocate memory or create variables • To define variables, use structure tag as type name Student s1; studentID name year gpa s1
  • 322. 7-322 Accessing Structure Members • Use the dot (.) operator to refer to members of struct variables getline(cin, s1.name); cin >> s1.studentID; s1.gpa = 3.75; • Member variables can be used in any manner appropriate for their data type
  • 323. 7-323 Displaying struct Members To display the contents of a struct variable, you must display each field separately, using the dot operator Wrong: cout << s1; // won’t work! Correct: cout << s1.studentID << endl; cout << s1.name << endl; cout << s1.year << endl; cout << s1.gpa;
  • 324. 7-324 Comparing struct Members • Similar to displaying a struct, you cannot compare two struct variables directly: if (s1 >= s2) // won’t work! • Instead, compare member variables: if (s1.gpa >= s2.gpa) // better
  • 325. 7-325 Initializing a Structure Cannot initialize members in the structure declaration, because no memory has been allocated yet struct Student // Illegal { // initialization int studentID = 1145; string name = "Alex"; short year = 1; float gpa = 2.95; };
  • 326. 7-326 Initializing a Structure (continued) • Structure members are initialized at the time a structure variable is created • Can initialize a structure variable’s members with either – an initialization list – a constructor
  • 327. 7-327 Using an Initialization List An initialization list is an ordered set of values, separated by commas and contained in { }, that provides initial values for a set of data members {12, 6, 3} // initialization list // with 3 values
  • 328. 7-328 More on Initialization Lists • Order of list elements matters: First value initializes first data member, second value initializes second data member, etc. • Elements of an initialization list can be constants, variables, or expressions {12, W, L/W + 1} // initialization list // with 3 items
  • 329. 7-329 Initialization List Example Structure Declaration Structure Variable struct Dimensions { int length, width, height; }; Dimensions box = {12,6,3}; box length 12 width 6 height 3
  • 330. 7-330 Partial Initialization Can initialize just some members, but cannot skip over members Dimensions box1 = {12,6}; //OK Dimensions box2 = {12,,3}; //illegal
  • 331. 7-331 Problems with Initialization List • Can’t omit a value for a member without omitting values for all following members • Does not work on most modern compilers if the structure contains any string objects – Will, however, work with C-string members
  • 332. 7-332 Using a Constructor to Initialize Structure Members • Similar to a constructor for a class: – name is the same as the name of the struct – no return type – used to initialize data members • It is normally written inside the struct declaration
  • 333. 7-333 A Structure with a Constructor struct Dimensions { int length, width, height; // Constructor Dimensions(int L, int W, int H) {length = L; width = W; height = H;} };
  • 334. 7-334 Nested Structures A structure can have another structure as a member. struct PersonInfo { string name, address, city; }; struct Student { int studentID; PersonInfo pData; short year; double gpa; };
  • 335. 7-335 Members of Nested Structures Use the dot operator multiple times to access fields of nested structures Student s5; s5.pData.name = "Joanne"; s5.pData.city = "Tulsa";
  • 336. 7-336 Structures as Function Arguments • May pass members of struct variables to functions computeGPA(s1.gpa); • May pass entire struct variables to functions showData(s5); • Can use reference parameter if function needs to modify contents of structure variable
  • 337. 7-337 Notes on Passing Structures • Using a value parameter for structure can slow down a program and waste space • Using a reference parameter speeds up program, but allows the function to modify data in the structure • To save space and time, while protecting structure data that should not be changed, use a const reference parameter void showData(const Student &s) // header
  • 338. 7-338 Returning a Structure from a Function • Function can return a struct Student getStuData(); // prototype s1 = getStuData(); // call • Function must define a local structure variable – for internal use – to use with return statement
  • 339. 7-339 Returning a Structure Example Student getStuData() { Student s; // local variable cin >> s.studentID; cin.ignore(); getline(cin, s.pData.name); getline(cin, s.pData.address); getline(cin, s.pData.city); cin >> s.year; cin >> s.gpa; return s; }
  • 340. 7-340 Unions • Similar to a struct, but – all members share a single memory location, which saves space – only 1 member of the union can be used at a time • Declared using key word union • Otherwise the same as struct • Variables defined and accessed like struct variables
  • 341. 7-341 Example union Declaration union WageInfo { double hourlyRate; float annualSalary; }; union tag Notice the required ; union members
  • 342. 7.14 Introduction to Object-Oriented Analysis and Design • Object-Oriented Analysis: that phase of program development when the program functionality is determined from the requirements • It includes – identification of objects and classes – definition of each class's attributes – identification of each class's behaviors – definition of the relationship between classes 7-342
  • 343. Identify Objects and Classes • Consider the major data elements and the operations on these elements • Candidates include – user-interface components (menus, text boxes, etc.) – I/O devices – physical objects – historical data (employee records, transaction logs, etc.) – the roles of human participants 7-343
  • 344. Define Class Attributes • Attributes are the data elements of an object of the class • They are necessary for the object to work in its role in the program 7-344
  • 345. Define Class Behaviors • For each class, – Identify what an object of a class should do in the program • The behaviors determine some of the member functions of the class 7-345
  • 346. Relationships Between Classes Possible relationships – Access ("uses-a") – Ownership/Composition ("has-a") – Inheritance ("is-a") 7-346
  • 347. Finding the Classes Technique: • Write a description of the problem domain (objects, events, etc. related to the problem) • List the nouns, noun phrases, and pronouns. These are all candidate objects • Refine the list to include only those objects that are relevant to the problem 7-347
  • 348. Determine Class Responsibilities Class responsibilities: • What is the class responsible to know? • What is the class responsible to do? Use these to define some of the member functions 7-348
  • 349. Object Reuse • A well-defined class can be used to create objects in multiple programs • By re-using an object definition, program development time is shortened • One goal of object-oriented programming is to support object reuse 7-349
  • 350. 7.15 Screen Control • Programs to date have all displayed output starting at the upper left corner of computer screen or output window. Output is displayed left-to-right, line-by-line. • Computer operating systems are designed to allow programs to access any part of the computer screen. Such access is operating system-specific. 7-350
  • 351. Screen Control – Concepts • An output screen can be thought of as a grid of 25 rows and 80 columns. Row 0 is at the top of the screen. Column 0 is at the left edge of the screen. • The intersection of a row and a column is a cell. It can display a single character. • A cell is identified by its row and column number. These are its coordinates. 7-351
  • 352. Screen Control – Windows - Specifics • #include <windows.h> to access the operating system from a program • Create a handle to reference the output screen: HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE); • Create a COORD structure to hold the coordinates of a cell on the screen: COORD position; 7-352
  • 353. Screen Control – Windows – More Specifics • Assign coordinates where the output should appear: position.X = 30; // column position.Y = 12; // row • Set the screen cursor to this cell: SetConsoleCursorPosition(screen, position); • Send output to the screen: cout << "Look at me!" << endl; – be sure to end with endl, not 'n' or nothing 7-353
  • 355. Topics 8.1 Arrays Hold Multiple Values 8.2 Accessing Array Elements 8.3 Inputting and Displaying Array Contents 8.4 Array Initialization 8.5 Processing Array Contents 8.6 Using Parallel Arrays 8-355
  • 356. Topics (continued) 8.7 The typedef Statement 8.8 Arrays as Function Arguments 8.9 Two-Dimensional Arrays 8.10 Arrays with Three or More Dimensions 8.11 Vectors 8.12 Arrays of Objects 8-356
  • 357. 8.1 Arrays Hold Multiple Values • Array: variable that can store multiple values of the same type • Values are stored in consecutive memory locations • Declared using [] operator const int ISIZE = 5; int tests[ISIZE]; 8-357
  • 358. Array Storage in Memory The definition int tests[ISIZE]; // ISIZE is 5 allocates the following memory 8-358 Element 0 Element 1 Element 2 Element 3 Element 4
  • 359. Array Terminology In the definition int tests[ISIZE]; – int is the data type of the array elements – tests is the name of the array – ISIZE, in [ISIZE], is the size declarator. It shows the number of elements in the array. – The size of an array is the number of bytes allocated for it (number of elements) * (bytes needed for each element) 8-359
  • 360. Array Terminology Examples Examples: Assumes int uses 4 bytes and double uses 8 bytes const int ISIZE = 5, DSIZE = 10; int tests[ISIZE]; // holds 5 ints, array // occupies 20 bytes double volumes[DSIZE];// holds 10 doubles, // array occupies // 80 bytes 8-360
  • 361. 8.2 Accessing Array Elements • Each array element has a subscript, used to access the element. • Subscripts start at 0 8-361 subscripts 0 1 2 3 4
  • 362. Accessing Array Elements Array elements (accessed by array name and subscript) can be used as regular variables tests[0] = 79; cout << tests[0]; cin >> tests[1]; tests[4] = tests[0] + tests[1]; cout << tests; // illegal due to // missing subscript 8-362 0 1 2 3 4 tests
  • 363. 8.3 Inputting and Displaying Array Contents cout and cin can be used to display values from and store values into an array const int ISIZE = 5; int tests[ISIZE]; // Define 5-elt. array cout << "Enter first test score "; cin >> tests[0]; 8-363
  • 364. Array Subscripts • Array subscript can be an integer constant, integer variable, or integer expression • Examples: Subscript is cin >> tests[3]; int constant cout << tests[i]; int variable cout << tests[i+j]; int expression 8-364
  • 365. Accessing All Array Elements To access each element of an array – Use a loop – Let the loop control variable be the array subscript – A different array element will be referenced each time through the loop for (i = 0; i < 5; i++) cout << tests[i] << endl; 8-365
  • 366. Getting Array Data from a File const int ISIZE = 5, sales[ISIZE]; ifstream dataFile; datafile.open("sales.dat"); if (!dataFile) cout << "Error opening data filen"; else { // Input daily sales for (int day = 0; day < ISIZE; day++) dataFile >> sales[day]; dataFile.close(); } 8-366
  • 367. No Bounds Checking • There are no checks in C++ that an array subscript is in range • An invalid array subscript can cause program to overwrite other memory • Example: const int ISIZE = 3; int i = 4; int num[ISIZE]; num[i] = 25; 8-367 num [0] [1] [2] 25
  • 368. Off-By-One Errors • Most often occur when a program accesses data one position beyond the end of an array, or misses the first or last element of an array. • Don’t confuse the ordinal number of an array element (first, second, third) with its subscript (0, 1, 2) 8-368
  • 369. 8.4 Array Initialization • Can be initialized during program execution with assignment statements tests[0] = 79; tests[1] = 82; // etc. • Can be initialized at array definition with an initialization list const int ISIZE = 5; int tests[ISIZE] = {79,82,91,77,84}; 8-369
  • 370. Start at element 0 or 1? • You may choose to declare arrays to be one larger than needed. This allows you to use the element with subscript 1 as the ‘first’ element, etc., and may minimize off- by-one errors. • The element with subscript 0 is not used. • This is most often done when working with ordered data, e.g., months of the year or days of the week 8-370
  • 371. Partial Array Initialization • If array is initialized at definition with fewer values than the size declarator of the array, remaining elements will be set to 0 or the empty string int tests[ISIZE] = {79, 82}; • Initial values used in order; cannot skip over elements to initialize noncontiguous range • Cannot have more values in initialization list than the declared size of the array 8-371 79 82 0 0 0
  • 372. Implicit Array Sizing • Can determine array size by the size of the initialization list short quizzes[]={12,17,15,11}; • Must use either array size declarator or initialization list when array is defined 8-372 12 17 15 11
  • 373. 8.5 Processing Array Contents • Array elements can be – treated as ordinary variables of the same type as the array – used in arithmetic operations, in relational expressions, etc. • Example: if (principalAmt[3] >= 10000) interest = principalAmt[3] * intRate1; else interest = principalAmt[3] * intRate2; 8-373
  • 374. Using Increment and Decrement Operators with Array Elements When using ++ and -- operators, don’t confuse the element with the subscript tests[i]++; // adds 1 to tests[i] tests[i++]; // increments i, but has // no effect on tests 8-374
  • 375. Copying One Array to Another • Cannot copy with an assignment statement: tests2 = tests; //won’t work • Must instead use a loop to copy element- by-element: for (int indx=0; indx < ISIZE; indx++) tests2[indx] = tests[indx]; 8-375
  • 376. Are Two Arrays Equal? • Like copying, cannot compare in a single expression: if (tests2 == tests) • Use a while loop with a boolean variable: bool areEqual=true; int indx=0; while (areEqual && indx < ISIZE) { if(tests[indx] != tests2[indx] areEqual = false; } 8-376
  • 377. Sum, Average of Array Elements • Use a simple loop to add together array elements float average, sum = 0; for (int tnum=0; tnum< ISIZE; tnum++) sum += tests[tnum]; • Once summed, average can be computed average = sum/ISIZE; 8-377
  • 378. Largest Array Element • Use a loop to examine each element and find the largest element (i.e., one with the largest value) int largest = tests[0]; for (int tnum = 1; tnum < ISIZE; tnum++) { if (tests[tnum] > largest) largest = tests[tnum]; } cout << "Highest score is " << largest; • A similar algorithm exists to find the smallest element 8-378
  • 379. Partially-Filled Arrays • The exact amount of data (and, therefore, array size) may not be known when a program is written. • Programmer makes best estimate for maximum amount of data, sizes arrays accordingly. A sentinel value can be used to indicate end-of-data. • Programmer must also keep track of how many array elements are actually used 8-379
  • 380. Using Arrays vs. Using Simple Variables • An array is probably not needed if the input data is only processed once: – Find the sum or average of a set of numbers – Find the largest or smallest of a set of values • If the input data must be processed more than once, an array is probably a good idea: – Calculate the average, then determine and display which values are above the average and which are below the average 8-380
  • 381. C-Strings and string Objects Can be processed using array name – Entire string at once, or – One element at a time by using a subscript string city; cout << "Enter city name: "; cin >> city; 8-381 'S' 'a' 'l' 'e' 'm' city[0] city[1] city[2] city[3] city[4]
  • 382. 8.6 Using Parallel Arrays • Parallel arrays: two or more arrays that contain related data • Subscript is used to relate arrays – elements at same subscript are related • The arrays do not have to hold data of the same type 8-382
  • 383. Parallel Array Example const int ISIZE = 5; string name[ISIZE]; // student name float average[ISIZE]; // course average char grade[ISIZE]; // course grade 8-383 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 name average grade
  • 384. Parallel Array Processing const int ISIZE = 5; string name[ISIZE]; // student name float average[ISIZE]; // course average char grade[ISIZE]; // course grade ... for (int i = 0; i < ISIZE; i++) cout << " Student: " << name[i] << " Average: " << average[i] << " Grade: " << grade[i] << endl; 8-384
  • 385. 8.7 The typedef Statement • Creates an alias for a simple or structured data type • Format: typedef existingType newName; • Example: typedef unsigned int Uint; Uint tests[ISIZE]; // array of // unsigned ints 8-385
  • 386. Uses of typedef • Used to make code more readable • Can be used to create alias for an array of a particular type // Define yearArray as a data type // that is an array of 12 ints typedef int yearArray[MONTHS]; // Create two of these arrays yearArray highTemps, lowTemps; 8-386
  • 387. 8.8 Arrays as Function Arguments • Passing a single array element to a function is no different than passing a regular variable of that data type • Function does not need to know that the value it receives is coming from an array displayValue(score[i]); // call void displayValue(int item) // header { cout << item << endl; } 8-387
  • 388. Passing an Entire Array • To define a function that has an array parameter, use empty [] to indicate the array argument • To pass an array to a function, just use the array name // Function prototype void showScores(int []); // Function header void showScores(int tests[]) // Function call showScores(tests); 8-388
  • 389. Passing an Entire Array • Use the array name, without any brackets, as the argument • Can also pass the array size so the function knows how many elements to process showScores(tests, 5); // call void showScores(int[], int); // prototype void showScores(int A[], int size) // header 8-389
  • 390. Using typedef with a Passed Array Can use typedef to simplify function prototype and heading // Make intArray an integer array // of unspecified size typedef int intArray[]; // Function prototype void showScores(intArray, int); // Function header void showScores(intArray tests, int size) 8-390
  • 391. Modifying Arrays in Functions • Array parameters in functions are similar to reference variables • Changes made to array in a function are made to the actual array in the calling function • Must be careful that an array is not inadvertently changed by a function • Can use const keyword in prototype and header to prevent changes 8-391
  • 392. 8.9 Two-Dimensional Arrays • Can define one array for multiple sets of data • Like a table in a spreadsheet • Use two size declarators in definition int exams[4][3]; 8-392 Number of rows Number of cols
  • 393. Two-Dimensional Array Representation int exams[4][3]; Use two subscripts to access element exams[2][2] = 86; 8-393 exams[0][0] exams[0][1] exams[0][2] exams[1][0] exams[1][1] exams[1][2] exams[2][0] exams[2][1] exams[2][2] exams[3][0] exams[3][1] exams[3][2] columns r o w s
  • 394. Initialization at Definition • Two-dimensional arrays are initialized row- by-row int exams[2][2] = { {84, 78}, {92, 97} }; • Can omit inner { } 8-394 84 78 92 97
  • 395. Passing a Two-Dimensional Array to a Function • Use array name and number of columns as arguments in function call getExams(exams, 2); • Use empty [] for row and a size declarator for col in the prototype and header // Prototype, where NUM_COLS is 2 void getExams(int[][NUM_COLS], int); // Header void getExams (int exams[][NUM_COLS], int rows) 8-395
  • 396. Using typedef with a Two-Dimensional Array Can use typedef for simpler notation typedef int intExams[][2]; ... // Function prototype void getExams(intExams, int); // Function header void getExams(intExams exams, int rows) 8-396
  • 397. 2D Array Traversal • Use nested loops, one for row and one for column, to visit each array element. • Accumulators can be used to sum the elements row-by-row, column-by-column, or over the entire array. 8-397
  • 398. 8.10 Arrays with Three or More Dimensions • Can define arrays with any number of dimensions short rectSolid(2,3,5); double timeGrid(3,4,3,4); • When used as parameter, specify size of all but 1st dimension void getRectSolid(short [][3][5]); 8-398
  • 399. 8.11 Vectors • Holds a set of elements, like an array • Flexible number of elements - can grow and shrink – No need to specify size when defined – Automatically adds more space as needed • Defined in the Standard Template Library (STL) – Covered in a later chapter • Must include vector header file to use vectors #include <vector> 8-399
  • 400. Vectors • Can hold values of any type – Type is specified when a vector is defined vector<int> scores; vector<double> volumes; • Can use [] to access elements 8-400
  • 401. Defining Vectors • Define a vector of integers (starts with 0 elements) vector<int> scores; • Define int vector with initial size 30 elements vector<int> scores(30); • Define 20-element int vector and initialize all elements to 0 vector<int> scores(20, 0); • Define int vector initialized to size and contents of vector finals vector<int> scores(finals); 8-401
  • 402. Growing a Vector’s Size • Use push_back member function to add an element to a full array or to an array that had no defined size // Add a new element holding a 75 scores.push_back(75); • Use size member function to determine number of elements currently in a vector howbig = scores.size(); 8-402
  • 403. Removing Vector Elements • Use pop_back member function to remove last element from vector scores.pop_back(); • To remove all contents of vector, use clear member function scores.clear(); • To determine if vector is empty, use empty member function while (!scores.empty()) ... 8-403
  • 404. 8.14 Arrays of Objects • Objects can also be used as array elements class Square { private: int side; public: Square(int s = 1) { side = s; } int getSide() { return side; } }; Square shapes[10]; // Create array of 10 // Square objects 8-404
  • 405. Arrays of Objects • Like an array of structures, use an array subscript to access a specific object in the array • Then use dot operator to access member methods of that object for (i = 0; i < 10; i++) cout << shapes[i].getSide() << endl; 8-405
  • 406. Initializing Arrays of Objects • Can use default constructor to perform same initialization for all objects • Can use initialization list to supply specific initial values for each object Square shapes[5] = {1,2,3,4,5}; • Default constructor is used for the remaining objects if initialization list is too short Square boxes[5] = {1,2,3}; 8-406
  • 407. Initializing Arrays of Objects If an object is initialized with a constructor that takes > 1 argument, the initialization list must include a call to the constructor for that object Rectangle spaces[3] = { Rectangle(2,5), Rectangle(1,3), Rectangle(7,7) }; 8-407
  • 408. 8-408 Arrays of Structures • Structures can be used as array elements struct Student { int studentID; string name; short year; double gpa; }; const int CSIZE = 30; Student class[CSIZE]; // Holds 30 // Student structures
  • 409. 8-409 Arrays of Structures • Use array subscript to access a specific structure in the array • Then use dot operator to access members of that structure cin >> class[25].studentID; cout << class[i].name << " has GPA " << class[i].gpa << endl;
  • 410. Chapter 9: Searching, Sorting, and Algorithm Analysis
  • 411. Topics 9.1 Introduction to Search Algorithms 9.2 Searching an Array of Objects 9.3 Introduction to Sorting Algorithms 9.4 Sorting an Array of Objects 9.5 Sorting and Searching Vectors 9.6 Introduction to Analysis of Algorithms 9-411
  • 412. 9.1 Introduction to Search Algorithms • Search: to locate a specific item in a list (array, vector, etc.) of information • Two algorithms (methods) considered here: – Linear search (also called Sequential Search) – Binary search 9-412
  • 413. Linear Search Algorithm Set found to false Set position to –1 Set index to 0 While index < number of elts and found is false If list [index] is equal to search value found = true position = index End If Add 1 to index End While Return position 9-413
  • 414. Linear Search Example • Array numlist contains • Searching for the the value 11, linear search examines 17, 23, 5, and 11 • Searching for the the value 7, linear search examines 17, 23, 5, 11, 2, 29, and 3 9-414 17 23 5 11 2 29 3
  • 415. Linear Search Tradeoffs • Benefits – Easy algorithm to understand and to implement – Elements in array can be in any order • Disadvantage – Inefficient (slow): for array of N elements, it examines N/2 elements on average for a value that is found in the array, N elements for a value that is not in the array 9-415
  • 416. Binary Search Algorithm 1. Divide a sorted array into three sections: – middle element – elements on one side of the middle element – elements on the other side of the middle element 2. If the middle element is the correct value, done. Otherwise, go to step 1, using only the half of the array that may contain the correct value. 3. Continue steps 1 and 2 until either the value is found or there are no more elements to examine. 9-416
  • 417. Binary Search Example • Array numlist2 contains • Searching for the the value 11, binary search examines 11 and stops • Searching for the the value 7, binary search examines 11, 3, 5, and stops 9-417 2 3 5 11 17 23 29
  • 418. Binary Search Tradeoffs • Benefit – Much more efficient than linear search. For an array of N elements, it performs at most log2N comparisons. • Disadvantage – Requires that array elements be sorted 9-418
  • 419. 9.2 Searching an Array of Objects • Search algorithms are not limited to arrays of integers • When searching an array of objects or structures, the value being searched for is a member of an object or structure, not the entire object or structure • Member in object/structure: key field • Value used in search: search key 9-419
  • 420. 9.3 Introduction to Sorting Algorithms • Sort: arrange values into an order – Alphabetical – Ascending (smallest to largest) numeric – Descending (largest to smallest) numeric • Two algorithms considered here – Bubble sort – Selection sort 9-420
  • 421. Bubble Sort Algorithm 1. Compare 1st two elements and exchange them if they are out of order. 2. Move down one element and compare 2nd and 3rd elements. Exchange if necessary. Continue until the end of the array. 3. Pass through the array again, repeating the process and exchanging as necessary. 4. Repeat until a pass is made with no exchanges. 9-421
  • 422. Bubble Sort Example Array numlist3 contains 9-422 First, compare values 17 and 23. In correct order, so no exchange. Finally, compare values 23 and 11. Not in correct order, so exchange them. 17 23 5 11 Then, compare values 23 and 5. Not in correct order, so exchange them.
  • 423. Bubble Sort Example (continued) After first pass, array numlist3 contains 9-423 Compare values 17 and 5. Not in correct order, so exchange them. Compare values 17 and 23. In correct order, so no exchange. 17 5 11 23 Compare values 17 and 11. Not in correct order, so exchange them. In order from previous pass
  • 424. Bubble Sort Example (continued) After second pass, array numlist3 contains 9-424 No exchanges, so array is in order Compare values 5 and 11. In correct order, so no exchange. Compare values 17 and 23. In correct order, so no exchange. 5 11 17 23 Compare values 11 and 17. In correct order, so no exchange. In order from previous passes
  • 425. Bubble Sort Tradeoffs • Benefit – Easy to understand and to implement • Disadvantage – Inefficiency makes it slow for large arrays 9-425
  • 426. Selection Sort Algorithm 1. Locate smallest element in array and exchange it with element in position 0. 2. Locate next smallest element in array and exchange it with element in position 1. 3. Continue until all elements are in order. 9-426
  • 427. Selection Sort Example Array numlist contains Smallest element is 2. Exchange 2 with element in 1st array position (i.e., element 0). 9-427 11 2 29 3 2 11 29 3 Now in order
  • 428. Selection Sort – Example (continued) Next smallest element is 3. Exchange 3 with element in 2nd array position. Next smallest element is 11. Exchange 11 with element in 3rd array position. 9-428 2 3 29 11 2 3 11 29 Now in order Now in order
  • 429. Selection Sort Tradeoffs • Benefit – More efficient than Bubble Sort, due to fewer exchanges • Disadvantage – Considered harder than Bubble Sort to understand and implement 9-429
  • 430. 9.4 Sorting an Array of Objects • As with searching, arrays to be sorted can contain objects or structures • The key field determines how the structures or objects will be ordered • When exchanging the contents of array elements, entire structures or objects must be exchanged, not just the key fields in the structures or objects 9-430
  • 431. 9.5 Sorting and Searching Vectors • Sorting and searching algorithms can be applied to vectors as well as to arrays • Need slight modifications to functions to use vector arguments – vector <type> & used in prototype – No need to indicate vector size, as functions can use size member function to calculate 9-431
  • 432. 9.6 Introduction to Analysis of Algorithms • Given two algorithms to solve a problem, what makes one better than the other? • Efficiency of an algorithm is measured by – space (computer memory used) – time (how long to execute the algorithm) • Analysis of algorithms is a more effective way to find efficiency than by using empirical data 9-432
  • 433. Analysis of Algorithms: Terminology • Computational Problem: a problem solved by an algorithm • Basic step: an operation in the algorithm that executes in a constant amount of time • Examples of basic steps: – exchange the contents of two variables – compare two values 9-433
  • 434. Analysis of Algorithms: Terminology • Complexity of an algorithm: the number of basic steps required to execute the algorithm for an input of size N (N = number of input values) • Worst-case complexity of an algorithm: the number of basic steps for input of size N that requires the most work • Average case complexity function: the complexity for typical, average inputs of size N 9-434
  • 435. Complexity Example Analysis: Lines 1 and 2 execute once. The test in line 3 executes n times. The test in line 4 executes n times. The assignment in line 6 executes at most n times. Due to lines 3 and 4, the algorithm requires execution time proportional to n. 9-435 Find the largest value in array A of size n 1. biggest = A[0] 2. indx = 0 3. while (indx < n) do 4. if (A[n] > biggest) 5. then 6. biggest = A[n] 7. end if 8. end while
  • 436. Comparison of Algorithmic Complexity Given algorithms F and G with complexity functions f(n) and g(n) for input of size n • If the ratio approaches a constant value as n gets large, F and G have equivalent efficiency • If the ratio gets larger as n gets large, algorithm G is more efficient than algorithm F • If the ratio approaches 0 as n gets large, algorithm F is more efficient than algorithm G 9-436 ) ( ) ( n g n f ) ( ) ( n g n f ) ( ) ( n g n f
  • 437. "Big O" Notation • Function f(n) is O(g(n)) (“f is big O of g") for some mathematical function g(n) if the ratio approaches a positive constant as n gets large • O(g(n)) defines a complexity class for the function f(n) and for the algorithm F • Increasing complexity classes means faster rate of growth and less efficient algorithms 9-437 ) ( ) ( n g n f
  • 439. Topics 10.1 Pointers and the Address Operator 10.2 Pointer Variables 10.3 The Relationship Between Arrays and Pointers 10.4 Pointer Arithmetic 10.5 Initializing Pointers 10.6 Comparing Pointers 10-439
  • 440. Topics (continued) 10.7 Pointers as Function Parameters 10.8 Pointers to Constants and Constant Pointers 10.9 Dynamic Memory Allocation 10.10 Returning Pointers from Functions 10.11 Pointers to Class Objects and Structures 10.12 Selecting Members of Objects 10-440
  • 441. 10.1 Pointers and the Address Operator • Each variable in a program is stored at a unique location in memory that has an address • Use the address operator & to get the address of a variable: int num = -23; cout << &num; // prints address // in hexadecimal • The address of a memory location is a pointer 10-441
  • 442. 10.2 Pointer Variables • Pointer variable (pointer): a variable that holds an address • Pointers provide an alternate way to access memory locations 10-442
  • 443. Pointer Variables • Definition: int *intptr; • Read as: “intptr can hold the address of an int” or “the variable that intptr points to has type int” • The spacing in the definition does not matter: int * intptr; int* intptr; • * is called the indirection operator 10-443
  • 444. Pointer Variables • Assignment: int num = 25; int *intptr; intptr = &num; • Memory layout: • Can access num using intptr and indirection operator *: cout << intptr; // prints 0x4a00 cout << *intptr; // prints 25 *intptr = 20; // puts 20 in num 10-444 num intptr 25 0x4a00 address of num: 0x4a00
  • 445. 10.3 The Relationship Between Arrays and Pointers An array name is the starting address of the array int vals[] = {4, 7, 11}; cout << vals; // displays 0x4a00 cout << vals[0]; // displays 4 10-445 4 7 11 starting address of vals: 0x4a00
  • 446. The Relationship Between Arrays and Pointers • An array name can be used as a pointer constant int vals[] = {4, 7, 11}; cout << *vals; // displays 4 • A pointer can be used as an array name int *valptr = vals; cout << valptr[1]; // displays 7 10-446
  • 447. Pointers in Expressions • Given: int vals[]={4,7,11}; int *valptr = vals; • What is valptr + 1? • It means (address in valptr) + (1 * size of an int) cout << *(valptr+1); // displays 7 cout << *(valptr+2); // displays 11 • Must use ( ) in expression 10-447
  • 448. Array Access Array elements can be accessed in many ways 10-448 Array access method Example array name and [ ] vals[2] = 17; pointer to array and [ ] valptr[2] = 17; array name and subscript arithmetic *(vals+2) = 17; pointer to array and subscript arithmetic *(valptr+2) = 17;
  • 449. Array Access • Array notation vals[i] is equivalent to the pointer notation *(vals + i) • No bounds checking is performed on array access 10-449
  • 450. 10.4 Pointer Arithmetic Some arithmetic operators can be used with pointers: – Increment and decrement operators ++, -- – Integers can be added to or subtracted from pointers using the operators +, -, +=, and -= – One pointer can be subtracted from another by using the subtraction operator - 10-450
  • 451. Pointer Arithmetic Assume the variable definitions int vals[]={4,7,11}; int *valptr = vals; Examples of use of ++ and -- valptr++; // points at 7 valptr--; // now points at 4 10-451
  • 452. 10-452 More on Pointer Arithmetic Assume the variable definitions: int vals[]={4,7,11}; int *valptr = vals; Example of the use of + to add an int to a pointer: cout << *(valptr + 2) This statement will print 11
  • 453. 10-453 Assume the variable definitions: int vals[]={4,7,11}; int *valptr = vals; Example of use of +=: valptr = vals; // points at 4 valptr += 2; // points at 11 More on Pointer Arithmetic
  • 454. 10-454 More on Pointer Arithmetic Assume the variable definitions int vals[] = {4,7,11}; int *valptr = vals; Example of pointer subtraction valptr += 2; cout << valptr - val; This statement prints 2: the number of ints between valptr and val
  • 455. 10.5 Initializing Pointers • Can initialize to NULL or 0 (zero) int *ptr = NULL; • Can initialize to addresses of other variables int num, *numPtr = &num; int val[ISIZE], *valptr = val; • Initial value must have correct type float cost; int *ptr = &cost; // won't work 10-455
  • 456. 10.6 Comparing Pointers • Relational operators can be used to compare addresses in pointers • Comparing addresses in pointers is not the same as comparing contents pointed at by pointers: if (ptr1 == ptr2) // compares // addresses if (*ptr1 == *ptr2) // compares // contents 10-456
  • 457. 10.7 Pointers as Function Parameters • A pointer can be a parameter • It works like a reference parameter to allow changes to argument from within a function • A pointer parameter must be explicitly dereferenced to access the contents at that address 10-457
  • 458. Pointers as Function Parameters Requires: 1) asterisk * on parameter in prototype and heading void getNum(int *ptr); 2) asterisk * in body to dereference the pointer cin >> *ptr; 3) address as argument to the function in the call getNum(&num); 10-458
  • 459. Pointers as Function Parameters void swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; } int num1 = 2, num2 = -3; swap(&num1, &num2); //call 10-459
  • 460. 10.8 Ponters to Constants and Constant Pointers • Pointer to a constant: cannot change the value that is pointed at • Constant pointer: the address in the pointer cannot change after the pointer is initialized 10-460
  • 461. Ponters to Constant • Must use const keyword in pointer definition: const double taxRates[] = {0.65, 0.8, 0.75}; const double *ratePtr; • Use const keyword for pointers in function headers to protect data from modification from within function 10-461
  • 462. Pointer to Constant – What does the Definition Mean? 10-462 Read as: “rates is a pointer to a constant that is a double.”
  • 463. Constant Pointers • Defined with const keyword adjacent to variable name: int classSize = 24; int * const classPtr = &classSize; • Must be initialized when defined • Can be used without initialization as a function parameter – Initialized by argument when function is called – Function can receive different arguments on different calls • While the address in the pointer cannot change, the data at that address may be changed 10-463
  • 464. Constant Pointer – What does the Definition Mean? 10-464 Read as: “pts is a constant pointer to an int.”
  • 465. Constant Pointer to Constant • Can combine pointer to constants and constant pointers: int size = 10; const int * const ptr = &size; • What does it mean? 10-465
  • 466. 10.9 Dynamic Memory Allocation • Can allocate storage for a variable while program is running • Uses new operator to allocate memory double *dptr; dptr = new double; • new returns address of memory location 10-466
  • 467. Dynamic Memory Allocation • Can also use new to allocate array arrayPtr = new double[25]; – Program may terminate if there is not sufficient memory • Can then use [ ] or pointer arithmetic to access array 10-467
  • 468. Dynamic Memory Example int *count, *arrayptr; count = new int; cout <<"How many students? "; cin >> *count; arrayptr = new int[*count]; for (int i=0; i<*count; i++) { cout << "Enter score " << i << ": "; cin >> arrayptr[i]; } 10-468
  • 469. Releasing Dynamic Memory • Use delete to free dynamic memory delete count; • Use delete [] to free dynamic array memory delete [] arrayptr; • Only use delete with dynamic memory! 10-469
  • 470. Dangling Pointers and Memory Leaks • A pointer is dangling if it contains the address of memory that has been freed by a call to delete. – Solution: set such pointers to 0 as soon as memory is freed. • A memory leak occurs if no-longer-needed dynamic memory is not freed. The memory is unavailable for reuse within the program. – Solution: free up dynamic memory after use 10-470
  • 471. 10.10 Returning Pointers from Functions • Pointer can be return type of function int* newNum(); • The function must not return a pointer to a local variable in the function • The function should only return a pointer – to data that was passed to the function as an argument – to dynamically allocated memory 10-471
  • 472. 10.11 Pointers to Class Objects and Structures • Can create pointers to objects and structure variables struct Student {…}; class Square {…}; Student stu1; Student *stuPtr = &stu1; Square sq1[4]; Square *squarePtr = &sq1[0]; • Need to use() when using * and . operators (*stuPtr).studentID = 12204; 10-472
  • 473. Structure Pointer Operator • Simpler notation than (*ptr).member • Use the form ptr->member: stuPtr->studentID = 12204; squarePtr->setSide(14); in place of the form (*ptr).member: (*stuPtr).studentID = 12204; (*squarePtr).setSide(14); 10-473
  • 474. Dynamic Memory with Objects • Can allocate dynamic structure variables and objects using pointers: stuPtr = new Student; • Can pass values to constructor: squarePtr = new Square(17); • delete causes destructor to be invoked: delete squarePtr; 10-474
  • 475. Structure/Object Pointers as Function Parameters • Pointers to structures or objects can be passed as parameters to functions • Such pointers provide a pass-by-reference parameter mechanism • Pointers must be dereferenced in the function to access the member fields 10-475
  • 476. Controlling Memory Leaks • Memory that is allocated with new should be deallocated with a call to delete as soon as the memory is no longer needed. This is best done in the same function as the one that allocated the memory. • For dynamically-created objects, new should be used in the constructor and delete should be used in the destructor 10-476
  • 477. 10.12 Selecting Members of Objects Situation: A structure/object contains a pointer as a member. There is also a pointer to the structure/ object. Problem: How do we access the pointer member via the structure/object pointer? struct GradeList { string courseNum; int * grades; } GradeList test1, *testPtr = &test1; 10-477
  • 478. Selecting Members of Objects 10-478 Expression Meaning testPtr->grades Access the grades pointer in test1. This is the same as (*testPtr).grades *testPtr->grades Access the value pointed at by testPtr->grades. This is the same as *(*testPtr).grades *test1.grades Access the value pointed at by test1.grades
  • 479. Chapter 11: More About Classes and Object-Oriented Programming
  • 480. Topics 11.1 The this Pointer and Constant Member Functions 11.2 Static Members 11.3 Friends of Classes 11.4 Memberwise Assignment 11.5 Copy Constructors 11.6 Operator Overloading 11.7 Type Conversion Operators 11-480
  • 481. Topics (continued) 11.8 Convert Constructors 11.9 Aggregation and Composition 11.10 Inheritance 11.11 Protected Members and Class Access 11.12 Constructors, Destructors, and Inheritance 11.13 Overriding Base Class Functions 11-481
  • 482. 11.1 The this Pointer and Constant Member Functions • this pointer: - Implicit parameter passed to a member function - points to the object calling the function • const member function: - does not modify its calling object 11-482
  • 483. Using the this Pointer Can be used to access members that may be hidden by parameters with the same name: class SomeClass { private: int num; public: void setNum(int num) { this->num = num; } }; 11-483
  • 484. Constant Member Functions • Declared with keyword const • When const appears in the parameter list, int setNum (const int num) the function is prevented from modifying the parameter. The parameter is read-only. • When const follows the parameter list, int getX()const the function is prevented from modifying the object. 11-484
  • 485. 11.2 Static Members • Static member variable: – One instance of variable for the entire class – Shared by all objects of the class • Static member function: – Can be used to access static member variables – Can be called before any class objects are created 11-485
  • 486. Static Member Variables 1) Must be declared in class with keyword static: class IntVal { public: intVal(int val = 0) { value = val; valCount++ } int getVal(); void setVal(int); private: int value; static int valCount; }; 11-486
  • 487. Static Member Variables 2) Must be defined outside of the class: class IntVal { //In-class declaration static int valCount; //Other members not shown }; //Definition outside of class int IntVal::valCount = 0; 11-487
  • 488. Static Member Variables 3) Can be accessed or modified by any object of the class: Modifications by one object are visible to all objects of the class: IntVal val1, val2; 11-488 valCount val1 val2 2
  • 489. Static Member Functions 1)Declared with static before return type: class IntVal { public: static int getValCount() { return valCount; } private: int value; static int valCount; }; 11-489
  • 490. Static Member Functions 2) Can be called independently of class objects, through the class name: cout << IntVal::getValCount(); 3) Because of item 2 above, the this pointer cannot be used 4) Can be called before any objects of the class have been created 5) Used primarily to manipulate static member variables of the class 11-490
  • 491. 11.3 Friends of Classes • Friend function: a function that is not a member of a class, but has access to private members of the class • A friend function can be a stand-alone function or a member function of another class • It is declared a friend of a class with the friend keyword in the function prototype 11-491
  • 492. Friend Function Declarations 1) Friend function may be a stand-alone function: class aClass { private: int x; friend void fSet(aClass &c, int a); }; void fSet(aClass &c, int a) { c.x = a; } 11-492
  • 493. Friend Function Declarations 2) Friend function may be a member of another class: class aClass { private: int x; friend void OtherClass::fSet (aClass &c, int a); }; class OtherClass { public: void fSet(aClass &c, int a) { c.x = a; } }; 11-493
  • 494. Friend Class Declaration 3) An entire class can be declared a friend of a class: class aClass {private: int x; friend class frClass; }; class frClass {public: void fSet(aClass &c,int a){c.x = a;} int fGet(aClass c){return c.x;} }; 11-494
  • 495. Friend Class Declaration • If frClass is a friend of aClass, then all member functions of frClass have unrestricted access to all members of aClass, including the private members. • In general, restrict the property of Friendship to only those functions that must have access to the private members of a class. 11-495
  • 496. 11.4 Memberwise Assignment • Can use = to assign one object to another, or to initialize an object with an object’s data • Examples (assuming class V): V v1, v2; … // statements that assign … // values to members of v1 v2 = v1; // assignment V v3 = v2; // initialization 11-496
  • 497. 11.5 Copy Constructors • Special constructor used when a newly created object is initialized to the data of another object of same class • Default copy constructor copies field-to- field, using memberwise assignment • The default copy constructor works fine in most cases 11-497
  • 498. Copy Constructors Problems occur when objects contain pointers to dynamic storage: class CpClass { private: int *p; public: CpClass(int v=0) { p = new int; *p = v;} ~CpClass(){delete p;} }; 11-498
  • 499. Default Constructor Causes Sharing of Storage CpClass c1(5); if (true) { CpClass c2=c1; } // c1 is corrupted // when c2 goes // out of scope and // its destructor // executes 11-499 c1 c2 5
  • 500. Problems of Sharing Dynamic Storage • Destructor of one object deletes memory still in use by other objects • Modification of memory by one object affects other objects sharing that memory 11-500
  • 501. Programmer-Defined Copy Constructors • A copy constructor is one that takes a reference parameter to another object of the same class • The copy constructor uses the data in the object passed as parameter to initialize the object being created • Reference parameter should be const to avoid potential for data corruption 11-501
  • 502. Programmer-Defined Copy Constructors • The copy constructor avoids problems caused by memory sharing • Can allocate separate memory to hold new object’s dynamic member data • Can make new object’s pointer point to this memory • Copies the data, not the pointer, from the original object to the new object 11-502
  • 503. Copy Constructor Example class CpClass { int *p; public: CpClass(const CpClass &obj) { p = new int; *p = *obj.p; } CpClass(int v=0) { p = new int; *p = v; } ~CpClass(){delete p;} }; 11-503
  • 504. Copy Constructor – When Is It Used? A copy constructor is called when • An object is initialized from an object of the same class • An object is passed by value to a function • An object is returned using a return statement from a function 11-504
  • 505. 11.6 Operator Overloading • Operators such as =, +, and others can be redefined for use with objects of a class • The name of the function for the overloaded operator is operator followed by the operator symbol, e.g., operator+ is the overloaded + operator and operator= is the overloaded = operator 11-505
  • 506. Operator Overloading • Operators can be overloaded as - instance member functions, or as - friend functions • The overloaded operator must have the same number of parameters as the standard version. For example, operator= must have two parameters, since the standard = operator takes two parameters. 11-506
  • 507. Overloading Operators as Instance Members A binary operator that is overloaded as an instance member needs only one parameter, which represents the operand on the right: class OpClass { private: int x; public: OpClass operator+(OpClass right); }; 11-507
  • 508. Overloading Operators as Instance Members • The left operand of the overloaded binary operator is the calling object • The implicit left parameter is accessed through the this pointer OpClass OpClass::operator+(OpClass r) { OpClass sum; sum.x = this->x + r.x; return sum; } 11-508
  • 509. Invoking an Overloaded Operator • Operator can be invoked as a member function: OpClass a, b, s; s = a.operator+(b); • It can also be invoked in the more conventional manner: OpClass a, b, s; s = a + b; 11-509
  • 510. Overloading Assignment • Overloading the assignment operator solves problems with object assignment when an object contains pointer to dynamic memory. • Assignment operator is most naturally overloaded as an instance member function • It needs to return a value of the assigned object to allow cascaded assignments such as a = b = c; 11-510
  • 511. Overloading Assignment Assignment overloaded as a member function: class CpClass { int *p; public: CpClass(int v=0) { p = new int; *p = v; ~CpClass(){delete p;} CpClass operator=(CpClass); }; 11-511
  • 512. Overloading Assignment Implementation returns a value: CpClass CpClass::operator=(CpClass r) { *p = *r.p; return *this; }; Invoking the assignment operator: CpClass a, x(45); a.operator=(x); // either of these a = x; // lines can be used 11-512
  • 513. Notes on Overloaded Operators • Overloading can change the entire meaning of an operator • Most operators can be overloaded • Cannot change the number of operands of the operator • Cannot overload the following operators: ?: . .* sizeof 11-513
  • 514. Overloading Types of Operators • ++, -- operators overloaded differently for prefix vs. postfix notation • Overloaded relational operators should return a bool value • Overloaded stream operators >>, << must return istream, ostream objects and take istream, ostream objects as parameters 11-514
  • 515. Overloaded [] Operator • Can be used to create classes that behave like arrays, providing bounds- checking on subscripts • Overloaded [] returns a reference to object, not an object itself 11-515
  • 516. 11.7 Type Conversion Operators • Conversion Operators are member functions that tell the compiler how to convert an object of the class type to a value of another type • The conversion information provided by the conversion operators is automatically used by the compiler in assignments, initializations, and parameter passing 11-516
  • 517. Syntax of Conversion Operators • Conversion operator must be a member function of the class you are converting from • The name of the operator is the name of the type you are converting to • The operator does not specify a return type 11-517
  • 518. Conversion Operator Example • To convert from a class IntVal to an integer: class IntVal { int x; public: IntVal(int a = 0){x = a;} operator int(){return x;} }; • Automatic conversion during assignment: IntVal obj(15); int i; i = obj; cout << i; // prints 15 11-518
  • 519. 11.8 Convert Constructors Convert constructors are constructors that take a single parameter of a type other than the class in which they are defined class CCClass { int x; public: CCClass() //default CCClass(int a, int b); CCClass(int a); //convert CCClass(string s); //convert }; 11-519
  • 520. Example of a Convert Constructor The C++ string class has a convert constructor that converts from C-strings: class string { public: string(char *); //convert … }; 11-520
  • 521. Uses of Convert Constructors • They are automatically invoked by the compiler to create an object from the value passed as parameter: string s("hello"); //convert C-string CCClass obj(24); //convert int • The compiler allows convert constructors to be invoked with assignment-like notation: string s = "hello"; //convert C-string CCClass obj = 24; //convert int 11-521
  • 522. Uses of Convert Constructors • Convert constructors allow functions that take the class type as parameter to take parameters of other types: void myFun(string s); // needs string // object myFun("hello"); // accepts C-string void myFun(CCClass c); myFun(34); // accepts int 11-522
  • 523. 11.9 Aggregation and Composition • Class aggregation: An object of one class owns an object of another class • Class composition: A form of aggregation where the enclosing class controls the lifetime of the objects of the enclosed class • Supports the modeling of ‘has-a’ relationship between classes – enclosing class ‘has a(n)’ instance of the enclosed class 11-523
  • 524. Object Composition class StudentInfo { private: string firstName, LastName; string address, city, state, zip; ... }; class Student { private: StudentInfo personalData; ... }; 11-524
  • 525. Member Initialization Lists • Used in constructors for classes involved in aggregation. • Allows constructor for enclosing class to pass arguments to the constructor of the enclosed class • Notation: owner_class(parameters):owned_class(parameters); 11-525
  • 526. Member Initialization Lists Use: class StudentInfo { ... }; class Student { private: StudentInfo personalData; public: Student(string fname, lname): StudentInfo(fname, lname); }; 11-526
  • 527. Member Initialization Lists • Member Initialization lists can be used to simplify the coding of constructors • Should keep the entries in the initialization list in the same order as they are declared in the class 11-527
  • 528. Aggregation Through Pointers • A ‘has-a’ relationship can be implemented by owning a pointer to an object • Can be used when multiple objects of a class may ‘have’ the same attribute for a member – ex: students who may have the same city/state/ zipcode • Using pointers minimizes data duplication and saves space 11-528
  • 529. Aggregation, Composition, and Object Lifetimes • Aggregation represents the owner/owned relationship between objects. • Composition is a form of aggregation in which the lifetime of the owned object is the same as that of the owner object • Owned object is usually created as part of the owning object’s constructor, destroyed as part of owning object’s destructor 11-529
  • 530. 11.10 Inheritance • Inheritance is a way of creating a new class by starting with an existing class and adding new members • The new class can replace or extend the functionality of the existing class • Inheritance models the 'is-a' relationship between classes 11-530
  • 531. Inheritance - Terminology • The existing class is called the base class – Alternates: parent class, superclass • The new class is called the derived class – Alternates: child class, subclass 11-531
  • 532. Inheritance Syntax and Notation // Existing class class Base { }; // Derived class class Derived : public Base { }; Inheritance Class Diagram 11-532 Base Class Derived Class
  • 533. Inheritance of Members class Parent { int a; void bf(); }; class Child : public Parent { int c; void df(); }; Objects of Parent have members int a; void bf(); Objects of Child have members int a; void bf(); int c; void df(); 11-533
  • 534. 11.11 Protected Members and Class Access • protected member access specification: A class member labeled protected is accessible to member functions of derived classes as well as to member functions of the same class • Like private, except accessible to members functions of derived classes 11-534
  • 535. Base Class Access Specification Base class access specification determines how private, protected, and public members of base class can be accessed by derived classes 11-535
  • 536. Base Class Access C++ supports three inheritance modes, also called base class access modes: - public inheritance class Child : public Parent { }; - protected inheritance class Child : protected Parent{ }; - private inheritance class Child : private Parent{ }; 11-536
  • 537. Base Class Access vs. Member Access Specification Base class access is not the same as member access specification: – Base class access: determine access for inherited members – Member access specification: determine access for members defined in the class 11-537
  • 538. Member Access Specification Specified using the keywords private, protected, public class MyClass { private: int a; protected: int b; void fun(); public: void fun2(); }; 11-538
  • 539. Base Class Access Specification class Child : public Parent { protected: int a; public: Child(); }; 11-539 member access base access
  • 540. Base Class Access Specifiers 1) public – object of derived class can be treated as object of base class (not vice- versa) 2) protected – more restrictive than public, but allows derived classes to know some of the details of parents 3) private – prevents objects of derived class from being treated as objects of base class. 11-540
  • 541. Effect of Base Access 11-541 private: x protected: y public: z private: x protected: y public: z private: x protected: y public: z Base class members x inaccessible private: y private: z x inaccessible protected: y protected: z x inaccessible protected: y public: z How base class members appear in derived class private base class protected base class public base class
  • 542. 11.12 Constructors,Destructors and Inheritance • By inheriting every member of the base class, a derived class object contains a base class object • The derived class constructor can specify which base class constructor should be used to initialize the base class object 11-542
  • 543. Order of Execution • When an object of a derived class is created, the base class’s constructor is executed first, followed by the derived class’s constructor • When an object of a derived class is destroyed, its destructor is called first, then that of the base class 11-543
  • 544. Order of Execution // Student – base class // UnderGrad – derived class // Both have constructors, destructors int main() { UnderGrad u1; ... return 0; }// end main 11-544 Execute Student constructor, then execute UnderGrad constructor Execute UnderGrad destructor, then execute Student destructor
  • 545. Passing Arguments to Base Class Constructor • Allows selection between multiple base class constructors • Specify arguments to base constructor on derived constructor heading • Can also be done with inline constructors • Must be done if base class has no default constructor 11-545
  • 546. Passing Arguments to Base Class Constructor class Parent { int x, y; public: Parent(int,int); }; class Child : public Parent { int z public: Child(int a): Parent(a,a*a) {z = a;} }; 11-546
  • 547. 11.13 Overriding Base Class Functions • Overriding: function in a derived class that has the same name and parameter list as a function in the base class • Typically used to replace a function in base class with different actions in derived class • Not the same as overloading – with overloading, the parameter lists must be different 11-547
  • 548. Access to Overridden Function • When a function is overridden, all objects of derived class use the overriding function. • If necessary to access the overridden version of the function, it can be done using the scope resolution operator with the name of the base class and the name of the function: Student::getName(); 11-548
  • 549. Chapter 12: More on C-Strings and the string Class
  • 550. Topics 12.1 C-Strings 12.2 Library Functions for Working with C-Strings 12.3 Conversions Between Numbers and Strings 12.4 Writing Your Own C-String Handling Functions 12.5 More About the C++ string Class 12.6 Creating Your Own String Class 12-550
  • 551. 12.1 C-Strings • C-string: sequence of characters stored in adjacent memory locations and terminated by NULL character • The C-string "Hi there!" would be stored in memory as shown: 12-551 H i t h e r e ! 0
  • 552. What is NULL? • The null character is used to indicate the end of a string • It can be specified as – the character '0' – the int value 0 – the named constant NULL 12-552
  • 553. Representation of C-strings As a string literal "Hi There!" As a pointer to char char *p; As an array of characters char str[20]; All three representations are pointers to char 12-553
  • 554. String Literals • A string literal is stored as a null-terminated array of char • Compiler uses the address of the first character of the array as the value of the string • String literal is a pointer to char 12-554 h i 0 value of "hi" is the address of this array
  • 555. Array of char • An array of char can be defined and initialized to a C-string char str1[20] = "hi"; • An array of char can be defined and later have a string copied into it using strcpy or cin.getline char str2[20], str3[20]; strcpy(str2, "hi"); cout << "Enter your name: "; cin.getline(str3, 20); 12-555
  • 556. Array of char • The name of an array of char is used as a pointer to char • Unlike a string literal, a C-string defined as an array can be referred to in other parts of the program by using the array name 12-556
  • 557. Pointer to char • Defined as char *pStr; • Does not itself allocate memory • Useful in repeatedly referring to C- strings defined as a string literal pStr = "Hi there"; cout << pStr << " " << pStr; 12-557
  • 558. Pointer to char • Pointer to char can also refer to C-strings defined as arrays of char char str[20] = "hi"; char *pStr = str; cout << pStr; // prints hi • Can dynamically allocate memory to be used for C-string using new 12-558
  • 559. 12.2 Library Functions for Working with C-Strings • Require cstring header file • Functions take one or more C-strings as arguments. Argument can be: – Name of an array of char – pointer to char – string literal 12-559
  • 560. Library Functions for Working with C-Strings int strlen(char *str) Returns length of a C-string: cout << strlen("hello"); Prints: 5 Note: This is the number of characters in the string, NOT the size of the array that contains it 12-560
  • 561. strcat strcat(char *dest, char *source) • Takes two C-strings as input. It adds the contents of the second string to the end of the first string: char str1[15] = "Good "; char str2[30] = "Morning!"; strcat(str1, str2); cout << str1; // prints: Good Morning! • No automatic bounds checking: programmer must ensure that 1st string has enough room for result 12-561
  • 562. strcpy strcpy(char *dest, char *source) • Copies a string from a source address to a destination address char name[15]; strcpy(name, "Deborah"); cout << name; // prints Deborah • Again, no automatic bounds checking 12-562
  • 563. strcmp int strcmp(char *str1, char*str2) • Compares strings stored at two addresses to determine their relative alphabetic order: • Returns a value: less than 0 if str1 precedes str2 equal to 0 if str1 equals str2 greater than 0 if str1 succeeds str2 12-563
  • 564. strcmp • Often used to test for equality if(strcmp(str1, str2) == 0) cout << "equal"; else cout << "not equal"; • Also used to determine ordering of C-strings in sorting applications • Note: – Comparisons are case-sensitive: "Hi" != "hi" – C-strings cannot be compared using == (compares addresses of C-strings, not contents) 12-564
  • 565. strstr char *strstr(char *str1,char *str2) • Searches for the occurrence of str2 within str1. • Returns a pointer to the occurrence of str2 within str1 if found, and returns NULL otherwise char s[15] = "Abracadabra"; char *found = strstr(s,"dab"); cout << found; // prints dabra 12-565
  • 566. 12.3 Conversions Between Numbers and Strings • "1416" is a string; 1416 without quotes is an int • There are classes that can be used to convert between string and numeric forms of numbers • Need to include sstream header file 12-566
  • 567. Conversion Classes • istringstream: – contains a string to be converted to numeric values where necessary – Use str(s) to initialize string to contents of s – Use the stream extraction operator >> to read from the string • ostringstream: – collects a string in which numeric data is converted as necessary – Use the stream insertion operator << to add data onto the string – Use str() to retrieve converted string 12-567
  • 568. atoi and atol • atoi converts alphanumeric to int • atol converts alphanumeric to long int atoi(char *numericStr) long atol(char *numericStr) • Examples: int number; long lnumber; number = atoi("57"); lnumber = atol("50000"); 12-568
  • 569. atof • atof converts a numeric string to a floating point number, actually a double double atof(char *numericStr) • Example: double dnumber; dnumber = atof("3.14159"); 12-569
  • 570. atoi, atol, atof • if C-string being converted contains non- digits, results are undefined – function may return result of conversion up to first non-digit – function may return 0 • All functions require cstdlib 12-570
  • 571. itoa • itoa converts an int to an alphanumeric string • Allows user to specify the base of conversion itoa(int num, char *numStr, int base) • Example: To convert the number 1200 to a hexadecimal string char numStr[10]; itoa(1200, numStr, 16); • The function performs no bounds-checking on the array numStr 12-571
  • 572. 12.4 Character Testing require cctype header file FUNCTION MEANING isalpha true if arg. is a letter, false otherwise isalnum true if arg. is a letter or digit, false otherwise isdigit true if arg. is a digit 0-9, false otherwise islower true if arg. is lowercase letter, false otherwise 12-572
  • 573. 12.4 Writing Your Own C-String Handling Functions When writing C-String Handling Functions: – can pass arrays or pointers to char – can perform bounds checking to ensure enough space for results – can anticipate unexpected user input 12-573
  • 574. 12.5 More About the C++ string Class • The string class offers several advantages over C-style strings: – large body of member functions – overloaded operators to simplify expressions • Need to include the string header file 12-574
  • 575. string class constructors • Default constructor string() • Copy constructor string(string&) initializes string objects with values of other string objects • Convert constructor string(char *) initializes string objects with values of C- strings • Various other constructors 12-575
  • 576. Overloaded string Operators OPERATOR MEANING >> reads whitespace-delimited strings into string object << inserts string object into a stream = assigns string on right to string object on left += appends string on the right to the end of contents of string on left 12-576
  • 577. Overloaded string Operators (continued) OPERATOR MEANING + Returns concatenation of the two strings [] references character in string using array notation >, >=, <, <=, ==, != relational operators for string comparison. Return true or false 12-577
  • 578. Overloaded string Operators string word1, phrase; string word2 = " Dog"; cin >> word1; // user enters "Hot" // word1 has "Hot" phrase = word1 + word2; // phrase has // "Hot Dog" phrase += " on a bun"; for (int i = 0; i < 16; i++) cout << phrase[i]; // displays // "Hot Dog on a bun" 12-578
  • 579. string Member Functions Categories: – conversion to C-strings: c_str, data – modification: append, assign, clear, copy, erase, insert, replace, swap – space management: capacity, empty, length, resize, size – substrings: find, substr – comparison: compare 12-579
  • 580. Conversion to C-strings • data() and c_str() both return the C- string equivalent of a string object • Useful when using a string object with a function that is expecting a C-string char greeting[20] = "Have a "; string str("nice day"); strcat(greeting, str.data()); 12-580
  • 581. Modification of string objects • str.append(string s) appends contents of s to end of str • Convert constructor for string allows a C- string to be passed in place of s string str("Have a "); str.append("nice day"); • append is overloaded for flexibility 12-581
  • 582. Modification of string objects • str.insert(int pos, string s) inserts s at position pos in str • Convert constructor for string allows a C- string to be passed in place of s string str("Have a day"); str.insert(7, "nice "); • insert is overloaded for flexibility 12-582
  • 583. 12.6 Creating Your Own String Class • A good way to put OOP skills into practice • The class allocates dynamic memory, so has copy constructor, destructor, and overloaded assignment • Overloads the stream insertion and extraction operators, and many other operators 12-583
  • 584. Chapter 13: Advanced File and I/O Operations
  • 585. Topics 13.1 Input and Output Streams 13.2 More Detailed Error Testing 13.3 Member Functions for Reading and Writing Files 13.4 Binary Files 13.5 Creating Records with Structures 13.6 Random-Access Files 13.7 Opening a File for Both Input and Output 13-585
  • 586. 13.1 Input and Output Streams • Input Stream – data stream from which information can be read – Ex: cin and the keyboard – Use istream, ifstream, and istringstream objects to read data • Output Stream – data stream to which information can be written – Ex: cout and monitor screen – Use ostream, ofstream, and ostringstream objects to write data • Input/Output Stream – data stream that can be both read from and written to – Use fstream objects here 13-586
  • 587. File Stream Classes • ifstream (open primarily for input), ofstream (open primarily for output), and fstream (open for either or both input and output) • All have open member function to connect the program to an external file • All have close member function to disconnect program from an external file when access is finished – Files should be open for as short a time as possible – Always close files before the program ends 13-587
  • 588. File Open Modes • File open modes specify how a file is opened and what can be done with the file once it is open • ios::in and ios::out are examples of file open modes, also called file mode flag • File modes can be combined and passed as second argument of open member function 13-588
  • 589. The fstream Object • fstream object can be used for either input or output fstream file; • To use fstream for input, specify ios::in as the second argument to open file.open("myfile.dat",ios::in); • To use fstream for output, specify ios::out as the second argument to open file.open("myfile.dat",ios::out); 13-589
  • 590. File Mode Flags ios::app create new file, or append to end of existing file ios::ate go to end of existing file; write anywhere ios::binary read/write in binary mode (not text mode) ios::in open for input ios::out open for output 13-590
  • 591. Opening a File for Input and Output • fstream object can be used for both input and output at the same time • Create the fstream object and specify both ios::in and ios::out as the second argument to the open member function fstream file; file.open("myfile.dat", ios::in|ios::out); 13-591
  • 592. File Open Modes • Not all combinations of file open modes make sense • ifstream and ofstream have default file open modes defined for them, hence the second parameter to their open member function is optional 13-592
  • 593. Opening Files with Constructors • Stream constructors have overloaded versions that take the same parameters as open • These constructors open the file, eliminating the need for a separate call to open fstream inFile("myfile.dat", ios::in); 13-593
  • 594. Default File Open Modes • ofstream: – open for output only – file cannot be read from – file is created if no file exists – file contents erased if file exists • ifstream: – open for input only – file cannot be written to – open fails if the file does not exist 13-594
  • 595. Output Formatting with I/O Manipulators • Can format with I/O manipulators: they work with file objects just like they work with cout • Can format with formatting member functions • The ostringstream class allows in-memory formatting into a string object before writing to a file 13-595
  • 596. I/O Manipulators left, right left or right justify output oct, dec, hex display output in octal, decimal, or hexadecimal endl, flush write newline (endl only) and flush output showpos, noshowpos do, do not show leading + with non-negative numbers showpoint, noshowpoint do, do not show decimal point and trailing zeroes 13-596
  • 597. More I/O Manipulators fixed, scientific use fixed or scientific notation for floating-point numbers setw(n) sets minimum field output width to n setprecision(n) sets floating-point precision to n setfill(ch) uses ch as fill character 13-597
  • 598. sstream Formatting 1) To format output into an in-memory string object, include the sstream header file and create an ostringstream object #include <sstream> ostringstream outStr; 13-598
  • 599. sstream Formatting 2) Write to the ostringstream object using I/O manipulators, all other stream member functions: outStr << showpoint << fixed << setprecision(2) << '$'<< amount; 13-599
  • 600. sstream Formatting 3) Access the C-string inside the ostringstream object by calling its str member function cout << outStr.str(); 13-600
  • 601. 13.2 More Detailed Error Testing 13-601 • Stream objects have error bits (flags) that are set by every operation to indicate success or failure of the operation, and the status of the stream • Stream member functions report on the settings of the flags
  • 602. Error State Bits Can examine error state bits to determine file stream status ios::eofbit set when end of file detected ios::failbit set when operation failed ios::hardfail set when an irrecoverable error occurred ios::badbit set when invalid operation attempted ios::goodbit set when no other bits are set 13-602
  • 603. Error Bit Reporting Functions eof() true if eofbit set, false otherwise fail() true if failbit or hardfail set, false otherwise bad() true if badbit set, false otherwise good() true if goodbit set, false otherwise clear() clear all flags (no arguments), or clear a specific flag 13-603
  • 604. Detecting File Operation Errors • The file handle is set to true if a file operation succeeds. It is set to false when a file operation fails • Test the status of the stream by testing the file handle: inFile.open("myfile"); if (!inFile) { cout << "Can't open file"; exit(1); } 13-604
  • 605. 13.3 Member Functions for Reading and Writing Files Unlike the extraction operator >>, these reading functions do not skip whitespace: getline: read a line of input get: reads a single character seekg: goes to beginning of input file 13-605
  • 606. getline Member Function getline(char s[ ], int max, char stop ='n') – char s[ ]: Character array to hold input – int max : 1 more than the maximum number of characters to read – char stop: Terminator to stop at if encountered before max number of characters is read . Optional, default is 'n' 13-606
  • 607. Single Character Input get(char &ch) Read a single character from the input stream and put it in ch. Does not skip whitespace. ifstream inFile; char ch; inFile.open("myFile"); inFile.get(ch); cout << "Got " << ch; 13-607
  • 608. Single Character Input, Again get() Read a single character from the input stream and return the character. Does not skip whitespace. ifstream inFile; char ch; inFile.open("myFile"); ch = inFile.get(); cout << "Got " << ch; 13-608
  • 609. Single Character Input, with a Difference peek() Read a single character from the input stream but do not remove the character from the input stream. Does not skip whitespace. ifstream inFile; char ch; inFile.open("myFile"); ch = inFile.peek(); cout << "Got " << ch; ch = inFile.peek(); cout << "Got " << ch;//same output 13-609
  • 610. Single Character Output • put(char ch) Output a character to a file • Example ofstream outFile; outFile.open("myfile"); outFile.put('G'); 13-610
  • 611. Moving About in Input Files seekg(offset, place) Move to a given offset relative to a given place in the file – offset: number of bytes from place, specified as a long – place: location in file from which to compute offset ios::beg: beginning of file ios::end: end of the file ios::cur: current position in file 13-611
  • 612. Example of Single Character I/O To copy an input file to an output file char ch; infile.get(ch); while (!infile.fail()) { outfile.put(ch); infile.get(ch); } infile.close(); outfile.close(); 13-612
  • 613. Rewinding a File • To move to the beginning of file, seek to an offset of zero from beginning of file inFile.seekg(0L, ios::beg); • Error or eof bits will block seeking to the beginning of file. Clear bits first: inFile.clear(); inFile.seekg(0L, ios::beg); 13-613
  • 614. 13.4 Binary Files • Binary files store data in the same format that a computer has in main memory • Text files store data in which numeric values have been converted into strings of ASCII characters • Files are opened in text mode (as text files) by default 13-614
  • 615. Using Binary Files • Pass the ios::binary flag to the open member function to open a file in binary mode infile.open("myfile.dat",ios::binary); • Reading and writing of binary files requires special read and write member functions read(char *buffer, int numberBytes) write(char *buffer, int numberBytes) 13-615
  • 616. Using read and write read(char *buffer, int numberBytes) write(char *buffer, int numberBytes) • buffer: holds an array of bytes to transfer between memory and the file • numberBytes: the number of bytes to transfer Address of the buffer needs to be cast to char * using reinterpret_cast <char *> 13-616
  • 617. Using write To write an array of 2 doubles to a binary file ofstream outFile("myfile",ios:binary); double d[2] = {12.3, 34.5}; outFile.write( reinterpret_cast<char *>(d),sizeof(d)); 13-617
  • 618. Using read To read two 2 doubles from a binary file into an array ifstream inFile("myfile", ios:binary); const int DSIZE = 10; double data[DSIZE]; inFile.read( reinterpret_cast<char *>(data), 2*sizeof(double)); // only data[0] and data[1] contain // values 13-618
  • 619. 13.5 Creating Records with Structures • Can write structures to, read structures from files • To work with structures and files, – use binary file flag upon open – use read, write member functions 13-619
  • 620. Creating Records with Structures struct TestScore { int studentId; float score; char grade; }; TestScore test1[20]; ... // write out test1 array to a file gradeFile.write( reinterpret_cast<char*>(test1), sizeof(test1)); 13-620
  • 621. Notes on Structures Written to Files • Structures to be written to a file must not contain pointers • Since string objects use pointers and dynamic memory internally, structures to be written to a file must not contain any string objects 13-621
  • 622. 13.6 Random-Access Files • Sequential access: start at beginning of file and go through data the in file, in order, to the end of the file – to access 100th entry in file, go through 99 preceding entries first • Random access: access data in a file in any order – can access 100th entry directly 13-622
  • 623. Random Access Member Functions • seekg (seek get): used with input files • seekp (seek put): used with output files Both are used to go to a specific position in a file 13-623
  • 624. Random Access Member Functions seekg(offset,place) seekp(offset,place) offset:long integer specifying number of bytes to move place: starting point for the move, specified by ios:beg, ios::cur or ios:end 13-624
  • 625. Random-Access Member Functions • Examples: // Set read position 25 bytes // after beginning of file inData.seekg(25L, ios::beg); // Set write position 10 bytes // before current position outData.seekp(-10L, ios::cur); 13-625
  • 626. Random Access Information • tellg member function: return current byte position in input file, as a long long whereAmI; whereAmI = inFile.tellg(); • tellp member function: return current byte position in output file, as a long whereAmI = outFile.tellp(); 13-626
  • 627. 13.7 Opening a File for Both Input and Output • A file can be open for input and output simultaneously • Supports updating a file: – read data from file into memory – update data – write data back to file • Use fstream for file object definition: fstream gradeList("grades.dat", ios::in | ios::out); 13-627
  • 629. Topics 14.1 Introduction to Recursion 14.2 The Recursive Factorial Function 14.3 The Recursive gcd Function 14.4 Solving Recursively Defined Problems 14.5 A Recursive Binary Search Function 14.6 The QuickSort Algorithm 14.7 The Towers of Hanoi 14.8 Exhaustive and Enumeration Algorithms 14.9 Recursion Versus Iteration 14-629
  • 630. 14.1 Introduction to Recursion • A recursive function is a function that calls itself. • Recursive functions can be useful in solving problems that can be broken down into smaller or simpler subproblems of the same type. A base case should eventually be reached, at which time the breaking down (recursion) will stop. 14-630
  • 631. Recursive Functions Consider a function for solving the count-down problem from some number num down to 0: – The base case is when num is already 0: the problem is solved and we “blast off!” – If num is greater than 0, we count off num and then recursively count down from num-1 14-631
  • 632. Recursive Functions A recursive function for counting down to 0: void countDown(int num) { if (num == 0) cout << "Blastoff!"; else { cout << num << ". . ."; countDown(num-1); // recursive } // call } 14-632
  • 633. What Happens When Called? If a program contains a line like countDown(2); 1. countDown(2) generates the output 2..., then it calls countDown(1) 2. countDown(1) generates the output 1..., then it calls countDown(0) 3. countDown(0) generates the output Blastoff!, then returns to countDown(1) 4. countDown(1) returns to countDown(2) 5. countDown(2)returns to the calling function 14-633
  • 634. What Happens When Called? 14-634 third call to countDown num is 0 countDown(1); countDown(0); // no // recursive // call second call to countDown num is 1 first call to countDown num is 2 OUTPUT: 2... 1... Blastoff!
  • 635. Stopping the Recursion • A recursive function should include a test for the base cases • In the sample program, the test is: if (num == 0) 14-635
  • 636. Stopping the Recursion void countDown(int num) { if (num == 0) // test cout << "Blastoff!"; else { cout << num << "...n"; countDown(num-1); // recursive } // call } 14-636
  • 637. Stopping the Recursion • With each recursive call, the parameter controlling the recursion should move closer to the base case • Eventually, the parameter reaches the base case and the chain of recursive calls terminates 14-637
  • 638. Stopping the Recursion void countDown(int num) { if (num == 0) // base case cout << "Blastoff!"; else { cout << num << "...n"; countDown(num-1); } } 14-638 Value passed to recursive call is closer to base case of num = 0.
  • 639. What Happens When Called? • Each time a recursive function is called, a new copy of the function runs, with new instances of parameters and local variables being created • As each copy finishes executing, it returns to the copy of the function that called it • When the initial copy finishes executing, it returns to the part of the program that made the initial call to the function 14-639
  • 640. Types of Recursion • Direct recursion – a function calls itself • Indirect recursion – function A calls function B, and function B calls function A. Or, – function A calls function B, which calls …, which then calls function A 14-640
  • 641. 14.2 The Recursive Factorial Function • The factorial of a nonnegative integer n is the product of all positive integers less or equal to n • The factorial of n is denoted by n! • The factorial of 0 is 1 0 ! = 1 n ! = n x (n-1) x … x 2 x 1 if n > 0 14-641
  • 642. Recursive Factorial Function • Factorial of n can be expressed in terms of the factorial of n-1 0 ! = 1 n ! = n x (n-1) ! • Recursive function int factorial(int n) { if (n == 0) return 1; else return n *factorial(n-1); } 14-642
  • 643. 14.3 The Recursive gcd Function • Greatest common divisor (gcd) of two integers x and y is the largest number that divides both x and y • The Greek mathematician Euclid discovered that – If y divides x, then gcd(x, y) is just y – Otherwise, the gcd(x, y) is the gcd of y and the remainder of dividing x by y 14-643
  • 644. The Recursive gcd Function int gcd(int x, int y) { if (x % y == 0) //base case return y; else return gcd(y, x % y); } 14-644
  • 645. 14.4 Solving Recursively Defined Problems • The natural definition of some problems leads to a recursive solution • Example: Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, ... • After the initial 0 and 1, each term is the sum of the two preceding terms • Recursive calculation of the nth Fibonacci number: fib(n) = fib(n – 1) + fib(n – 2); • Base cases: n == 0, n == 1 14-645
  • 646. Recursive Fibonacci Function int fib(int n) { if (n <= 0) // base case return 0; else if (n == 1) // base case return 1; else return fib(n – 1) + fib(n – 2); } 14-646
  • 647. 14.5 A Recursive Binary Search Function • Assume an array a that is sorted in ascending order, and an item X to search for • We want to write a function that searches for X within the array a, returning the index of X if it is found, and returning -1 if X is not in the array 14-647
  • 648. Recursive Binary Search A recursive strategy for searching a portion of the array from index lo to index hi is to set m to the index of the middle element of the array: 14-648 m lo hi
  • 649. Recursive Binary Search If a[m] == X, we found X, so return m If a[m] > X, recursively search a[lo..m-1] If a[m] < X, recursively search a[m+1..hi] 14-649 m lo hi
  • 650. Recursive Binary Search int bSearch(int a[],int lo,int hi,int X) { int m = (lo + hi) /2; if(lo > hi) return -1; // base if(a[m] == X) return m; // base if(a[m] > X) return bsearch(a,lo,m-1,X); else return bsearch(a,m+1,hi,X); } 14-650
  • 651. 14.6 The QuickSort Algorithm • Recursive algorithm that can sort an array • First, determine an element to use as pivot value: 14-651 pivot sublist 1 sublist 2
  • 652. The QuickSort Algorithm • Then, values are shifted so that elements in sublist1 are < pivot and elements in sublist2 are >= pivot • Algorithm then recursively sorts sublist1 and sublist2 • Base case: a sublist has size <=1 14-652 pivot value sublist 1 sublist 2
  • 653. 14.7 The Towers of Hanoi • Setup: 3 pegs, one has n disks on it, the other two pegs empty. The disks are arranged in increasing diameter, top bottom • Objective: move the disks from peg 1 to peg 3, observing these rules: – only one disk moves at a time – all remain on pegs except the one being moved – a larger disk cannot be placed on top of a smaller disk at any time 14-653
  • 654. The Towers of Hanoi How it works: 14-654 n=1 Move disk from peg 1 to peg 3. Done. n=2 Move top disk from peg 1 to peg 2. Move remaining disk from peg 1 to peg 3. Move disk from peg 2 to peg 3. Done.
  • 655. Outline of Recursive Algorithm If n==0, do nothing (base case) If n>0, then a. Move the topmost n-1 disks from peg1 to peg2 b. Move the nth disk from peg1 to peg3 c. Move the n-1 disks from peg2 to peg3 end if 14-655
  • 656. 14.8 Exhaustive and Enumeration Algorithms • Enumeration algorithm: generate all possible combinations Example: all possible ways to make change for a certain amount of money • Exhaustive algorithm: search a set of combinations to find an optimal one Example: change for a certain amount of money that uses the fewest coins 14-656
  • 657. 14.9 Recursion vs. Iteration • Benefits (+), disadvantages(-) for recursion: + Natural formulation of solution to certain problems + Results in shorter, simpler functions – May not execute very efficiently • Benefits (+), disadvantages(-) for iteration: + Executes more efficiently than recursion – May not be as natural a method of solution as recursion for some problems 14-657
  • 658. Chapter 15: Polymorphism and Virtual Functions
  • 659. Topics 15.1 Type Compatibility in Inheritance Hierarchies 15.2 Polymorphism and Virtual Member Functions 15.3 Abstract Base Classes and Pure Virtual Functions 15.4 Composition Versus Inheritance 15-659
  • 660. 15.1 Type Compatibility in Inheritance Hierarchies • Classes in a program may be part of an inheritance hierarchy • Classes lower in the hierarchy are special cases of those above 15-660 Animal Cat Dog Poodle
  • 661. Type Compatibility in Inheritance • A pointer to a derived class can be assigned to a pointer to a base class. Another way to say this is: • A base class pointer can point to derived class objects Animal *pA = new Cat; 15-661
  • 662. Type Compatibility in Inheritance • Assigning a base class pointer to a derived class pointer requires a cast Animal *pA = new Cat; Cat *pC; pC = static_cast<Cat *>(pA); • The base class pointer must already point to a derived class object for this to work 15-662
  • 663. Using Type Casts with Base Class Pointers • C++ uses the declared type of a pointer to determine access to the members of the pointed-to object • If an object of a derived class is pointed to by a base class pointer, all members of the derived class may not be accessible • Type cast the base class pointer to the derived class (via static_cast) in order to access members that are specific to the derived class 15-663
  • 664. 15.2 Polymorphism and Virtual Member Functions • Polymorphic code: Code that behaves differently when it acts on objects of different types • Virtual Member Function: The C++ mechanism for achieving polymorphism 15-664
  • 665. Polymorphism Consider the Animal, Cat, Dog hierarchy where each class has its own version of the member function id( ) 15-665 Animal Cat Dog Poodle
  • 666. Polymorphism class Animal{ public: void id(){cout << "animal";} } class Cat : public Animal{ public: void id(){cout << "cat";} } class Dog : public Animal{ public: void id(){cout << "dog";} } 15-666
  • 667. Polymorphism • Consider the collection of different Animal objects Animal *pA[] = {new Animal, new Dog, new Cat}; and accompanying code for(int k=0; k<3; k++) pA[k]->id(); • Prints: animal animal animal, ignoring the more specific versions of id() in Dog and Cat 15-667
  • 668. Polymorphism • The preceding code is not polymorphic: it behaves the same way even though Animal, Dog and Cat have different types and different id() member functions • Polymorphic code would have printed "animal dog cat" instead of "animal animal animal" 15-668
  • 669. Polymorphism • The code is not polymorphic because in the expression pA[k]->id() the compiler sees only the type of the pointer pA[k], which is pointer to Animal • Compiler does not see type of actual object pointed to, which may be Animal, or Dog, or Cat 15-669
  • 670. Virtual Functions Declaring a function virtual will make the compiler check the type of each object to see if it defines a more specific version of the virtual function 15-670
  • 671. Virtual Functions If the member functions id()are declared virtual, then the code Animal *pA[] = {new Animal, new Dog,new Cat}; for(int k=0; k<3; k++) pA[k]->id(); will print animal dog cat 15-671
  • 672. Virtual Functions How to declare a member function virtual: class Animal{ public: virtual void id(){cout << "animal";} } class Cat : public Animal{ public: virtual void id(){cout << "cat";} } class Dog : public Animal{ public: virtual void id(){cout << "dog";} } 15-672
  • 673. Function Binding • In pA[k]->id(), Compiler must choose which version of id() to use: There are different versions in the Animal, Dog, and Cat classes • Function binding is the process of determining which function definition to use for a particular function call • The alternatives are static and dynamic binding 15-673
  • 674. Static Binding • Static binding chooses the function in the class of the base class pointer, ignoring any versions in the class of the object actually pointed to • Static binding is done at compile time 15-674
  • 675. Dynamic Binding • Dynamic Binding determines the function to be invoked at execution time • Can look at the actual class of the object pointed to and choose the most specific version of the function • Dynamic binding is used to bind virtual functions 15-675
  • 676. 15.3 Abstract Base Classes and Pure Virtual Functions • An abstract class is a class that contains no objects that are not members of subclasses (derived classes) • For example, in real life, Animal is an abstract class: there are no animals that are not dogs, or cats, or lions… 15-676
  • 677. Abstract Base Classes and Pure Virtual Functions • Abstract classes are an organizational tool. They are useful in organizing inheritance hierarchies • Abstract classes can be used to specify an interface that must be implemented by all subclasses 15-677
  • 678. Abstract Functions • The member functions specified in an abstract class do not have to be implemented • The implementation is left to the subclasses • In C++, an abstract class is a class with at least one abstract member function 15-678
  • 679. Pure Virtual Functions • In C++, a member function of a class is declared to be an abstract function by making it virtual and replacing its body with = 0; class Animal{ public: virtual void id()=0; }; • A virtual function with its body omitted and replaced with =0 is called a pure virtual function, or an abstract function 15-679
  • 680. Abstract Classes • An abstract class can not be instantiated • An abstract class can only be inherited from; that is, you can derive classes from it • Classes derived from abstract classes must override all pure virtual functions with a concrete member functions before they can be instantiated. 15-680
  • 681. 15.4 Composition vs. Inheritance • Inheritance models an 'is a' relation between classes. An object of a derived class 'is a(n)' object of the base class • Example: – an UnderGrad is a Student – a Mammal is an Animal – a Poodle is a Dog 15-681
  • 682. Composition vs. Inheritance • When defining a new class: • Composition is appropriate when the new class needs to use an object of an existing class • Inheritance is appropriate when – objects of the new class are a subset of the objects of the existing class, or – objects of the new class will be used in the same ways as the objects of the existing class 15-682
  • 683. Chapter 16: Exceptions, Templates, and the Standard Template Library (STL)
  • 684. Topics 16.1 Exceptions 16.2 Function Templates 16.3 Class Templates 16.4 Class Templates and Inheritance 16.5 Introduction to the Standard Template Library 16-684
  • 685. 16.1 Exceptions • An exception is a value or an object that indicates that an error has occurred • When an exception occurs, the program must either terminate or jump to special code for handling the exception. • The special code for handling the exception is called an exception handler 16-685
  • 686. Exceptions – Key Words • throw – followed by an argument, is used to signal an exception • try – followed by a block { }, is used to invoke code that throws an exception • catch – followed by a block { }, is used to process exceptions thrown in a preceding try block. It takes a parameter that matches the type of exception thrown 16-686
  • 687. Throwing an Exception • Code that detects the exception must pass information to the exception handler. This is done using a throw statement: throw "Emergency!" throw 12; • In C++, information thrown by the throw statement may be a value of any type 16-687
  • 688. Catching an Exception • Block of code that handles the exception is said to catch the exception and is called an exception handler • An exception handler is written to catch exceptions of a given type: For example, the code catch(char *str) { cout << str; } can only catch exceptions of type C-string 16-688
  • 689. Catching an Exception Another example of a handler: catch(int x) { cerr << "Error: " << x; } This can catch exceptions of type int 16-689
  • 690. Connecting to the Handler Every catch block is attached to a try block of code and is responsible for handling exceptions thrown from that block try { } catch(char e1) { // This code handles exceptions // of type char that are thrown // in this block } 16-690
  • 691. Execution of Catch Blocks • The catch block syntax is similar to a that of a function • A catch block has a formal parameter that is initialized to the value of the thrown exception before the block is executed 16-691
  • 692. Exception Example • An example of exception handling is code that computes the square root of a number. • It throws an exception in the form of a C- string if the user enters a negative number 16-692
  • 693. Example int main( ) { try { double x; cout << "Enter a number: "; cin >> x; if (x < 0) throw "Bad argument!"; cout << "Square root of " << x << " is " << sqrt(x); } catch(char *str) { cout << str; } return 0; } 16-693
  • 694. Flow of Control 1. Computer encounters a throw statement in a try block 2. The computer evaluates the throw expression, and immediately exits the try block 3. The computer selects an attached catch block that matches the type of the thrown value, places the value in the catch block’s formal parameter, and executes the catch block 16-694
  • 695. Uncaught Exception • An exception may be uncaught if – there is no catch block with a data type that matches the exception that was thrown, or – it was not thrown from within a try block • The program will terminate in either case 16-695
  • 696. Handling Multiple Exceptions Multiple catch blocks can be attached to the same block of code. The catch blocks should handle exceptions of different types try{...} catch(int iEx){ } catch(char *strEx){ } catch(double dEx){ } 16-696
  • 697. Throwing an Exception Class • An exception class can be defined and thrown • A catch block must be designed to catch an object of the exception class • The exception class object can pass data to exception handler via data members 16-697
  • 698. Exception When Calling new • If new cannot allocate memory, it throws an exception of type bad_alloc • Must #include <new> to use bad_alloc • Can invoke new from within a try block, and use a catch block to detect that memory was not allocated. 16-698
  • 699. Nested Exception Handling try blocks can be nested in other try blocks and even in catch blocks try { try{ } catch(int i){ } } catch(char *s) { } 16-699
  • 700. Where to Find an Exception Handler? • The compiler looks for a suitable handler attached to an enclosing try block in the same function • If there is no matching handler in the function, it terminates execution of the function, and continues the search for a handler starting at the point of the call in the calling function. 16-700
  • 701. Unwinding the Stack • An unhandled exception propagates backwards into the calling function and appears to be thrown at the point of the call • The computer will keep terminating function calls and tracing backwards along the call chain until it finds an enclosing try block with a matching handler, or until the exception propagates out of main (terminating the program). • This process is called unwinding the call stack 16-701
  • 702. Rethrowing an Exception • Sometimes an exception handler may need to do some tasks, then pass the exception to a handler in the calling environment. • The statement throw; with no parameters can be used within a catch block to pass the exception to a handler in the outer block 16-702
  • 703. 16.2 Function Templates • Function template: A pattern for creating definitions of functions that differ only in the type of data they manipulate. It is a generic function • They are better than overloaded functions, since the code defining the algorithm of the function is only written once 16-703
  • 704. Example Two functions that differ only in the type of the data they manipulate void swap(int &x, int &y) { int temp = x; x = y; y = temp; } void swap(char &x, char &y) { char temp = x; x = y; y = temp; } 16-704
  • 705. A swap Template The logic of both functions can be captured with one template function definition template<class T> void swap(T &x, T &y) { T temp = x; x = y; y = temp; } 16-705
  • 706. Using a Template Function • When a function defined by a template is called, the compiler creates the actual definition from the template by inferring the type of the type parameters from the arguments in the call: int i = 1, j = 2; swap(i,j); • This code makes the compiler instantiate the template with type int in place of the type parameter T 16-706
  • 707. Function Template Notes • A function template is a pattern • No actual code is generated until the function named in the template is called • A function template uses no memory • When passing a class object to a function template, ensure that all operators referred to in the template are defined or overloaded in the class definition 16-707
  • 708. Function Template Notes • All data types specified in template prefix must be used in template definition • Function calls must pass parameters for all data types specified in the template prefix • Function templates can be overloaded – need different parameter lists • Like regular functions, function templates must be defined before being called 16-708
  • 709. Where to Start When Defining Templates • Templates are often appropriate for multiple functions that perform the same task with different parameter data types • Develop function using usual data types first, then convert to a template: – add template prefix – convert data type names in the function to a type parameter (i.e., a T type) in the template 16-709
  • 710. 16.3 Class Templates • It is possible to define templates for classes. Such classes define abstract data types • Unlike functions, a class template is instantiated by supplying the type name (int, float, string, etc.) at object definition 16-710
  • 711. Class Template Consider the following classes 1. Class used to join two integers by adding them: class Joiner { public: int combine(int x, int y) {return x + y;} }; 2. Class used to join two strings by concatenating them: class Joiner { public: string combine(string x, string y) {return x + y;} }; 16-711
  • 712. Example class Template A single class template can capture the logic of both classes: it is written with a template prefix that specifies the data type parameters: template <class T> class Joiner { public: T combine(T x, T y) {return x + y;} }; 16-712
  • 713. Using Class Templates To create an object of a class defined by a template, specify the actual parameters for the formal data types Joiner<double> jd; Joiner<string> sd; cout << jd.combine(3.0, 5.0); cout << sd.combine("Hi ", "Ho"); Prints 8.0 and Hi Ho 16-713
  • 714. 16.4 Class Templates and Inheritance • Templates can be combined with inheritance • You can derive – Non template classes from a template class: instantiate the base class template and then inherit from it – Template class from a template class • Other combinations are possible 16-714
  • 715. 16.5 Introduction to the Standard Template Library • Standard Template Library (STL): a library containing templates for frequently used data structures and algorithms • Programs can be developed faster and are more portable if they use templates from the STL 16-715
  • 716. Standard Template Library Two important types of data structures in the STL: – containers: classes that store data and impose some organization on it – iterators: like pointers; provides mechanisms for accessing elements in a container 16-716
  • 717. Containers Two types of container classes in STL: – sequential containers: organize and access data sequentially, as in an array. These include vector, dequeue, and list containers. – associative containers: use keys to allow data elements to be quickly accessed. These include set, multiset, map, and multimap containers. 16-717
  • 718. Creating Container Objects • To create a list of int, write list<int> mylist; • To create a vector of string objects, write vector<string> myvector; • Requires the vector header file 16-718
  • 719. Iterators • Generalization of pointers, used to access information in containers • Many types: – forward (uses ++) – bidirectional (uses ++ and -- ) – random-access – input (can be used with cin and istream objects) – output (can be used with cout and ostream objects) 16-719
  • 720. Containers and Iterators • Each container class defines an iterator type, used to access its contents • The type of an iterator is determined by the type of the container: list<int>::iterator x; list<string>::iterator y; x is an iterator for a container of type list<int> 16-720
  • 721. Containers and Iterators Each container class defines functions that return iterators: begin(): returns iterator to item at start end(): returns iterator denoting end of container 16-721
  • 722. Containers and Iterators • Iterators support pointer-like operations. If iter is an iterator, then – *iter is the item it points to: this dereferences the iterator – iter++ advances to the next item in the container – iter-- backs up in the container • The end() iterator points to past the end: it should never be dereferenced 16-722
  • 723. Traversing a Container Given a vector: vector<int> v; for (int k=1; k<= 5; k++) v.push_back(k*k); Traverse it using iterators: vector<int>::iterator iter = v.begin(); while (iter != v.end()) { cout << *iter << " "; iter++} Prints 1 4 9 16 25 16-723
  • 724. Some vector Class Member Functions Function Description front(), back() Returns a reference to the first, last element in a vector size() Returns the number of elements in a vector capacity() Returns the number of elements that a vector can hold clear() Removes all elements from a vector push_back(value) Adds element containing value as the last element in the vector pop_back() Removes the last element from the vector insert(iter, value) Inserts new element containing value just before element pointed at by iter 16-724
  • 725. Algorithms • STL contains algorithms that are implemented as function templates to perform operations on containers. • Requires algorithm header file • Collection of algorithms includes 16-725 binary_search count for_each find max_element min_element random_shuffle sort and others
  • 726. Using STL algorithms • Many STL algorithms manipulate portions of STL containers specified by a begin and end iterator • max_element(iter1, iter2) finds max element in the portion of a container delimited by iter1, iter2 • min_element(iter1, iter2) is similar to above 16-726
  • 727. More STL algorithms • random_shuffle(iter1, iter2) randomly reorders the portion of the container in the given range • sort(iter1, iter2) sorts the portion of the container specified by the given range 16-727
  • 728. random-shuffle Example The following example stores the squares 1, 4, 9, 16, 25 in a vector, shuffles the vector, and then prints it out 16-728
  • 729. random_shuffle example int main() { vector<int> vec; for (int k = 1; k <= 5; k++) vec.push_back(k*k); random_shuffle(vec.begin(),vec.end()); vector<int>::iterator p = vec.begin(); while (p != vec.end()) { cout << *p << " "; p++; } return 0; } 16-729
  • 731. Topics 17.1 Introduction to the Linked List ADT 17.2 Linked List Operations 17.3 A Linked List Template 17.4 Recursive Linked List Operations 17.5 Variations of the Linked List 17.6 The STL list Container 17-731
  • 732. 17.1 Introduction to the Linked List ADT • Linked list: a sequence of data structures (nodes) with each node containing a pointer to its successor • The last node in the list has its successor pointer set to NULL 17-732 NULL list head
  • 733. Linked List Terminology • The node at the beginning is called the head of the list • The entire list is identified by the pointer to the head node. This pointer is called the list head. 17-733
  • 734. Linked Lists • Nodes can be added or removed from the linked list during execution • Addition or removal of nodes can take place at beginning, end, or middle of the list 17-734 NULL list head Add or delete node
  • 735. Linked Lists vs. Arrays and Vectors • Linked lists can grow and shrink as needed, unlike arrays, which have a fixed size • Unlike vectors, insertion or removal of a node in the middle of the list is very efficient 17-735 NULL list head
  • 736. Node Organization A node contains: – data: one or more data fields – may be organized as structure, object, etc. – a pointer that can point to another node 17-736 data pointer
  • 737. Empty List • A list with no nodes is called the empty list • In this case the list head is set to NULL 17-737 NULL list head
  • 738. Creating an Empty List • Define a pointer for the head of the list: ListNode *head = NULL; • Head pointer initialized to NULL to indicate an empty list 17-738 NULL head
  • 739. C++ Implementation Implementation of nodes requires a structure containing a pointer to a structure of the same type (a self-referential data structure): struct ListNode { int data; ListNode *next; }; 17-739
  • 740. C++ Implementation Nodes can be equipped with constructors: struct ListNode { int data; ListNode *next; ListNode(int d, ListNode* p=NULL) {data = d; next = p;} }; 17-740
  • 741. Building a List from a File of Numbers ListNode *head = NULL; int val; while (inFile >> val) { // add new nodes at the head head = new ListNode(val, head); }; 17-741
  • 742. Traversing a Linked List • List traversals visit each node in a linked list to display contents, validate data, etc. • Basic process of traversal: set a pointer to the head pointer while pointer is not NULL process data set pointer to the successor of the current node end while 17-742
  • 743. Traversing a Linked List 17-743 NULL list head 5 13 19 nodePtr nodePtr points to the node containing 5, then the node containing 13, then the node containing 19, then points to NULL, and the list traversal stops
  • 744. 17.2 Linked List Operations Basic operations: • add a node to the end of the list • insert a node within the list • traverse the linked list • Delete/remove a node from the list • delete/destroy the list 17-744
  • 745. Creating a Node ListNode *p; int num = 23; p = new ListNode(num); 17-745 NULL 23 p
  • 746. Appending an Item To add an item to the end of the list: • If the list is empty, set head to a new node containing the item head = new ListNode(num); • If the list is not empty, move a pointer p to the last node, then add a new node containing the item p->next = new ListNode(num); 17-746
  • 747. Appending an Item 17-747 list head 5 13 23 p NULL List originally has nodes with 5 and 13. p locates the last node, then a node with a new item, 23, is added
  • 748. Destroying a Linked List • Must remove all nodes used in the list • To do this, use list traversal to visit each node • For each node, – Unlink the node from the list – Free the node’s memory • Finally, set the list head to NULL 17-748
  • 749. Inserting a Node • Used to insert an item into a sorted list, keeping the list sorted. • Two possibilities: – Insertion is at the head of the list (because item at head is already greater than item being inserted, or because list is empty – Insertion is after an existing node in a non- empty list 17-749
  • 750. Inserting a Node at Head of a List • Test to see if – head pointer is NULL, or – node value pointed at by head is greater than value to be inserted • Must test in this order: unpredictable results if second test is attempted on an empty list • Create new node, set its next pointer to head, then point head to it 17-750
  • 751. Inserting a Node in Body of a List • Requires two pointers to traverse the list: – pointer to locate the node with data value greater than that of node to be inserted – pointer to 'trail behind' one node, to point to node before point of insertion • New node is inserted between the nodes pointed at by these pointers 17-751
  • 752. Inserting a Node into a Linked List 17-752 NULL list head 5 13 19 17 nodePtr previousNode Correct position located Item to insert num
  • 753. Inserting a Node into a Linked List 17-753 NULL list head 5 13 19 17 nodePtr previousNode New node created and inserted in order in the linked list
  • 754. Removing an Element • Used to remove a node from a linked list • Requires two pointers: one to locate the node to be deleted, one to point to the node before the node to be deleted 17-754
  • 755. Deleting a Node 17-755 NULL list head 5 13 19 nodePtr previousNode Locating the node containing 13 Contents of node to be deleted: 13
  • 756. Deleting a Node 17-756 NULL list head 5 13 19 nodePtr previousNode Adjusting pointer around the node to be deleted
  • 757. Deleting a Node 17-757 NULL list head 5 19 nodePtr previousNode Linked list after deleting the node containing 13
  • 758. 17.3 A Linked List Template • A linked list template can be written by replacing the type of the data in the node with a type parameter, say T. • If defining the linked list as a class template, then all member functions must be function templates • Implementation assumes use with data types that support comparison: == and <= 17-758
  • 759. 17.4 Recursive Linked List Operations • A non-empty linked list consists of a head node followed by the rest of the nodes • The rest of the nodes form a linked list that is called the tail of the original list 17-759
  • 760. Recursive Linked List Operations Many linked list operations can be broken down into the smaller problems of processing the head of the list and then recursively operating on the tail of the list 17-760
  • 761. Recursive Linked List Operations To find the length (number of elements) of a list – If the list is empty, the length is 0 (base case) – If the list is not empty, find the length of the tail and then add 1 to obtain the length of the original list 17-761
  • 762. Recursive Linked List Operations To find the length of a list: int length(ListNode *myList) { if (myList == NULL) return 0; else return 1 + length(myList->next); } 17-762
  • 763. Recursive Linked List Operations Using recursion to display a list: void displayList(ListNode *myList) { if (myList != NULL) { cout << myList->data << " "; displayList(myList->next); } } 17-763
  • 764. Other Recursive Linked List Operations • Insert and remove operations can be written to use recursion • General design considerations: – Base case is often when the list is empty – Recursive case often involves the use of the tail of the list (i.e., the list without the head). Since the tail has one fewer entry than the list that was passed in to this call, the recursion eventually stops. 17-764
  • 765. 17.5 Variations of the Linked List Other linked list organizations: – doubly-linked list: each node contains two pointers: one to the next node in the list, one to the previous node in the list 17-765 NULL list head 5 13 19 NULL
  • 766. Variations of the Linked List Other linked list organizations: – circular linked list: the last node in the list points back to the first node in the list, not to NULL 17-766 list head 5 13 19
  • 767. 17.6 The STL list Container • Template for a doubly linked list • Member functions for – locating beginning, end of list: front, back, end – adding elements to the list: insert, merge, push_back, push_front – removing elements from the list: erase, pop_back, pop_front, unique 17-767
  • 768. Chapter 18: Stacks and Queues
  • 769. Topics 18.1 Introduction to the Stack ADT 18.2 Dynamic Stacks 18.3 The STL stack Container 18.4 Introduction to the Queue ADT 18.5 Dynamic Queues 18.6 The STL deque and queue Containers 18.7 Eliminating Recursion 18-769
  • 770. 18.1 Introduction to the Stack ADT • Stack: a LIFO (last in, first out) data structure • Examples: – plates in a cafeteria serving area – return addresses for function calls 18-770
  • 771. Stack Basics • Stack is usually implemented as a list, with additions and removals taking place at one end of the list • The active end of the list implementing the stack is the top of the stack • Stack types: – Static – fixed size, often implemented using an array – Dynamic – size varies as needed, often implemented using a linked list 18-771
  • 772. Stack Operations and Functions Operations: – push: add a value at the top of the stack – pop: remove a value from the top of the stack Functions: – isEmpty: true if the stack currently contains no elements – isFull: true if the stack is full; only useful for static stacks 18-772
  • 773. Static Stack Implementation • Uses an array of a fixed size • Bottom of stack is at index 0. A variable called top tracks the current top of the stack const int STACK_SIZE = 3; char s[STACK_SIZE]; int top = 0; top is where the next item will be added 18-773
  • 774. Array Implementation Example This stack has max capacity 3, initially top = 0 and stack is empty. K E G K E 18-774 E push('E'); push('K'); push('G'); top is 1 top is 2 top is 3
  • 775. Stack Operations Example After three pops, top is 0 and the stack is empty E 18-775 K E pop(); (remove G) pop(); (remove K) pop(); (remove E)
  • 776. Array Implementation char s[STACK_SIZE]; int top=0; To check if stack is empty: bool isEmpty() { if (top == 0) return true; else return false; } 18-776
  • 777. Array Implementation char s[STACK_SIZE]; int top=0; To check if stack is full: bool isFull() { if (top == STACK_SIZE) return true; else return false; } 18-777
  • 778. Array Implementation To add an item to the stack void push(char x) { if (isFull()) {error(); exit(1);} // or could throw an exception s[top] = x; top++; } 18-778
  • 779. Array Implementation To remove an item from the stack void pop(char &x) { if (isEmpty()) {error(); exit(1);} // or could throw an exception top--; x = s[top]; } 18-779
  • 780. Class Implementation class STACK { private: char *s; int capacity, top; public: void push(char x); void pop(char &x); bool isFull(); bool isEmpty(); STACK(int stackSize); ~STACK() }; 18-780
  • 781. Exceptions from Stack Operations • Exception classes can be added to the stack object definition to handle cases where an attempt is made to push onto a full stack (overflow) or to pop from an empty stack (underflow) • Programs that use push and pop operations should do so from within a try block. • catch block(s) should follow the try block, interpret what occurred, and inform the user. 18-781
  • 782. 18.2 Dynamic Stacks • Implemented as a linked list • Can grow and shrink as necessary • Can't ever be full as long as memory is available 18-782
  • 783. Dynamic Linked List Implementation • Define a class for a dynamic linked list • Within the class, define a private member class for dynamic nodes in the list • Define a pointer to the beginning of the linked list, which will serve as the top of the stack 18-783
  • 784. Linked List Implementation A linked stack after three push operations: push('a'); push('b'); push('c'); 18-784 NULL top a b c
  • 785. Operations on a Linked Stack Check if stack is empty: bool isEmpty() { if (top == NULL) return true; else return false; } 18-785
  • 786. Operations on a Linked Stack Add a new item to the stack void push(char x) { top = new LNode(x, top); } 18-786
  • 787. Operations on a Linked Stack Remove an item from the stack void pop(char &x) { if (isEmpty()) { error(); exit(1);} x = top->value; LNode *oldTop = top; top = top->next; delete oldTop; } • 18-787
  • 788. 18.3 The STL stack Container • Stack template can be implemented as a vector, list, or a deque • Implements push, pop, and empty member functions • Implements other member functions: – size: number of elements on the stack – top: reference to element on top of the stack (must be used with pop to remove and retrieve top element) 18-788
  • 789. Defining an STL-based Stack • Defining a stack of char, named cstack, implemented using a vector: stack< char, vector<char> > cstack; • Implemented using a list: stack< char, list<char> > cstack; • Implemented using a deque (default): stack< char > cstack; • Spaces are required between consecutive > > symbols to distinguish from stream extraction 18-789
  • 790. 18.4 Introduction to the Queue ADT • Queue: a FIFO (first in, first out) data structure. • Examples: – people in line at the theatre box office – print requests sent by users to a network printer • Implementation: – static: fixed size, implemented as array – dynamic: variable size, implemented as linked list 18-790
  • 791. Queue Locations and Operations • rear: position where elements are added • front: position from which elements are removed • enqueue: add an element to the rear of the queue • dequeue: remove an element from the front of a queue 18-791
  • 792. Array Implementation of Queue An empty queue that can hold char values: enqueue('E'); E 18-792 front rear front, rear
  • 793. Queue Operations - Example enqueue('K'); enqueue('G'); E K E K G 18-793 front rear front rear
  • 794. Queue Operations - Example dequeue(); // remove E dequeue(); // remove K K G G 18-794 front rear front rear
  • 795. Array Implementation Issues • In the preceding example, Front never moves. • Whenever dequeue is called, all remaining queue entries move up one position. This takes time. • Alternate approach: – Circular array: front and rear both move when items are added and removed. Both can ‘wrap around’ from the end of the array to the front if warranted. • Other conventions are possible 18-795
  • 796. Array Implementation Issues • Variables needed – const int QSIZE = 100; – char q[QSIZE]; – int front = -1; – int rear = -1; – int number = 0; //how many in queue • Could make these members of a queue class, and queue operations would be member functions 18-796
  • 797. isEmpty Member Function Check if queue is empty bool isEmpty() { if (number > 0) return false; else return true; } 18-797
  • 798. isFull Member Function Check if queue is full bool isFull() { if (number < QSIZE) return false; else return true; } 18-798
  • 799. enqueue and dequeue • To enqueue, we need to add an item x to the rear of the queue • Queue convention says q[rear] is already occupied. Execute if(!isFull) { rear = (rear + 1) % QSIZE; // mod operator for wrap-around q[rear] = x; number ++; } 18-799
  • 800. enqueue and dequeue • To dequeue, we need to remove an item x from the front of the queue • Queue convention says q[front] has already been removed. Execute if(!isEmpty) { front = (front + 1) % QSIZE; x = q[front]; number--; } 18-800
  • 801. enqueue and dequeue • enqueue moves rear to the right as it fills positions in the array • dequeue moves front to the right as it empties positions in the array • When enqueue gets to the end, it wraps around to the beginning to use those positions that have been emptied • When dequeue gets to the end, it wraps around to the beginning use those positions that have been filled 18-801
  • 802. enqueue and dequeue • Enqueue wraps around by executing rear = (rear + 1) % QSIZE; • Dequeue wraps around by executing front = (front + 1) % QSIZE; 18-802
  • 803. Exception Handling in Static Queues • As presented, the static queue class will encounter an error if an attempt is made to enqueue an element to a full queue, or to dequeue an element from an empty queue • A better design is to throw an underflow or an overflow exception and allow the programmer to determine how to proceed • Remember to throw exceptions from within a try block, and to follow the try block with a catch block 18-803
  • 804. 18.5 Dynamic Queues • Like a stack, a queue can be implemented using a linked list • This allows dynamic sizing and avoids the issue of wrapping indices 18-804 front rear NULL
  • 805. Dynamic Queue Implementation Data Structures • Define a class for the dynamic queue • Within the dynamic queue, define a private member class for a dynamic node in the queue • Define pointers to the front and rear of the queue 18-805
  • 806. isEmpty Member Function To check if queue is empty: bool isEmpty() { if (front == NULL) return true; else return false; } 18-806
  • 807. enqueue Member Function Details To add item at rear of queue if (isEmpty()) { front = new QNode(x); rear = front; } else { rear->next = new QNode(x); rear = rear->next; } 18-807
  • 808. dequeue Member Function To remove item from front of queue if (isEmpty()) { error(); exit(1); } x = front->value; QNode *oldfront = front; front = front->next; delete oldfront; 18-808
  • 809. 18.6 The STL deque and queue Containers • deque: a double-ended queue (DEC). Has member functions to enqueue (push_back) and dequeue (pop_front) • queue: container ADT that can be used to provide a queue based on a vector, list, or deque. Has member functions to enqueue (push) and dequeue (pop) 18-809
  • 810. Defining a Queue • Defining a queue of char, named cQueue, based on a deque: deque<char> cQueue; • Defining a queue with the default base container queue<char> cQueue; • Defining a queue based on a list: queue<char, list<char> > cQueue; • Spaces are required between consecutive > > symbols to distinguish from stream extraction 18-810
  • 811. 18.7 Eliminating Recursion • Recursive solutions to problems are often elegant but inefficient • A solution that does not use recursion is more efficient for larger sizes of inputs • Eliminating the recursion: re-writing a recursive algorithm so that it uses other programming constructs (stacks, loops) rather than recursive calls 18-811
  • 813. Topics 19.1 Definition and Application of Binary Trees 19.2 Binary Search Tree Operations 19.3 Template Considerations for Binary Search Trees 19-813
  • 814. 19.1 Definition and Application of Binary Trees • Binary tree: a nonlinear data structure in which each node may point to 0, 1, or two other nodes • The nodes that a node N points to are the (left or right) children of N 19-814 NULL NULL NULL NULL NULL NULL
  • 815. Terminology • If a node N is a child of another node P, then P is called the parent of N • A node that has no children is called a leaf node • In a binary tree there is a unique node with no parent. This is the root of the tree 19-815
  • 816. Binary Tree Terminology • Root pointer: like a head pointer for a linked list, it points to the root node of the binary tree • Root node: the node with no parent 19-816 NULL NULL NULL NULL NULL NULL
  • 817. Binary Tree Terminology Leaf nodes: nodes that have no children The nodes containing 7 and 43 are leaf nodes 19-817 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 818. Binary Tree Terminology Child nodes, children: The children of the node containing 31 are the nodes containing 19 and 59 19-818 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 819. Binary Tree Terminology The parent of the node containing 43 is the node containing 59 19-819 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 820. Binary Tree Terminology • A subtree of a binary tree is a part of the tree from a node N down to the leaf nodes • Such a subtree is said to be rooted at N, and N is called the root of the subtree 19-820
  • 821. Subtrees of Binary Trees • A subtree of a binary tree is itself a binary tree • A nonempty binary tree consists of a root node, with the rest of its nodes forming two subtrees, called the left and right subtree 19-821
  • 822. Binary Tree Terminology • The node containing 31 is the root • The nodes containing 19 and 7 form the left subtree • The nodes containing 59 and 43 form the right subtree 19-822 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 823. Uses of Binary Trees • Binary search tree: a binary tree whose data is organized to simplify searches • Left subtree at each node contains data values less than the data in the node • Right subtree at each node contains values greater than the data in the node • 19-823 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 824. 19.2 Binary Search Tree Operations • Create a binary search tree • Insert a node into a binary tree – put node into tree in its correct position to maintain order • Find a node in a binary tree – locate a node with particular data value • Delete a node from a binary tree – remove a node and adjust links to preserve the binary tree and the order 19-824
  • 825. Binary Search Tree Node • A node in a binary tree is like a node in a linked list, except that it has two node pointer fields: class TreeNode { int value; TreeNode *left; TreeNode *right; }; • Define the nodes as class objects. A constructor can aid in the creation of nodes 19-825
  • 826. TreeNode Constructor TreeNode::TreeNode(int val, TreeNode *l1=NULL, TreeNode *r1=NULL) { value = val; left = l1; right = r1; } 19-826
  • 827. Creating a New Node TreeNode *p; int num = 23; p = new TreeNode(num); 19-827 NULL NULL 23 p
  • 828. Inserting an item into a Binary Search Tree 1) If the tree is empty, replace the empty tree with a new binary tree consisting of the new node as root, with empty left and right subtrees 2) Otherwise, if the item is less than the root, recursively insert the item in the left subtree. If the item is greater than the root, recursively insert the item into the right subtree 19-828
  • 829. Inserting an item into a Binary Search Tree 19-829 NULL NULL 7 19 31 43 59 root Step 1: 23 is less than 31. Recursively insert 23 into the left subtree Step 2: 23 is greater than 19. Recursively insert 23 into the right subtree Step 3: Since the right subtree is NULL, insert 23 here NULL NULL NULL NULL value to insert: 23
  • 830. Traversing a Binary Tree Three traversal methods: 1) Inorder: a) Traverse left subtree of node b) Process data in node c) Traverse right subtree of node 2) Preorder: a) Process data in node b) Traverse left subtree of node c) Traverse right subtree of node 3) Postorder: a) Traverse left subtree of node b) Traverse right subtree of node c) Process data in node 19-830
  • 831. Traversing a Binary Tree 19-831 NULL NULL 7 19 31 43 59 TRAVERSAL METHOD NODES ARE VISITED IN THIS ORDER Inorder 7, 19, 31, 43, 59 Preorder 31, 19, 7, 59, 43 Postorder 7, 19, 43, 59, 31 NULL NULL NULL NULL
  • 832. Searching in a Binary Tree 1) Start at root node 2) Examine node data: a) Is it desired value? Done b) Else, is desired data < node data? Repeat step 2 with left subtree c) Else, is desired data > node data? Repeat step 2 with right subtree 3) Continue until desired value found or NULL pointer reached 19-832 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 833. Searching in a Binary Tree To locate the node containing 43, 1. Examine the root node (31) 2. Since 43 > 31, examine the right child of the node containing 31, (59) 3. Since 43 < 59, examine the left child of the node containing 59, (43) 4. The node containing 43 has been found 19-833 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL
  • 834. Deleting a Node from a Binary Tree – Leaf Node If node to be deleted is a leaf node, replace parent node’s pointer to it with a NULL pointer, then delete the node 19-834 NULL 7 19 NULL NULL NULL 19 NULL Deleting node with 7 – before deletion Deleting node with 7 – after deletion
  • 835. Deleting a Node from a Binary Tree – One Child If node to be deleted has one child node, adjust pointers so that parent of node to be deleted points to child of node to be deleted, then delete the node 19-835
  • 836. Deleting a Node from a Binary Tree – One Child 19-836 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL NULL 7 31 43 59 NULL NULL NULL NULL Deleting node containing 19 – before deletion Deleting node containing 19 – after deletion
  • 837. Deleting a Node from a Binary Tree – Two Children • If node to be deleted has left and right children, – ‘Promote’ one child to take the place of the deleted node – Locate correct position for other child in subtree of promoted child • Convention in text: “attach" the right subtree to its parent, then position the left subtree at the appropriate point in the right subtree 19-837
  • 838. Deleting a Node from a Binary Tree – Two Children 19-838 NULL NULL 7 19 31 43 59 NULL NULL NULL NULL 43 59 NULL NULL Deleting node with 31 – before deletion Deleting node with 31 – after deletion 7 19 NULL NULL NULL
  • 839. 19.3 Template Considerations for Binary Search Trees • Binary tree can be implemented as a template, allowing flexibility in determining type of data stored • Implementation must support relational operators >, <, and == to allow comparison of nodes 19-839