Top-Down Design with Functions and Classes Chapter 3

advertisement
Top-Down Design with Functions
and Classes
Chapter 3
3.1 Building Programs from
Existing Information
– Reuse of existing programs
– Develop program in stages
– Compile along the way
– Keep it small
– Comments to describe actions
2
3.1 Building Programs from
Existing Information






Try not to start from scratch (if possible)
Use any kind of information you get
Use solutions of other problems (if possible)
Adhere to the software development phases
Build comments from the designed algorithm and
its refinements
// BAD: multiply kms by MILE_TO_KM and store
// result in miles
// GOOD: convert from kilometers to miles
miles = MILE_TO_KM * kms;
3
3.1 Building Programs from
Existing Information

Example: Area of and Circumference of a
Circle
- Problem: Get the radius of the circle and
compute the area and circumference
- Analysis: Constant PI = 3.14
Inputs: float radius
Output: float area, float circumference
Formulas: area is PI*radius*radius
circumference = 2*PI*radius
4
3.1 Building Programs from
Existing Information

Design
– Get the radius of the circle
– Compute the area of the circle
• Assign PI * radius * radius to area
– Compute the circumference of the circle
• Assign 2 * PI * radius to circumference
– Display the area and the circumference
5
3.1 Building Programs from
Existing Information

Implementation (1. Draft)
// compute area and circumference
int main() {
const float PI = 3.14;
float radius;
// input: radius of the circle
float area;
// output: are of the circle
float circumference; // output circumference of the circle
// Get the radius
// Compute the area of the circle
// Assign PI * radius * radius to area
// Compute the circumference of the circle
// Assign 2 * PI * radius to circumference
// Display area and circumference
return 0;
}
6
3.1 Building Programs from
Existing Information

Implementation (cont’d)
– Finish the raw implementation of the previous
step

Test
– Run the program using sample input data
7
3.1 Building Programs from
Existing Information


d2
Reuse of this program in order to solve another problem is possible
Example: Weight of a Batch of Washers
– Problem: Your company ask to compute the weight for produced washers
– Analysis: A washer resembles a small donut. We need the rim area, the
thickness, and the density of the material used. The last two quantities are
inputs.
• Problem Constant: PI = 3.14
• Inputs: float holeDiameter // diameter of the hole (d1)
float edgeDiameter // diameter of outer edge (d2)
// Assumption: edgeDiameter >= holeDiameter !!!
float thickness
// washer thickness
float density
// material density (needed for weight)
float quatity
// number f washers
d1
8
3.1 Building Programs from
Existing Information
• Output: float weight // weight of batch of washers
• Variables:
– float holeRadius, edgeRadius, rimArea, unitWeight
• Formulas:
–
–
–
–
area of circle = PI*radius*radius (see previous problem)
Radius of circle = diameter / 2
Rim area = area of outer circle – area of hole
Unit weight = rim area * thickness * density
9
Implementation: Washers.cpp
// File: washers.cpp
// Computes the weight of a batch of flat
// washers.
#include <iostream>
using namespace std;
int main()
{
const float PI = 3.14159;
float holeDiameter; // input -
10
Washers.cpp
float
float
float
float
float
float
float
float
float
edgeDiameter;
thickness;
density;
quantity;
weight;
holeRadius;
edgeRadius;
rimArea;
unitWeight;
//
//
//
//
//
//
//
//
//
input - diameter
input - thickness
input - density
input - number
output - weight
radius of hole
radius of outer edge
area of rim
weight of 1 washer
11
Washers.cpp
cout << "Inner diameter in centimeters: ";
cin >> holeDiameter;
cout << "Outer diameter in centimeters: ";
cin >> edgeDiameter;
// check for edgeDiameter >= holeDiameter
// is not yet made
cout << "Thickness in centimeters: ";
cin >> thickness;
cout << "Material density in grams per
cubic centimeter: ";
cin >> density;
cout << "Quantity in batch: ";
cin >> quantity;
12
Washers.cpp
// Compute the rim area.
holeRadius = holeDiameter / 2.0;
edgeRadius = edgeDiameter / 2.0;
rimArea = PI * edgeRadius * edgeRadius PI * holeRadius * holeRadius;
// Compute the weight of a flat washer.
unitWeight = rimArea * thickness * density;
// Compute the weight the batch of washers
weight = unitWeight * quantity;
13
Washers.cpp
// Display the weight
cout << "The expected weight of the batch
is " << weight;
cout << " grams." << endl;
return 0;
}
14
Washers.cpp
Program Output
Inner Diameter in centimeters: 1.2
Outer Diameter in centimeters: 2.4
Thickness in centimeters: 0.1
Material density in grams per cubic centimeter: 7.87
Quantity in batch: 1000
The expected weight of the batch is 2670.23 grams
15
3.2 Library Functions
– Goal of Structured Programming
• Error free code
– Reusability
• Don’t reinvent the wheel
– C ++ provides collection of functions
– Organized in Libraries
16
3.2 Library Functions

Examples
–
–
–
–
–
abs(x): absolute value
ceil(x) and floor(x)
cos(x), sin(x), tan(x)
log(x), log10(x), exp(x)
pow(x, y)
<cstdlib>
<cmath>
<cmath>
<cmath>
<cmath>
17
C++ Math Library
– Functions in the Math library
• sqrt
cos
sin
pow
– Function use in Assignments
y = sqrt (x);
sqrt is function name
x is function argument
– Activated by a “function call”
– Result of execution is assigned to variable y
18
C++ Math Library (cont)
Function sqrt as a “black box”
X is 16.0
Square root
computation
Result is 4.0
19
C++ Library Functions
– We can effectively utilize existing functions by
learning to read function prototypes with the
preconditions and postconditions.
– Example prototype (or signature)



double sqrt(double x)
// PRE: x >= 0.0
// POST: Returns the square root of x.
20
Preconditions and
Postconditions
– Comments that represents a contract
between the implementor of a function
and the user (client) of that function.
– We'll look at two such comments:
• Precondition: What the function requires.
• Postcondition: What the function will do if
the precondition is met.
21
Preconditions and
Postconditions
– The preconditions are the circumstances
that must be true before the function can
successfully fulfill the promised
postconditions.
– Example (Precondition abbreviates to
PRE:
double sqrt(double x);
// PRE: x >= 0
// POST: Returns square root of argument X
22
SquareRoot.cpp
// File: squareRoot.cpp
// Performs three square root computations
#include <cmath>
#include <iostream>
using namespace std;
// sqrt function
// i/o functions
int main()
{
float first;
float second;
float answer;
23
SquareRoot.cpp
// Get first number and display its square root.
cout << "Enter the first number: ";
cin >> first;
answer = sqrt(first);
cout << "The square root of the first
number is " << answer << endl;
// Get second number and display its square root.
cout << "Enter the second number: ";
cin >> second;
answer = sqrt(second);
cout << "The square root of the second
number is " << answer << endl;
24
SquareRoot.cpp
// Display the square root of the sum of first
// and second.
answer = sqrt(first + second);
cout << "The square root of the sum of
both numbers is " << answer << endl;
return 0;
}
25
SquareRoot.cpp
Program Output
Enter the first number: 9
The square root of the first number is 3
Enter the second number: 16
The square root of the second number is 4
The square root of the sum of both numbers is 5
26
Examples





Roots of a quadratic equation
log10(xy)
Floor(76.97)
Ceil(105.04)
Sqrt(floor(fabs(-19.9)))
27
3.3 Top-Down Design and
Structure Charts
Original Problem
Draw a
Circle
Detailed
subproblem
s
Draw a
figure
Level 0
Draw a
Triangle
Draw
intersecting
lines
Draw
intersecting
lines
Draw a
base
Level 1
Level 2
28
3.4 Functions without
Arguments
– Functions are used in Top-Down Design
– main() is just a function
• called by OS
– C++ program is a collection of Functions
• top level function is called the main()
• lower level functions
– User Defined or Libraries
– Example StkFigMn.cpp
29
StickFigure.cpp
// File: stickFigure.cpp
// Draws a stick figure
#include <iostream>
using namespace std;
// Functions used ...
void
void
void
void
drawCircle();
// Draws a circle
drawTriangle(); // Draws a triangle
drawIntersect(); // Draws intersecting lines
drawBase();
// Draws a horizontal line
30
StickFigure.cpp
int main()
{
// Draw a circle.
drawCircle();
// Draw a triangle.
drawTriangle();
// Draw intersecting lines.
drawIntersect();
return 0;
}
31
Function Calls
– We can call a function and get results
without knowing the implementation of
that function.
• pow(x, y) returns x to the yth power.
– For now, we need not know exactly how
a function is implemented.
– However, we do need to know how to use
the function.
32
Function Calls
– This general form of a function call:
function-name ( optional argument-list );
– Example function call:
drawCircle ();
– The function name is drawCircle
– No arguments to this function
33
Function Prototype
– This general form of a function prototype:
type function-name ( optional argument-list );
– Example function prototype:
void skipThree ();
– Type
• int - float - char
– Name
– ( );
– Descriptive comment
34
Function Definition
– General form of a function definition:
type function-name ( optional argument-list )
{
local-declarations - function body
executable-statements
}
– Example function definition:
void drawTriangle ()
35
Function Definition
void drawTriangle () function header
{
function body
// Draw a triangle.
drawIntersect ();
drawBase ();
}
36
StickFigure.cpp
// Draws a circle
void drawCircle()
{
cout << "
* " << endl;
cout << " *
*" << endl;
cout << "
* * " << endl;
} // end drawCircle
37
StickFigure.cpp
void drawCircleChar(char symbol)
{
cout << "
" << symbol << " " << endl;
cout << " " << symbol << "
" << symbol <<
endl;
cout << "
" << symbol << " " << symbol <<
endl;
}
// Draws a triangle
void drawTriangle()
{
drawIntersect();
drawBase();
}
38
StickFigure.cpp
// Draws intersecting lines
void drawIntersect()
{
cout << "
/ \\ " << endl;
cout << " /
\\ " << endl;
cout << " /
\\" << endl;
}
// draws a horizontal line
void drawBase()
{
cout << " -------" << endl;
}
39
Order of Execution
int main()
{
drawCircle();
drawTriangle();
drawIntersect();
return 0;
}
void drawCircle()
{
cout << “ * “ <<
endl;
cout << “ * * “ <<
endl;
cout << “ * * “ <<
endl;
}
40
Function Advantages
–
–
–
–
–
Program team on large project
Simplify tasks
Each Function is a separate unit
Top-down approach
Procedural abstraction
• Main as collection of functions refined step by step
– Information hiding
• We need not know how a function is implemented
– Reuse (drawTriangle)
41
Abstraction
– Recall: Abstraction (here procedural)
• Refers to the act of ignoring details to
concentrate on essentials.
• Allows us to use complicated things with
little effort (CD players, automobiles,
computers).
42
3.5 Functions with Input
Arguments
– Functions used like building blocks
– Build systems one functions at a time
• Stereo Components
– Use function return values and arguments to
communicate between functions
– Example:
• rimArea = findArea(edgeRadius) + findArea(holeRadius)
43
Function Call
Form:
fname (actual arg list);
Example:
scale (3.0, z);
44
Function Return

Functions must return a value unless
declared as void
Form:
return expression;
Example: return x * y;
45
Function Definition
Form:
type fname (formal arg list)
{
function body
}
Example:
float scale(float x, int n)
{
float scaleFactor;
scaleFactor = pow(10, n);
return (x * scaleFactor);
}
46
Function Prototype
Form: type fname (formal arg type list);
Example: float scale (float x, int n);
47
TestScale.cpp
// File testScale.cpp
// Tests function scale.
#include <iostream>
#include <cmath>
using namespace std;
// Function prototype
float scale(float, int);
int main()
{
48
TestScale.cpp
float num1;
int num2;
// Get values for num1 and num2
cout << "Enter a real number: ";
cin >> num1;
cout << "Enter an integer: ";
cin >> num2;
// Call scale and display result.
cout << "Result of call to function scale
is " << scale(num1, num2) << endl;
return 0;
}
49
TestScale.cpp
float scale(float x, int n)
{
float scaleFactor;
scaleFactor = pow(10, n);
return (x * scaleFactor);
}
 This program acts as driver for testing the
scale function
 Unit test before integration test !!
50
Argument / Parameter List
Correspondence
– Functions can have more than 1 arg
– Correspondence between Actual & Formal
arguments
Function call scale (3.0, z);
Actual Argument
Formal Argument
3.0
x
z
n
51
Argument / Parameter List
Correspondence
float scale(float x, int n)
{
float scaleFactor;
scaleFactor = pow(10, n);
return (x * scaleFactor);
}
52
Argument / Parameter List
Correspondence
Function call scale (x + 2.0, y);
Actual Argument
x + 2.0
y
Formal Argument
x
y
53
Argument / Parameter List
Correspondence
Function call scale (y, x);
Actual Argument
y
x
Formal Argument
x
y
Watch for type matches in formal and actual
arguments
54
Key Points
 The
substitution of the value of an actual
argument in a function call for its
corresponding formal argument is strictly
positional. That is, the value of the first
actual argument is substituted for the first
formal argument; the second and so on
55
Key Points
 The
names of these corresponding pairs of
arguments are no consequence in the
substitution process. The names may be
different, or they may be the same.
 The substituted value is used in place of the
formal argument at each point where that
argument appears in the called function.
56
Key Points


Positional correspondence
Type consistent is key because of positional
correspondence
– Argument types
– Return types
57
Key Points


Type of a value returned by a called function
must be consistent with the type expected
by the caller as identified in the prototype
Type of an actual argument in a function
call must be consistent with the type of its
corresponding formal argument
58
3.6 Scope of Names




Scope of a name: Region of a program where the
name is visible and can be referenced
Variable declared in a function has a local scope
within the function
Same for variables declared in the main
Variable declared before main is global scope
– Call anywhere in program

Functions declared globally
59
Scope of Names
void foo1(int a1, float b1);
void foo2(int a2, float b2);
const int CONST = 100;
int main() {
int localMain;
…
}
void foo1(int a1, float b1) {
float local1= 12.98; …
}
void foo2(int a2, float b2) {
int local2= 10; …
}
Main
CONST
a1
b1
a2
b2
local1
local2
localMain
main
foo1
foo2
yes
no
no
no
no
no
no
yes
yes
yes
yes
foo1
foo2
yes
yes
yes
no
no
yes
no
no
yes
yes
yes
yes
no
no
yes
yes
no
yes
no
yes
yes
yes
60
3.7 Extending C++ through
Classes
– Discuss two classes
• String class part of compiler
• Money class is a user defined class
– #include <string>
– #include “money.h”
61
String Class







Declaring string objects
Reading & Displaying strings
Assignment & Concatenation
Operator Overloading
Dot Notation
Member Functions
Object Assignments
62
Declaring string Objects

A number of ways to declare
string firstName, lastName;
string wholeName;
string greeting = “Hello “;
63
Reading & Displaying string
Objects

Use extraction operator >> & the
stream cin for input
– cin >> firstName;

Use insertion operator << & the
stream cout for output
– cout << greeting << wholeName <<
endl;
64
Reading & Displaying string
Objects
getline (cin, lastName, ‘\n’);
reads all characters typed in from the
keyboard up to the new line into the
string object
65
StringOperations.cpp
// FILE: StringOperations.cpp
// ILLUSTRATES STRING OPERATIONS
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string firstName, lastName;
string wholeName;
string greeting = "Hello ";
cout << "Enter your first name: ";
cin >> firstName;
66
StringOperations.cpp
cout << "Enter your last name: ";
cin >> lastName;
// Join names in whole name
wholeName = firstName + " " + lastName;
// Display results
cout << greeting << wholeName <<
'!' << endl; cout << "You have " <<
(wholeName.length () - 1) <<
" letters in your name." << endl;
67
StringOperations.cpp
// Display initials
cout << "Your initials are " <<
(firstName.at(0)) <<
(lastName.at(0)) << endl;
return 0;
}
68
StringOperations.cpp
Program output
Enter your first name: Caryn
Enter your last name: Jackson
Hello Caryn Jackson!
You have 12 letters in your name.
Your initials are CJ
69
Assignment

Stores the first and last name
wholeName = firstName + “ “ +
lastName;

Concatenation
‘+’ joins the two objects together

“ “ for string values not ‘ ‘
70
Operator Overloading


‘+’ normally means addition but with strings
it means concatenation
The ‘+’ can take on many meanings
– Operator Overloading: performing different
operations depending on the used data type.
– C++ can have multi meanings to 1 operator
– >> & << are overloaded operators
– * / - == = all can be overloaded
71
Dot Notation

Dot notation used to call an objects member functions
int len = wholeName.length();
– Applies member function length to string object wholeName
– Function returns the objects length

Examples of other member functions:
– “first last”.find(“first”)  0
– “first last”.find(“last”)  6
– “first last”.insert(0, “Mr. “)  “Mr. first last”
– “Mr. first last”.replace(9, 1, “ middle “)  “Mr. first middle last”
– “Mr. first middle last”.erase(10, 7)  “Mr. first last”
– myTitle.assign(“Mr. first last”, 0, 3)  myTitle = “Mr.”
72
Money Class


Process money objects
Two attributes
– dollars
– cents

Why do this ?? Why not float ??
73
Money Class

Allocate a money object
– money creditLimit = 5000.00;

Assignments
– taxAmount = salePrice * taxPercent/100.0;
– finalCost = salePrice + taxAmount;
74
MoneyDemo.cpp
// FILE: MoneyDemo.cpp
// ILLUSTRATES MONEY OPERATIONS
#include <iostream>
#include "money.h"
using namespace std;
int main ()
{
// Local declarations
const float taxPercent = 6.25;
money creditLimit = 5000.00;
75
MoneyDemo.cpp
money salePrice;
money taxAmount;
money finalCost;
cout << "Enter item price: ";
cin >> salePrice;
// Compute tax amount
taxAmount = salePrice * taxPercent / 100.0;
// Compute final cost
finalCost = salePrice + taxAmount;
76
MoneyDemo.cpp
// Display
cout
cout
cout
cout
sales receipt
<< "Sales receipt" << endl;
<< "Price " << salePrice << endl;
<< "Tax
" << taxAmount << endl;
<< "Paid " << finalCost << endl <<
endl;
// Compute new credit limit
cout << "Your initial credit limit is " <<
creditLimit << endl;
creditLimit = creditLimit - finalCost;
cout << "Your new credit limit is " <<
creditLimit << endl;
return 0;
}
77
MoneyDemo.cpp
Program output
Enter item price: 345.77
Sales Receipt
Price $345.77
Tax $21.61
Paid $367.38
Your initial credit limit is $5,000.00
Your new credit limit is $4,632.62
78
Header and Implementation
Files

Header file (.h)
– File containing information that C++ needs to
compile a program that accesses a user-defined
class

Implementation file (.cpp)
– File containing the C++ code for the operators
of a user defined class
79
Another Example: Complex
numbers



Want to work with complex numbers?
C++ does not support them directly
Solution:
– Define a class “Complex”
– Overload operators: +, -, *, and so on so that
complex algebra works.
80
Complex numbers

Addition (pair notation)
(a, b) + (c, d) = (a+c, b+d)

Multiplication:
(a, b) * (c, d) = (a*c – b*d, a*d + b*c)

Program piece:
int main () {
Complex z, z1, z2;
…
z =z1*z2;
z1 = z1 + z2;
…
}
81
3.8 Common Programming
Errors
– Semicolon in Function Prototype (Declaration)
– Inconsistencies in Number of Arguments
• Too few arguments in a call
• Too many arguments in a call
– Argument Mismatch
• Correct position (formal & actual params)
82
Common Programming Errors
– Function Prototype & Definition Mismatches
• Both are the same except for the ;
– Return Statements
• “Return value expected”
• “Function should return value”
– Missing Object Name in Call to Member
Function
– Missing #include
– Type Mismatches
83
Download