|
course.wilkes.edu/CS125Labs |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Lab 3b: Controlling Function Behavior
IntroductionToday's lab explores some C++ statements that we can use to write more sophisticated functions. The exercise consists of two parts: In the first part, we examine a problem whose solution requires more complicated behaviors than we have seen thus far, and introduce the new statements to elicit that behavior. In the second part, we introduce a new program-development tool called the debugger and use it to study the behavior of the new statements.
Part I: The Payroll ProblemOur problem today is to write an interactive payroll program, that a small-business owner might use to simplify computing the payroll at his or her business. For the sake of simplicity, we will assume that all employees at the business are hourly employees. Recall that object-centered design involves several stages:
Once we have our design, we can encode it in a programming language, test and debug the resulting program, and then perform any maintenance required over its lifetime. Today's exercise is to use these stages to develop a program that solves our payroll problem.
Preparing Your Workspace
Begin by creating a directory for this exercise (e.g.,
DesignAs always, spending a bit of time planning how to attack our problem will result in a better solution. To do so, we follow the steps of object-centered design. Behavior. We can begin by visualizing and writing down how we want our program to behave. One approach is to have our program behave something like the following: This program computes the payroll interactively.Put into words, our program should display on the screen a greeting, followed by a prompt for the number of employees, which it should then read from the keyboard. For each employee, our program should then display a prompt for their name, hours and rate of pay. The program should then read these values from the keyboard, and compute and display the employee's pay, along with their name. Objects. If we identify the nouns in this behavioral description, we get the following list:
From this list, we can build a precise specification of how our program is to behave:
Input: The number of employees;
Each employee's name, hours of work, and rate of pay.
Output: Each employee's name and pay.
Use this information to complete the specification of payroll.cpp.
Operations. If we identify the operations in our behavioral description, we get this list:
As indicated, most of these operations are provided for us by C++.
Operations 1-4 and 6 should be familiar by now.
There is no predefined C++ capability to perform operation 5,
and since accounting for overtime pay makes it non-trivial,
we will write a function to perform this operation.
Since it seems like an operation that might be useful again some day,
we will store it in a library.
Finally, operation 7 involves a new C++ statement that we haven't seen before
called the Algorithm. Even without knowing the details of how we will compute the pay, we can organize our operations into an algorithm for our problem:
Coding, Testing and DebuggingOnce we have designed an algorithm to solve our problem, we must encode that algorithm in the a high level programming language (i.e., C++). We can begin this process by constructing a minimal C++ program, consisting of int main() true(These lines are already present in payroll.cpp,
after its opening documentation.)
To make sure that this much is correct before we add to it,
take a moment to translate payroll.cpp.
To facilitate the translation, we have provided a complete Makefile,
so use the compile command and make to perform the translation:
Compile command: make -kIf you examine the Makefile, you will note that each call to g++
uses the -g switch, which tells g++ to save the information
needed by the GNU debugger (discussed below).
This switch must be used to compile and link in order for the debugger
to be used.
Given the minimal C++ program, we are ready to encode our algorithm using stepwise translation. We therefore begin with the first step:
1. Via Coding: This step can be performed using a C++ output statement, which we have seen before: cout << Value1 << Value2 << ... << ValueN;so add an output statement to payroll.cpp
that displays the following message:
This program computes the payroll interactively.Don't forget the #include <iostream>
and using namespace std; directives!
Before proceeding to the next step, check the correctness of what you just wrote by retranslating your program. The compiler will alert you to any syntax errors in your statement. If an error is listed, you can infer that the error(s) lies in the text ' you just added, since the program was error-free before that. Find your error(s) within those lines and use the editor to correct them.
When your source program compiles correctly, execute
2. From Coding: We can encode this step in C++ using an input statement: cin >> Var1 >> Var2 >> ... >> VarN;Add an input statement to your source program to perform step 1. Don't forget to declare a variable to store numberOfEmployees! Check that what you have added is free of syntax errors before continuing.
Note that we could use an
3. For each value empNum in the range 1 to numberOfEmployees: Coding: Let's take this step a piece at a time, starting with the outer part (3) and then doing the inner parts (a-d).
3. For each value empNum in the range 1 to numberOfEmployees: The purpose of step 3 is to count from 1 to the number of employees, and repeat steps a[not equal]d that many times. That is, if there are three employees, then steps a[not equal]d should be repeated three times.
For situations like this that require repetitious behavior,
C++ supplies the
for (Type loopVar = firstValue; loopVar <= lastValue; loopVar++)
{
Statements
}
where loopVar is the loop-control variable,
and the Statements between the curley-braces
are called the body of the loop.
The behavior of this statement is as follows:
In our problem, we must count from 1 to the value stored in
numberOfEmployees,
using for (int empNum = 1; empNum <= numberOfEmployees; empNum++) trueleaving its Statements empty for the moment.
Note that if the user enters a negative value for numberOfEmployees, the body of the loop will not be executed, because the loop's body is only executed if the condition controlling the loop evaluates to true, and a negative value for numberOfEmployees will make this condition false.
Add this to
3a. Via Enter the name, hours and rate for employee 1: Enter the name, hours and rate for employee 2: Enter the name, hours and rate for employee 3: Then check the syntax of what you have written using the compiler. When your program translates correctly, run it and enter 3 for the number of employees, to verify that what you have written is free of logic errors.
3b. From This step can be encoded by adding a normal input statement to the body of the loop, after the output statement, so take a moment to do so. However, before such a statement will compile correctly, the objects name, hours and rate must be declared. This raises an interesting question: Where should these objects be declared?
If we declare name, hours and rate within
the body of the loop, then they will be redeclared anew each execution
of the body, wasting time.
For the sake of efficiency, they should instead be declared
immediately before the
Add the necessary statements to your program to
(i) declare name, hours and rate(outside the loop),
and (ii) fill these objects with values entered from the keyboard
(inside the loop).
To declare name as a #include <string>(The string header file does not end in .h.)
Then check your code's syntax using the compiler,
and continue when it is correct.
Anytime we program an input operation, we should consider the possibility of human error: what could the user do to foul up our program? There are several possibilities here:
Since any of these three errors will cause our program to generate
incorrect pay amounts, our code should safeguard against them.
To do so, add an
Then check the syntax of what you have written using the compiler,
then run your program and test that your 3c. Compute pay, using hours and rate. This operation is not predefined, and so we will design and build a function to perform it. Function Analysis. To compute pay for an arbitrary employee, our function needs their hours and rate. Since these values will differ from employee to employee, our function should receive these values from its caller. Function Behavior. Our function should receive the hours and rate from its caller. If hours is less than or equal to the number of hours in a work week (40 in the U.S.), then our function should compute the total pay as hours times rate. Otherwise, it should compute the normal pay as the work week times the rate; compute the overtime pay as the overtime hours times the rate; and then compute the total pay as the sum of the overtime pay and the normal pay. Function Objects. Ignoring nouns like "our function" and "caller", we can identify the following objects in this description:
For each received object, we must provide a parameter to store that value. We can thus specify the behavior of our function as follows: Receive: hours and rate, both doubles. Precondition: 0 <= hours and hours <= 168 and 0 <= rate. Return: the total pay, a double.These observations allow us to create the following stub for our function: double ComputePay(double hours, double rate) trueEach object that is neither received nor returned must be defined as a local object, within the body of our function. For example, OVERTIME_FACTOR will be a local constant double object, defined to have the value 1.5;
while normalPay will be a local variable double object.
Since this seems like a function that might be reuseable some day,
we will store its definition in a library named Before this stub, add an include directive: #include pay.hto insert the header file of our pay library into
the implementation file when it is compiled.
Then add a prototype of this function to the header file
pay.h and the documentation file pay.doc.
Finally, copy-and-paste the function's specification into pay.doc.
Function Operations. From our behavioral description, we have these operations:
We have seen each of these operations before, except for operation (5),
which introduces a new behavior in which we must select
one group of statements or another, but not both.
As we shall see shortly, the C++
|
Home Membership
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Last update: Wednesday, August 23, 2000 at 10:26:37 AM. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||