Date post: | 18-Dec-2015 |
Category: |
Documents |
View: | 219 times |
Download: | 0 times |
COIT29222-Structured Programming
Lecture Week 10
Reading: Study Guide Book 2, Module 12 Study Guide Book 3, Module 2
This week, we will cover the following topics:Multi-file program developmentCode Reuse
Multi-file program development: Separating a program into files
Each program we have written so far has been encapsulated in a project and saved as a single file with a .cpp file name extension
But we can separate parts of a program into different files.
The most common way to do this for a small program is to separate it into 3 parts:– The main– Function prototypes and any globally defined
constants– The function definitions
Separating a program into three files
Header filehas function prototypes
Function definition file has definitions of
functions used by main
Main filecontains the main
program
Encapsulated in a C++ project
Why separate a program into multiple files?
If we can separate the main from the function definitions then it allows us to make a collection of functions that can be used by more than one program.
It allows us to reuse code (functions) that have been previously written.
It means we do not need to re-invent the wheel by re-writing functions that others have spent a lot of time writing
Standard Library functionsWe already know that C++ comes with standard
functions that are stored in standard libraries.For Example: To use cout and cin we #include <iostream> To use strings we #include <string> To use isspace() we #include <cctype> The #include precompiler directive causes the
compiler to look for functions which we have used in our program but defined externally (in a separate file), to be inserted into our program.
User-defined function library In the same way that standard libraries
are created and used, we can create our own function library which will contain functions that can be reused (used by more than one program
Once we have the function library we can #include its name in our program whenever we use any function contained in this library
How is it done ? Download stats.cpp from the course web
page - a program that used an array to calculate the average, frequency and mode of a set of scores.
Compile and run it. We’re going to break this program into 3
files:1. statsHeaders.h – contains function
prototypes2. statsDefs.cpp – contains function
definitions3. statsMain.cpp – the main
Contents of statsHeaders.h file
//Prototypes for the stats functionsvoid findFreq(int scores[], int frequency[], int
&mode);float aveScores(int scores[]);int findMode(int frequency[]);const int size = 20; // globally defined constant
include "statsHeaders.h"void findFreq(int scores[], int frequency[], int &mode){
for(int i=0;i<size;i++)++frequency[scores[i]];
} float aveScores(int scores[]){
float total = 0.0;for(int i = 0; i<size;i++)
total = total + scores[i];return (total/size);
}int findMode(int frequency[]){ int mode = 0;
for(int i = 1; i<7;i++)if(frequency[i]>mode)
mode = i;return mode;
}
Contents of statsDefs.cpp
file
Header file must beincluded in this file
Contents of statsMain.cpp file#include <iostream>using namespace std;#include "statsHeaders.h"void main(void){
int scores[size] = {1,5,6,3,4,2,6,5,3,5,2,4,5,6,6,6,3,1,2,6};int frequency[7] = {0},mode = 0;float average = 0.0;average = aveScores(scores);cout <<"The average score is "<<average<<endl<<endl;findFreq(scores, frequency, mode);for(int i=1;i<7;i++)
cout<<"The frequency of score "<<i<<" is = "<<frequency[i]<<endl;mode = findMode(frequency);cout << "\nMode is "<< mode<<endl;
}
Header file includedin this file
Putting it all together
1. In Visual C++, all files must be placed in a project for the program to work
2. Then the function library files ( statsDefs.cpp in our case) are compiled in turn
3. The main program (also called the driver) is then compiled
4. The project is then built – in this process, the compiled object codes from the function libraries are linked to the main
5. Resulting executable code is then run!
Try it out
The three files – statsHeaders.h– statsDefs.cpp– statsMain.cpp
for the project are on the course web page. Download them and use the above procedures
to put the program together and then run it.
Your project should look like the one shown here
Header file is includedin main()
Program consists of 3 files in the form of a project
Software Reuse
Software reuse is the reuse of some previously constructed software item in a new context. Can be applied to all facets of the software development
process, including:Project plans/strategies, system designs/models,
skeletons for documentation, testing plans, etc.Code reuse
"pluggable" components/executable objects,
libraries, routine reuse within/across modules
Software Reuse Why reuse software items?
Use for efficiency and thus profitability Capitalise on the similarity of software systems,
rather than build systems from scratch
Advantages of software reuse Reduction in development costs Reduction in maintenance costs Increased system reliability (or quality)
Assuming the item being reused has been rigorously tested in its original context
Effective Software Reuse
Requires organisation and a budgetRequires a policy involving all levels of the
software development life cycle to:Identify & reuse existing componentsBuild reusable components
Time consuming & costlyBut investment repaid with each reuse
of a component & whenever it undergoes maintenance, since all uses reap the benefits
Code Reuse
Modularisation is at the heart of code reuse The process of breaking a system up
into smaller, more manageable chunks Allows a programmer to concentrate on
the details of a particular task while thinking only abstractly about the other "chunks" that make up the entire system
Enables software developers to better manage the inherent complexity of the overall system
Modularisation: Decomposition into Sub-tasks
Sub-tasks in a system
A sub-task has 2 logically separate parts:Interface
Describes what the sub-task does & how its service can be used by other sub-tasks in the system
Visible to other sub-tasks in the systemImplementation
Defines the steps involved in achieving the functionality of the sub-task
Ideally hidden from other sub-tasks in the system
Modular decomposition in C++
Decomposition into sub-tasks (in this course) occurs at the level of C++ functions:– called functional decomposition
C++ functions:– interface:
function prototype– implementation:
function implementation
Libraries
Reusable code is generally held in libraries:Standard libraries
Usually part of the programming language definition
Provide functionality common to many programs
Third-party librariesPortability issues must be considered prior
to acquisitionLibraries developed “in house”
A software project
A software project will generally consist of:A set of libraries
The code stored in libraries is generally compiled code or object code
Code written to accomplish the project’s taskUsually separated into discrete files called
compilation unitsCompilation units are compiled into object code with
a program called a compiler
Compilation
A large project will typically consist of:
a set of compilation units, compiled into object code
a set of object code libraries
LinkageA project’s object files (compilation units &
libraries) are linked into a single executable program.Static linkage
Object files linked prior to program execution
Dynamic linkagePerformed after a program has been loaded
into memory for execution Dynamic/shared libraries e.g. dll’s
Compilation & (Static) Linkage for a Project
Advantages of Dynamic over Static Libraries
Changes to (the implementation part of) a dynamic library do not require re-generation of a project's executable file
One copy of a dynamically linked library can be shared by many running programs
Dynamic libraries are more storage
efficient than static libraries
C++ Standard Libraries
The C++ standard libraries form part of the C++ programming environment. Incorporated into the ISO/ANSI C++
language standard They provide common fundamental data
structures together with fundamental algorithms to be used on them
Code reuse use C++ standard library functions instead of writing new functions
Categorisation of C++ Standard Libraries
Include header files to use C++ library services
The interfaces to a group of related C++ library services are gathered together into a header file. To use a particular library service, its associated
header file must be included in the client program - Example:
#include <iostream> // required for use of cout using namespace std; void main(void){
cout << "Hello there!\n"; // use of object, cout}
Include header files to use C++ library services
The header file associated with a particular service contains the declarations &/or definitions required to use the service.
The include directive includes those declarations &/or definitions in the client program at the position of the directive.
If the iostream header file is not included in the program of the previous slide, the object cout would be undefined a compile-time error.
The std namespace The names/identifiers in the C++ standard
libraries are defined in the std namespace.
An identifier in a C++ program is visible (can be used) in a certain scope.
Different uses of the same identifier in a scope can cause a conflict.
Namespaces a means of avoiding such conflicts.
Each namespace itself has a name and it defines a scope for identifiers in that namespace
An identifier can be uniquely specified by qualifying it with its namespace name.
The std namespaceTo make all the names in the std namespace global:
using namespace std;considered poor programming practice, especially in large
programsAlternatively, names can be qualified with their
namespace identifier:#include <iostream> // required for use of cout void main(void){
std::cout << "Hello there!\n";}
The std namespace
Alternatively, explicit using statements can be used:
#include <iostream>
// make the name, cout, from the std // namespace, global
using std::cout;
void main(void)
{
cout << "Hello there!\n";
}
Using C++ Standard Library Services
Before using a C++ library function be sure you understand its interface:What needs to be passed into the
function via its parameter listWhat the function returns, via its
parameter list &/or as the function return value
Note which header file must be included to use the library service.
Character testing & case- conversion functions
To use these functions, include the header file:
#include <cctype> The character-handling functions take an
int parameter representing the character to be tested:Valid arguments are in the range 0..255 & EOFPassing an argument of type char to these
functions may yield unpredictable results
toupper() functionFunction prototype: int toupper(int ch);
– if ch is a lower-case letter, returns the upper-case equivalent, else returns ch
– Example:
// loop until user enters Y,y,N or ndo {// display prompt and get responsecout << "Continue (Y/N)?";cin >> Response;
// convert Response to upper caseUpperCaseResponse = toupper(Response); …/cont’d
toupper() function
// display error message if response// was invalidif (UpperCaseResponse != YES &&
UpperCaseResponse != NO)cout << "Enter Y, y, N or n"
<< endl;} while (UpperCaseResponse != YES && UpperCaseResponse != NO);
isspace(), isalpha() & isdigit() functions
int isspace(int ch);returns non-zero (indicating true) if ch is a white
space character (space, tab, newline etc), otherwise zero (indicating false)
int isalpha(int ch); returns non-zero (true) if ch is a letter, otherwise
zero (false)int isdigit(int ch);
returns non-zero ( true)if ch is a digit, otherwise zero (false)
Example: isspace(), isalpha() & isdigit()
// read the first characterch = cin.get(); // loop until a non-white space char readwhile (!isspace(ch)){
// if char is a digit, increment NumDigitsif (isdigit(ch))
NumDigits++;else
// if char alphabetic, incr. NumAlphaif (isalpha(ch))
NumAlpha++; // read the next characterch = cin.get();
}
Random Number Generation The element of chance is common to
applications which simulate coin tossing, card playing, dice rolling and the random occurrences in computer games.
The element of chance introduced into computer programs by random number generation. Egs:A random number in the range 1..6 can
simulate the roll of a die2 random numbers in ranges 1..13 (value) &
1..4 (suit) can simulate the random draw of a playing card
Random Number Generation To introduce the element of chance into C++
programs, use the rand() & srand() functions from <cstdlib> library#include <cstdlib> int rand(void);
Returns a random number as an int in the range 0 to RAND_MAX (a named constant defined in the <cstdlib> header file).
void srand(unsigned int seed); Sets the starting point for generating a series of
random integers A seed argument of 1 reinitialises the generatorAny other value for seed sets the generator to a
random starting point
Random Number Generation
For a given application, the required range of randomly generated values will differ – E.g.:– range: 1..6, when throwing a die– range: 0..1, when tossing a coin
The modulus operator (%) can be used to map the values generated from the rand() function (0 .. RAND_MAX) onto the set of valid random values for the current application. For Examplerand() % 6- will return values in the range 0..5 rand() % 6+1-will return values in the range 1..6
Example: random rolls of a die
#include <iostream> // for cout, endl#include <cstdlib> // for rand(), srand() using std::cout;using std::endl; const int MAX_DIE = 6, // sides on a die
MAX_ROLLS = 10; // times rolled void main( void ){ // Display MAX_ROLLS rolls of a die for (int i = 0; i < MAX_ROLLS; i++ ) cout << (rand() % MAX_DIE + 1) << " "; cout << endl;}
Seeding the random number generator
The srand() library routine is used to seed the rand() function a different sequence of random numbers generated with each execution of the program. Commonly achieved by passing the current time in seconds
(according to the system clock) as argument to the srand() function.
The time() function from the <ctime> library can be used for this purpose. The expression:
static_cast<unsigned>(time(NULL))
is passed to the srand() function
Example: random rolls of a die#include <iostream> // for cout, endl#include <cstdlib> // for rand(), srand()#include <ctime> // for time() using std::cout;using std::endl; const int MAX_DIE = 6, // sides on a die
MAX_ROLLS = 10; // times rolled void main( void ){// Seed the random number generator srand(static_cast<unsigned>(time(NULL)));
// Display MAX_ROLLS rolls of a die for (int i = 0;i < MAX_ROLLS; i++ )
cout << (rand() % MAX_DIE + 1) << " "; cout << endl;
}
C++ #include directive The C++ pre-processor replaces an #include
directive with the contents of the specified file.
#include directive takes 2 forms:
#include "path_and_file" Path specified relative to the current directory
#include <path_and_file> Path specified relative to the directory to which the compiler is configured to look for the standard library header files
Example: areas compilation unit -interface (areas.h)
// interface: calc. areas of geometric shapes#ifndef AREAS_H // avoid multiple inclusions#define AREAS_H // of this file
const float PI = 3.142F; // named const. for pi // function interfaces (prototypes)float AreaSquare(float Side); // area square // of given Side
float AreaCircle(float Diameter); //area circle // given Dia.
#endif
#ifndef, #define & #endif directives
These directives used to prevent multiple inclusion of given header file in a compilation unit.
The first time an attempt is made to include areas.h:#ifndef AREAS_H is true (AREAS_H not defined)
compilation of code up to #endif directive#define AREAS_H, defines AREAS_H
Subsequent attempts to include areas.h:#ifndef AREAS_H is false code to #endif ignored
Example: areas compilation unit – implementation (areas.cpp)
#include "areas.h" // include interface
float AreaSquare(float Side) // area of square // of given Side
{ return(Side * Side);} float AreaCircle(float Diameter) // area circle // given Dia.
{ float Radius; Radius = Diameter / 2.0; return(PI * Radius * Radius);
}
Summary
In this lecture, we have covered the following things:• Reasons for separating a program into multiple
files• What is involved in the separation process• How this separation process is done in Visual C++• How (why) to reuse software/code• How to use standard libraries and include
directives• How to generate random numbers