Libraries Making Functions Globally Reusable ( 1

advertisement
Libraries
Making Functions Globally Reusable
(§ 6.4)
1
Review
We have written a program that used functions to
compute the area and circumference of ellipses.
area  ab
a
b
b
a
a b
circumference  2
2
2
2
2
Function Prototypes (placed before main()):
double ellipseArea(double length, double width);
double ellipseCircumference(double length, double width);
Function Definitions & Documentation
(placed after 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;
3
/* 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);
}
Putting these prototypes, documentation, and definitions
along with main() in the same program makes it possible to
reuse them at several different places in the program.
However, suppose that in order to solve some other
problem, a different program requires computing the area
and circumference of an ellipse.
4
Funcs call others Proj 5 area ->
perim Proj.6: many
How can we reuse our functions
in a different program?
Options:
• Copy-and-paste ellipseArea()
and ellipseCircumference()
from our previous program into
the new program.
• Store ellipseArea() and
ellipseCircumference()in a
library so that programs
can share them.
Is there
automatic
updating
of a program
if the original
functions are
modified?
No
Yes!
We also
have global
reusability.
5
OLE
Libraries
A library consists of three files:
Header
A header file (whose name has a
Files
.h suffix) that contains shareable
function prototypes and constants.
Source
An implementation file (whose name
Files
has a .cpp suffix) that contains shareable
function definitions.
A documentation file (whose name has
Resource
Files
a .txt (or .doc) suffix) that contains
documentation for the library.
In Visual C++, put all 3 and
the program that uses the
library in the same project.
6
6
What? How? Detailed what - user man.
Example
Since we are creating a library to
share functions that describe an ellipse,
we might name our library ellipse,
with
must be
• header file ellipse.h,
the same
• implementation file ellipse.cpp, and
• documentation file ellipse.txt.
Other Examples:
Text: Temperature conversion
Project: Metric conversion
7
Temp – good e.g. to look at
Header file: ellipse.h
In ellipse.h, we place the function prototypes:
Can use this same opening
documentation in all 3 files
but change
1st line
/*----- ellipse.h ----Library of functions for computing ellipse attributes.
L. Nyhoff
CS 104X
Jan 16, 2012
Note the
"directory"
Functions provided:
ellipseArea: compute area of an ellipse
ellipseCircumference: compute circumference of an ellipse
------------------------------------------------------------*/
double
double
// ...
// ...
ellipseArea(double length, double width);
ellipseCircumference(double length, double width);
plus any others we want to provide such as the
focal length, eccentricity, etc.
The corresponding implementation file ellipse.cpp and
any program that uses these functions must contain
#include "ellipse.h"
Metric
8
What? How? Detailed what - user man
opening doc: dict-ary;.cpp encyclop. publ
Implementation file: ellipse.cpp
Their definitions are placed in ellipse.cpp:
/*----- ellipse.cpp ----Library of functions for computing ellipse attributes.
L. Nyhoff
CS 104X
Jan 16, 2012
Functions provided:
ellipseArea: compute area of an ellipse
ellipseCircumference: compute circumference of an ellipse
------------------------------------------------------------*/
#include <cmath>
#include <cassert>
Put after
using namespace std;
using namespace std;
#include "ellipse.h"
const double PI = 3.14159;
// Could go in ellipse.h
double ellipseArea(double length, double width)
{
assert(length >= 0 && width >= 0);
double halfLength = length/2.0,
halfWidth = width/2.0;
return PI * halfLength * halfWidth;
}
9
#include .h - compiler check func protos
with defs. here; can chamge implem.
Implementation file (cont.)
double ellipseCircumference(double length, double width)
{
assert(length >= 0 && width >= 0);
double halfLength = length/2.0,
halfWidth = width/2.0;
return 2.0 * PI *
sqrt((halfLength * halfLength + halfWidth * halfWidth)/2.0);
}
//... plus definitions of any others we provide ...
This file can be compiled separately from any
program that uses it (called a client program).
Metric
10
Not build -- private
Documentation file: ellipse.txt
Our documentation file will be a copy of the
header file with function specifications
added for additional documentation.
/*----- ellipse.txt ----Library of functions for computing ellipse attributes.
L. Nyhoff
CS 104X
Jan 16, 2012
Functions provided:
ellipseArea: compute area of an ellipse
ellipseCircumference: compute circumference of an ellipse
------------------------------------------------------------*/
/*------------------------------------------------------Compute the area of an ellipse.
Receive: length, width, two double values.
Return: the area of the corresponding ellipse.
-------------------------------------------------------*/
double ellipseArea(double length, double width);
11
Documentation file (cont.)
/*------------------------------------------------------Compute the circumference of an ellipse.
Receive: length, width, two double values.
Return: the circumference of ellipse defined by
length and width.
-------------------------------------------------------*/
double ellipseCircumference(double length, double width);
// ... plus prototypes and specifications
// ... for any others we provide ...
By storing the documentation in a separate file,
we provide information on how to use the library
without cluttering the other library files.
Metric
But some programmers
do put the documentation
in the header file.
12
public
Program Translation
Translating a program into machine language
consists of two steps:
1. Compiling, in which the syntax of the
main program and of the implementation files
of any included libraries are checked, and if
no errors are found, converts them into
the computer’s machine language.
2. Linking, in which any calls to functions
(from main() or from other functions) are
bound to the definitions of those functions.
13
link: now defs outside program
compile & link diagram
Using a Library
To use a library:
A program must #include its header file
(usually above the main function and after
using namespace std;).
When the compiler (actually its
preprocessor) encounters this #include
directive, it must be able to find the header file
so it can open it and replace the #include
directive with its contents so they get compiled
along with the program.
When the file contains function prototypes, the
effect of the #include directive is to insert
those prototypes into the program.
In Visual C++:
Put it in the
project's header
files
Metric
14
In Visual C++:
It must also be able to find the
corresponding implementation file so
it can open it, insert the contents of
its header file into it, and then compile
it (separately from the program).
Put it in the
project's
source files
Once these compilations are successful, the linker
combines these compiled files into one, connecting
(i.e., "linking") each function call to the compiled
code of that function's definition.
A failure in either stage is an error.
15
Compilation Errors
A program calling a function for which
no prototype is given produces a
compiler error.
This can occur if you call a library function and
neglect to #include the header file containing its
prototype.
You’ll be trying to use a function that has not been
declared.
16
what proto does!
Linking Errors
A program calling a function for which the
linker cannot find a definition
produces a linker error.
This can occur if a program calls a function
but the linker is not told to use the library
implementation file or object file containing
that function’s definition.
How this is done varies from platform to
platform, but often involves a project file.
17
Example
#include <iostream>
using namespace std;
// cin, cout, <<, >>, ...
#include "ellipse.h"
// insert ellipse prototypes
Temperature
conversion
example in
the text
Put after
int main()
using namespace std;
{
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 an ellipse with major axis " << majorAxis
<< " meters and minor axis " << minorAxis << " meters\n"
<< "\tarea = " << area << " sq. meters\n"
<< "\tcircumference = " << circumference << " meters\n";
cout << "\nEnter major & minor axes (in meters) (0 0 to stop): ";
cin >> majorAxis >> minorAxis;
Metric
18
1>------ Rebuild All started: Project: EllipseLib, Configuration: Debug
Win32 -----1> ellipse.cpp
1> driver.cpp
1> Generating Code...
1> EllipseLib.vcxproj -> E:\CS10412Int\classprogs\EllipseLib\Debug\EllipseLib.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
EXECUTION:
Program to compute the area and circumference of ellipses.
Enter major & minor axes (in meters) (0 0 to stop): 2 2
For an ellipse with 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): 0 0
Press any key to continue . . .
19
Compilation creates a binary object file
(usually with a .o or .obj suffix) from a
.cpp file.
int main()
{
// ...
}
file.cpp
C++
Compiler
00100111010
10110001001
...
11101100100
file.obj
20
Linking binds multiple object files
into a single binary executable file
that can be executed by the operating system.
file1.obj
file2.obj
fileN.obj
00100111010
10110001001
...
11101100100
11100101011
10010001000
...
10101101101
01101101011
11010101001
...
00101100100
C++
Linker
00100111010
10110001001
...
11101100100
11100101011
10010001000
...
10101101101
01101101011
11010101001
...
00101100100
file.exe
21
OCD with Libraries
1. Specify the desired behavior of the program.
2. Identify the objects needed.
3. Identify the operations.
Extending
a. If an operation is not predefined:
C++
Write a function to perform it.
b. If an operation is likely to be reusable someday:
Store its function in a library and access it from there.
4. Organize objects and operations into an algorithm.
22
/*----- ellipse.h ----Library of functions for computing ellipse attributes.
L. Nyhoff
CS 104X
Jan 16, 2012
Functions provided:
ellipseArea: compute area of an ellipse
ellipseCircumference: compute circumference of an ellipse
------------------------------------------------------------*/
double
double
// ...
// ...
ellipseArea(double length, double width);
ellipseCircumference(double length, double width);
plus any others we want to provide such as the
focal length, eccentricity, etc.
23
/*----- ellipse.cpp ----Library of functions for computing ellipse attributes.
L. Nyhoff
CS 104X
Jan 16, 2012
Functions provided:
ellipseArea: compute area of an ellipse
ellipseCircumference: compute circumference of an ellipse
------------------------------------------------------------*/
#include <cmath>
#include <cassert>
using namespace std;
#include "ellipse.h”
const double PI = 3.14159; // Could go in ellipse.h
double ellipseArea(double length, double width)
{
assert(length >= 0 && width >= 0);
double halfLength = length/2.0,
halfWidth = width/2.0;
}
return PI * halfLength * halfWidth;
double ellipseCircumference(double length, double width)
{
assert(length >= 0 && width >= 0);
double halfLength = length/2.0,
halfWidth = width/2.0;
return 2.0 * PI *
sqrt((halfLength * halfLength + halfWidth * halfWidth)/2.0);
}
//... plus definitions of any others we provide ...
24
double ellipseCircumference(double length, double width)
{
assert(length >= 0 && width >= 0);
double halfLength = length/2.0,
halfWidth = width/2.0;
return 2.0 * PI *
sqrt((halfLength * halfLength + halfWidth * halfWidth)/2.0);
}
//... plus definitions of any others we provide ...
25
Download