Introduction to Programmer-Defined Functions Creating Reusable Operations (§5.1 - §5.3)

advertisement
Introduction to
Programmer-Defined Functions
Creating Reusable Operations
(§5.1 - §5.3)
1
Problem
The playing field (actually called a
"pitch") for Australian Rules Football
field is an ellipse whose (ideal)
dimensions are 165m x 135m.
A team owner is planning to put
artificial turf on the field and a
running track around the outside
and would like to know, therefore,
the area and the circumference of
the field.
Our task: Write a program that
computes the area and the
circumference of the field.
2
Problem Generalization
Generally, a program should solve a collection of
problems rather than just one specific one. So we
reformulate our task:
Design a program that computes the area and
circumference for any number of ellipses.
area = pab
b
a
Project
1.3
b
a
a2 + b2
circumference = 2p
2
3
Text: temperature conversion
Algorithm
1. Display via cout the program information.
2. Loop:
a. Display a prompt for the major and minor axes of an ellipse.
b. Read majorAxis, minorAxis from cin.
c. Compute semiMajor = majorAxis / 2.0 and
semiMinor = minorAxis / 2.0.
d. Compute area = PI * semiMajor * semiMinor.
e. Compute circumference = 2.0 * PI *
sqrt((semiMajor 2 + semiMinor 2) / 2.0).
f. Display area and circumference with descriptive labels.
End Loop
4
Coding
PROGRAM DOCUMENTATION GOES HERE
#include <iostream>
#include <cmath>
using namespace std;
// cin, cout, <<, >>, ...
// sqrt(), pow(), ...
int main()
{
cout << "Program to compute the area and circumference of ellipses.\n";
const double PI = 3.14159;
Ellipse
Computations
double majorAxis, minorAxis;
cout << "\nEnter major & minor axes (in meters) (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
while (majorAxis > 0)
{
double semiMajor = majorAxis/2.0,
semiMinor = minorAxis/2.0;
double
area
minorAxis);
double area =
= ellipseArea(majorAxis,
PI * semiMajor * semiMinor
;
double circumference = ellipseCircumference(majorAxis,
minorAxis);
2.0 * PI * sqrt(
(semiMajor * semiMajor + semiMinor * semiMinor) / 2.0);
}
}
cout << "\nFor major axis " << majorAxis << " meters, minor axis "
<< minorAxis << " meters\n"
<< "\tarea = " << area << " sq. meters\n"
<< "\tcircumference = " << circumference << " meters\n";
cout << "\nEnter ellipse's major & minor axes (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
5
Note the while
Encapsulate in funcs so can reuse
Testing
Program to compute the area and circumference of ellipses.
Enter major & minor axes (in meters) (0 0 to stop): 2 2
For major axis 2 meters and minor axis 2 meters
area = 3.14159 sq. meters
circumference = 6.28318 meters
Enter major & minor axes (in meters) (0 0 to stop): 8 6
For major axis 8 meters and minor axis 6 meters
area = 37.6991 sq. meters
circumference = 22.2144 meters
Solve Problem
Enter major & minor axes (in meters) (0 0 to stop): 165 135
For major axis 165 meters and minor axis 135 meters
area = 17494.7 sq. meters
circumference = 473.589 meters
Enter major & minor axes (in meters) (0 0 to stop): 0 0
6
test: circle radius 1;
2nd: approx. 7pi ~ 22
Improving Reusability
We’ve done a fair amount of work in creating
these formulas, but we have no way to
directly reuse our work if we ever need to
use these ellipse-related formulas again.
Solution: Rewrite those formulas as functions.
Why use functions?
• Improve code
reusability
• Implement new
operations
• Modularize complex
programs
large-scale reuse
Put functions
in a library
7
What's Necessary to Use a
Function in a Program?
• The function must have a name; we will use
the same naming convention for functions as
we do for variables.
• Like mathematical functions, we must be able
to pass values (called arguments) to
the function.
We do this using expressions of the form
functionName(list-of-arguments)
and we refer to this as calling the function.
8
User perspective: needs to know: name: sqrt, pow, floor
# & types of args; what returns and type
An Aside
Why "call" a function?
One reasonable explanation: In the 1960s when scientists at IBM were
developing the Fortran programming language and using it to write
programs for scientific problems, they often needed some
mathematical function, e.g., a trig function such as sine. Since code for
computing values of such functions (using infinite series) was
nontrivial, a programmer would write it down and keep it in a notebook
so he could look it up and copy it into a program when needed.
If some other programmer needed one of these functions, she might
remember that Joe had the code in his notebook, and she would call
out, "Hey Joe, I need your sine function!"
As this began to happen more and more frequently, creating more
and more of a disturbance, these notebooks containing code for
commonly used functions were placed in the company's library where
programmers could get them and insert the code into their program.
Today, we still use this language of calling functions, and (as we'll
see later) we can put them in a library from where they can be
automatically retrieved and included in a program.
9
• The function must have some way to receive
the arguments passed to it. For this, the function
uses a list of variables called parameters that
will store these values.
• The function must also be able to return a value
that it computes. We can then use this value; for
example, assign it to a variable:
var = functionName(list-of-arguments);
• In order to use this value returned by the function,
we must know its type. So a function must also
specify what type of value it returns.
10
Function perspective: params to receive values;
return mechanism; specify return type; pow DIAGRAM
Function Prototypes
A declaration of a variable (or constant) gives it a name
and specifies what it does (e.g., stores a double).
A function must also be declared to name it and to
specify what it does (but not how it does it):
• What it receives
• What it returns
This is called the function's prototype.
Note the
semicolon!
Pattern for a prototype:
ReturnType name (parameter-declarations);
void if nothing
is returned
A valid identifier
May be empty
11
main() - empty; returns to OS;() indicate
function - not variable; void: later return > 1 value
A function's prototype must precede any call to
that function by another function — by main(),
in particular — (as well as any definition of that
function), or a compiler error will occur.
• Usually prototypes are put ahead of main(), after
the #includes and using namespace std;
This makes them available throughout the entire
program.
• Their order is irrelevant — it need not be the same
as the order in which they called (or the order in
which they will be defined).
12
like var - declare before use;
Example: Ellipse Computations
PROGRAM DOCUMENTATION GOES HERE
#include <iostream>
// cin, cout, <<, >>, ...
#include <cmath>
// sqrt(), pow(), ...
prototypes
using namespace std;
double ellipseArea(double length, double width);
double ellipseCircumference(double length, double width);
int main()
{
cout << "Program to compute the area and circumference of ellipses.\n ";
}
double majorAxis, minorAxis;
cout << "\nEnter major & minor axes (in meters) (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
while (majorAxis > 0)
{
double area = ellipseArea(majorAxis, minorAxis);
double circumference = ellipseCircumference(majorAxis, minorAxis);
cout << "\nFor major axis " << majorAxis << " meters, minor axis "
<< minorAxis << " meters\n"
<< "\tarea = " << area << " sq. meters\n"
<< "\tcircumference = " << circumference << " meters\n";
cout << "\nEnter ellipse's major & minor axes (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
}
13
#include <cmath> inserts prototypes of pow, etc.
Can omit param names -- bad idea
Once the prototypes are in place, a program that calls
the functions can be compiled (but not linked yet).
The compiler will only check that the functions are
being used correctly:
• Same number of arguments as parameters
• Type of each argument and the type of the
corresponding parameter are compatible
• Return value of function is used correctly
Argument names need not be different from the
parameter names. For example, we could use:
double ellipseArea(double majorAxis, double minorAxis);
double ellipseCircumference(double majorAxis, double minorAxis);
14
Compiler only needs the "what", not "how" - proc. abstr.
Linker needs 'how' where fun's code is to LINK a call to it.
May not know param names -- e.g., pow
Function Definitions
Our program cannot be executed yet because
prototypes only tell what functions do, not how
they do it. If we attempt to build (compile &
link) the program, we will get a linker error,
because the linker’s job is to connect each function
call with the code for that function’s definition.
This means that we must provide definitions
of the functions. Each one will contain statements
that dictate the function’s behavior when it is called.
ellipse0
15
ellipsedemo1
Pattern of function definition:
Return type, name, and
parameter types must
match those in prototype.
DOCUMENTATION
returnType name(parameter-declarations)
{
Note: No
statementList
semicolon!
}
The documentation describes what the function does,
what it receives, what it returns, and other information.
These definitions can be added to the program after
main()(but we will see later how to put them and their
prototypes in separate files called a library).
16
param names need not match -- but usually do
Copy prorotype and remove ; for heading
// end of main()
const double PI = 3.14159;
/* Function to compute the area of an ellipse
Receive: two double values length, width, representing
the major axis and minor axis of an ellipse
Return: the area of the ellipse
---------------------------------------------------------*/
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
17
/* Function to compute the circumference of an ellipse
Receive: two double values length, width, representing
the major axis and minor axis of an ellipse
Return: the circumference of the ellipse
---------------------------------------------------------*/
double ellipseCircumference(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return 2.0 * PI * sqrt(
(halfLength * halfLength + halfWidth * halfWidth) / 2.0);
}
• The order of the definitions is irrelevant; it need not
match the order of the prototypes.
ellipse1
See the start of program for Project 4 at
the end of these slides for another example.
18
23
29
How Function Calls Work
When a function is called, its caller can pass to it
values called arguments. These values are
copied and stored in the function's parameters.
main()
double area = ellipseArea(majorAxis, minorAxis);
165
135
165
135
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
19
Execution of the calling function (main()) is
then suspended and the called function
(ellipseArea()) begins execution using its
parameter values.
main()
double area = ellipseArea(majorAxis, minorAxis);
165
135
165
135
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
20
The values of the local variables halfLength
and halfWidth are calculated and then used in
the expression that calculates the area.
When the return statement is encountered:
• The value computed by the called function is
passed back to the caller (main()).
main()
double area = ellipseArea(majorAxis, minorAxis);
165
135
165
135
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
21
• Execution of the called function is terminated.
• Execution of the caller (main()) resumes using
the returned value to assign a value to area .
main()
double area = ellipseArea(majorAxis, minorAxis);
double circumference =
ellipseCircumference(majorAxis, minorAxis);
165
135
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
When the next statement is encountered,
execution proceeds in a similar manner with the
function ellipseCircumference().
22
29
Example of a void function:
PROGRAM DOCUMENTATION GOES HERE
#include <iostream>
#include <cmath>
using namespace std;
Project 5
Use a void function
to output results.
// cin, cout, <<, >>, ...
// sqrt(), pow(), ...
double ellipseArea(double length, double width);
double ellipseCircumference(double length, double width);
void display(double length, double width
double area, double circumference);
int main()
{
cout << "Program to compute the area and circumference of ellipses.\n";
}
double majorAxis, minorAxis;
cout << "\nEnter major & minor axes (in meters) (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
while (majorAxis > 0)
{
double area = ellipseArea(majorAxis, minorAxis);
double circumference = ellipseCircumference(majorAxis, minorAxis)
display(majorAxis, minorAxis, area, circumference);
cout << "\nEnter ellipse's major & minor axes (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
}
23
// DEFINITIONS OF ellipseArea() AND ellipseCircumference()
// GO HERE OR AFTER DEFINITION OF display()
/* Void function to output information about an ellipse.
Receives:
axes of ellipse (in meters), its area and
circumference (in square meters)
Returns:
nothing
Outputs:
axes, area, and circumference with labels
----------------------------------------------------------*/
void display(double length, double width,
double area, double circumference)
{
cout << "\nFor an ellipse with major axis "<< length
<< " meters and minor axis " << width << " meters:\n"
<< "\tarea = " << area << " sq. meters\n"
<< "\tcircumference = " << circumference << " meters\n";
}
19
24
Program Structure
C++ programs typically follow this pattern:
#include directives
Function prototypes
Main function
Function definitions
OCD with Functions
1. Specify the desired behavior of the program.
2. Identify the objects needed.
3. Identify the operations.
a. If any operation is not predefined:
Write a function to perform it.
4. Organize objects and operations into an algorithm.
25
#include <iostream>
#include <cmath>
using namespace std;
// cin, cout, <<, >>, ...
// sqrt(), pow(), ...
double ellipseArea(double length, double width);
double ellipseCircumference(double length, double width);
void display(double length, double width
double area, double circumference);
int main()
{
cout << "Program to compute the area and circumference of ellipses.\n";
double majorAxis, minorAxis;
cout << "\nEnter major & minor axes (in meters) (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
while (majorAxis > 0)
{
double area = ellipseArea(majorAxis, minorAxis);
double circumference = ellipseCircumference(majorAxis, minorAxis);
display(majorAxis, minorAxis, area, circumference);
cout << "\nEnter ellipse's major & minor axes (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
}
}
26
const double PI = 3.14159;
/* Function to compute the area of an ellipse
Receive: two double values length, width, representing
the major axis and minor axis of an ellipse
Return: the area of the ellipse
---------------------------------------------------------*/
double ellipseArea(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
/* Function to compute the circumference of an ellipse
Receive: two double values length, width, representing
the major axis and minor axis of an ellipse
Return: the circumference of the ellipse
---------------------------------------------------------*/
double ellipseCircumference(double length, double width)
{
double halfLength = length/2.0,
halfWidth = width/2.0;
}
return 2.0 * PI * sqrt(
(halfLength * halfLength + halfWidth * halfWidth) / 2.0);
27
/* Void function to output information about an ellipse.
Receives:
axes of ellipse (in meters), its area and
circumference (in square meters)
Returns:
nothing
Outputs:
axes, area, and circumference with labels
----------------------------------------------------------*/
void display(double length, double width,
double area, double circumference)
{
cout << "\nFor an ellipse with major axis "<< length
<< " meters and minor axis " << width << " meters:\n"
<< "\tarea = " << area << " sq. meters\n"
<< "\tcircumference = " << circumference << " meters\n";
}
28
/* This is a driver program to test the following
triangle-processing functions:
triangle() -- checks if 3 lengths can form a triangle
==> ADD NAMES & DESCRIPTIONS OF OTHER FUNCTIONS HERE
Input: Three sides of a triangle
Output: The boolean values returned by the functions
==> ADD YOUR NAME, DATE, COURSE & SECTION, PROJECT # HERE
------------------------------------------------------------*/
#include <iostream>
using namespace std;
// FUNCTION PROTOTYPES GO HERE
bool triangle(double sideA, double sideB, double sideC);
int main()
{
// ADD STATEMENTS TO OUTPUT PROGRAM INFO AND YOUR INFO HERE
double side1, side2, side3; // possible sides of a triangle
// LOOP
cout << "Enter three legs of a triangle: ";
cin >> side1 >> side2 >> side3;
29
cout << "Sides form a triangle --- " << boolalpha
<< triangle(side1, side2, side3) << endl;
// STATEMENTS TO TEST OTHER FUNCTIONS GO HERE
//END LOOP
} // end of main()
// FUNCTION DEFINITIONS GO HERE
/* Function to determine if 3 lengths form a triangle
Receive: three double values sideA, sideB, sideC,
representing three sides of a triangle
Return: true if triangle can be formed, false otherwise
-----------------------------------------------------------*/
bool triangle(double sideA, double sideB, double sideC)
{
bool isaTriangle = (sideA + sideB) > sideC &&
(sideA + sideC) > sideB &&
(sideB + sideC) > sideA;
return isaTriangle;
}
// ADD YOUR FUNCTION DEFINITIONS HERE
30
31
Download