ACS 168 Structured Programming Using the Computer
Download
Report
Transcript ACS 168 Structured Programming Using the Computer
ACS 168
Structured Programming Using
the Computer
Spring 2002
By
Joaquin Vila
Prepared by
Shirley White
1
Reminders
Keep Reading Chapter 3
Self-Test exercises
Supplemental Instruction (Exam Review)
Any question about chapter 2?
Homework Assignment (Montecarlo Simulation)
Quiz
2
3
Practice
Write an if statement to compute and
print the total for a sale. The cost of the
items being purchased is stored in
sub_total, a variable of type double. A
variable customer_type, of type char, has
the value ‘N’ for normal or ‘G’ for
government. Customers of type ‘G’ do
not pay sales tax. The sales tax rate is
stored in a constant named tax_rate.
4
Practice
Design and write a program that will
prompt for, receive, and total a collection
of payroll amounts entered by the user
until a sentinel amount of -99 is entered.
After the sentinel has been entered,
display the total payroll amount on the
screen.
5
Practice
Write a while loop to compute the
sum of all integers between first and
second (including first and second),
where first and second are integers
and first <= second. You may not
change the value of either first or
second.
6
Practice
Write a program that sums a sequence of
integers. Assume that the first integer
read specifies the number of values
remaining to be entered. Your program
should read only one value at a time. A
typical input sequence might be
5 100 200 300 400 500
7
Practice
Write a program that finds the
smallest of several integers.
Assume that input will end when a
sentinel value of –999 is read. Do
not count –999 as one of the
integers to consider.
8
Display 2.14 Charge Card Program (1 of 2)
#include <iostream>
using namespace std;
int main( )
{
double balance = 50.00;
int count = 0;
cout << "This program tells you how long it takes\n"
<< "to accumulate a debt of $100, starting with\n"
<< "an initial balance of $50 owed.\n"
<< "The interest rate is 2% per month.\n";
9
Display 2.14 Charge Card Program (2 of 2)
while (balance < 100.00)
{
balance = balance + 0.02 * balance;
count++;
}
count++
accomplishes
same thing as
cout << "After
" << count << the
" months,\n";
cout.setf(ios::fixed);
count = count +1
cout.setf(ios::showpoint);
cout.precision(2);
cout << "your balance due will be $" << balance << endl;
return 0;
}
10
Naming Constants
Do not hard-code numbers into your program that are
likely to change.
Example:
If the tax rate is 4% (0.04) today, it will go up. Make such
numbers declared constants unless you want to hunt
through your code to find and replace all instances of
0.04 and try to decide if it is a tax rate, then replace it by
the new tax rate, 0.05.
Name declared constants with the const keyword.
Spell declared constant names with upper case letters,
with successive words separated by underscores.
Example:
const int BRANCH_COUNT = 10;
const double TAX_RATE = 0.04;
11
Summary (1 of 2)
Use meaningful names for variables.
Check that variables have been declared before use,
and have the correct data type.
Be sure variables has a value before use. This can be
done by initialization at definition, or by assigning a
value before first use.
Use enough parentheses to make the order of
operations clear. Remember, code is meant to be read,
which implies writing for an audience.
Always have your program prompt the user for
expected input. Always echo user’s input.
An if-else statement chooses between two blocks of
code to execute. An if statement chooses whether to
execute a block of code.
12
Summary (2 of 2)
A do-while always executes its body at least once. A
while loop may not execute its body at all.
Numeric constants should be given meaningful names
to be used instead of the numbers. Use the const
modifier to do this.
Use indenting, spacing, and line break patterns similar
to the sample code to group sections of code such as
the body of a while statement, or the affirmative and
negative clauses of an if-else statement.
Insert commentary to explain major subsections of your
code, or to explain any unclear part of your program.
Make your code clear. Remember, a program is meant to
be read by programmers, not just compilers.
13
14
Chapter 3
Procedural Abstraction & Functions That Return a Value
3.1 Top Down Design
Step wise refinement, also known as
divide and conquer, means dividing
the problem into subproblems such
that once each has been solved, the
big problem is solved.
The subproblems should be smaller
and easier to understand and to solve
than the big problem.
15
3.2 Predefined Functions: Libraries
C++ comes with libraries of predefined
functions.
How do we use predefined (or library)
functions?
Everything must be declared before it
is used. The statement #include
<file> brings the declarations of
library functions into your program,
so you can use the library functions.
16
Libraries
#include <cmath> // include declarations of math
// library functions
#include <iostream> // include definitions of
// iostream objects
using namespace std; // make names available
int main()
{
cout << sqrt(3.0) << endl; // call math library function
}
// sqrt with argument 3.0, send
// the returned value to cout
17
3.2 Function Call
A function call is an expression consisting of a
function name followed by arguments enclosed in
parentheses. Multiple arguments are separated by
commas.
Syntax:
FunctionName(Arg_List)
where Arg_List is a comma separated list of
arguments.
Examples:
– side = sqrt(area);
– cout <<“2.5 to the power 3.0 is “
<< pow(2.5, 3.0);
18
Display 3.1 A Function Call (pt 1)
//Computes the size of a dog house that can be purchased
//given the user’s budget.
#include <iostream>
#include <cmath>
using namespace std;
int main( )
{
const double COST_PER_SQ_FT = 10.50;
double budget, area, length_side;
cout << "Enter the amount budgeted for your dog house $";
cin >> budget;
area = budget/COST_PER_SQ_FT;
length_side = sqrt(area);
// the function call
19
Display 3.1 A Function call (pt 2)
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << "For a price of $" << budget << endl
<< "I can build you a luxurious square dog
house\n"
<< "that is " << length_side
<< " feet on each side.\n";
return 0;
}
20
PITFALL: Problems with Library functions
Some compilers do not comply with the ISO
Standard.
If your compiler does not work with
#include <iostream>
use
#include <iostream.h>
Similarly, for headers like cstdlib: use stdlib.h, and
for cmath, use math.h
Most compilers at least coexist with the headers
without the .h, but some are hostile to these
headers.
21
Type changing functions
Question: 9/2 is an int, but we want the 4.5 floating
point result. We want the integer part of some
floating point number. How do we manage?
Answer: Type casting, or “type changing functions”.
C++ provides a function named double that takes a
value of some other type and converts it to double.
Example:
int total, number;
double ratio;
// input total, number
winnings = double(total) / number;
22
PITFALL:
Integer division drops the fractional part
REMEMBER: integer division returns just the
quotient. The remainder (and any fractional part)
are dropped.
If the numerator and denominator are both integer
values, the division is done as integer arithmetic,
dropping the fractional part.
Example: 11 / 2 is 5, NOT 5.5
10 / 3 is 3, NOT 3.333
Even if assigned to a double variable:
double ratio = 10/3; // assigned value is 3, NOT 3.3
23
3.3 Programmer Defined Functions
You can define your own functions.
You can put your functions in the same file
as the main function or in a separate file.
If you put your function after the function
containing a call to your function, or in a
separate file, you must put a prototype
(defined in the next slide) for your function
some place in the file where it is called,
prior to the call.
24
Function Prototypes
A function prototype tells you all the information you need to
call the function. A prototype of a function (or its definition)
must appear in your code prior to any call to the function.
Syntax:
Don’t forget the semicolon
– Type_of_returned_value Function_Name(Parameter_list);
– Write prototype comments for each function.
– Parameter_list is a comma separated list of parameter
definitions:
type_1 param_1, type_2 param_2, …. type_N param_N
Example:
double total_weight(int number, double weight_of_one);
// Returns total weight of number of items that
// each weigh weight_of_one
25
A function is like a small program
To understand functions, keep these points in mind:
A function definition is like a small program and
calling the function is the same thing as running
this small “program.”
A function has formal parameters, rather than cin,
for input. The arguments for the function are input
and they are plugged in for the formal parameters.
A function of the kind discussed in this chapter
does not send any output to the screen, but does
send a kind of “output” back to the program. The
function returns a return-statement instead of coutstatement for “output.”
26
Display 3.3 A function Definition (Slide 1 of 2)
#include <iostream>
using namespace std;
double total_cost(int number_par, double price_par);
//Computes the total cost, including 5% sales tax,
//on number_par items at a cost of price_par each.
int main( )
{
double price, bill;
int number;
cout << "Enter the number of items purchased: ";
cin >> number;
cout << "Enter the price per item $";
cin >> price;
bill =
total_cost(number, price);
The function call
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
27
Display 3.3 A function Definition (Slide 2)
cout << number << " items at "
<< "$" << price << " each.\n"
<< "Final bill, including tax, is $" << bill
<< endl;
return 0;
}
double total_cost(int number_par, double price_par)
{
This
line is the function heading.
const double TAX_RATE = 0.05; //5% sales tax
double subtotal;
subtotal = price_par * number_par;
return (subtotal + subtotal*TAX_RATE);
}
The entire
function
The function body
is called
thepart
is the
function
definition.
between
the { }.
28
Call-by-value Parameters
Consider the function call:
bill = total_cost(number, price);
The values of the arguments number and price are
“plugged” in for the formal parameters . This
process is (A precise definition of what “plugged”
means will be presented later. For now, we will use
this simile.)
A function of the kind discussed in this chapter
does not send any output to the screen, but does
send a kind of “output” back to the program. The
function returns a return-statement instead of coutstatement for “output.”
29
Alternate form for Function Prototypes
The parameter names are not required:
double total_cost(int number, double price);
It is permissible to write:
double total_cost(int, double );
Nevertheless, code should be readable to
programmers as well as understandable by the
compiler, so check for readability and chose to use
parameter names when it increases readability.
Function HEADERS (in the definition) must use
parameter names. (There is an exception to this
rule that we will not deal with in this course.)
30
Anatomy of a Function Call (part 1 of 3)
#include <iostream>
using namespace std;
double total_cost(int number_par, double price_par);
//Computes the total cost, including 5% sales tax,
//on number_par items at a cost of price_par each.
int main( )
{
double price, bill;
int number;
cout << "Enter the number of items purchased: ";
cin >> number;
cout << "Enter the price per item $";
cin >> price;
bill =
total_cost(number, price);
Before the function is called,
the value of the variables
number and price are set to
2 and 10.10, by cin.
The function call
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
31
Anatomy of a Function Call (part 2 of 3)
The value of number (which is 2) is plugged
in for number_par and the value of price
(which is 10.10) is plugged for price_par:
double total_cost(int number_par, double price_par)
{
const double TAX_RATE = 0.05;
//5% sales tax
double subtotal;
subtotal = price_par * number_par;
return (subtotal + subtotal*TAX_RATE);
}
32
Anatomy of a Function Call (part 3 of 3)
The execution produces the following effect:
The body of the function is executed, i.e., the
following is executed:
double total_cost(int 2, double 10.10)
{
const double TAX_RATE = 0.05;
//5% sales tax
double subtotal;
subtotal = 10.10 * 2;
return (subtotal + subtotal*TAX_RATE);
When the return statement is executed, the value of the expression after the
return }is the value returned by the function. In this case, when
return (subtotal + subtotal*TAX_RATE); is executed, the value of (subtotal +
subtotal*TAX_RATE), is returned by the function call which was
33
bill = total_cost(number, price); the value of bill is set to 21.21
PITFALL
Arguments in the wrong order
When a function is called, C++ substitutes the first
argument given in the call for the first parameter in
the definition, the second argument for the second
parameter, and so on.
There is no check for reasonableness. The only
things checked are: i) that there is agreement of
argument type with parameter type and ii) that the
number of arguments agrees with the number of
parameters.
If you do not put correct arguments in call in the
correct order, C++ will happily assign the “wrong”
arguments to the “right” parameters.
34
Summary of Syntax
for a Function that Returns a Value
Function Prototype:
Type_Returned Function_Name(Parameter_List);
Prototype Comment
function header
Function Definitions
Type_Returned Function_Name(Parameter_List)
{
Declaration_1
Declaration_2
...
Must include one or
Declaration_Last;
more return statements.
Executable_1;
body
Executable_2;
...
Executable_Last
}
35
Principle of Information Hiding
David Parnas, in 1972 stated the principle of
information hiding.
– A function’s author (programmer) should know everything
about how the function does its job, but nothing but
specifications about how the function will be used.
– The client programmer -- the programmer who will call the
function in her code -- should know only the function
specifications, but nothing about how the function is
implemented.
36
The Black Box Analogy
Based on the Principle of Information Hiding, the
text describes the BLACK BOX analogy.
When using a function, we behave as if we know
nothing about how the function does its job, that
we know only the specifications for the function.
When writing a function, we behave as if we know
nothing but the specifications about how the
function is to be used.
In this way, we avoid writing either application code
that depends on the internals of the function or
writing function code that depends in some way on
the internal structure of the application.
37
3.4 Procedural Abstraction
When applied to a function definition, the principle of procedural
abstraction means that your function should be written so
that it can be used like a black box. This means the user of a
function should not need to look at the internals of the
function to see how the function works. The function
prototype and accompanying commentary should provide
enough information for the programmer to use the function.
To ensure that your function definitions have this property, you
should adhere to these rules:
– The prototype comment should tell the programmer any
and all conditions that are required of the arguments to
the function and should describe the value returned by
the function.
– All variables used in the function body should be declared
in the function body. (The formal parameters are already
declared in the function header.)
38
3.5 Local Variables
Variables declared within the body of a function
definition are said to be local to that function, or have
that function’s block as their scope.
Variables declared within the body of the main function
are said to be local to the main function, or to have that
function’s block as their scope.
When we say a function is a local variable without
further mention of a function, we mean that variable is
local to some function definition.
If a variable is local to a function, you can have another
variable with the same name that is local to either main
or some other function.
39
Global Constants and Variables
A named constant declared outside the body of any function
definition is said to be a global named constant. A global named
constant can be used in any function definition that follows the
constant declaration. There is an exception to this we will point out
later.
Variables declared outside the body any function is said to be
global variables or to have global scope. Such a variable can be
used in any function definition that follows the constant
declaration. There is also an exception to this we will point out
later.
Use of global variables ties functions that use the global variables
in a way that makes understanding the functions individually
nearly impossible. There is seldom any reason to use global
variables.
40
Display 3.11 Global Named Constants
(Part 1 of 2)
//Computes the area of a circle and the volume of a sphere.
//Uses the same radius for both calculations.
#include <iostream>
#include <cmath>
Here PI is a global constant that is
using namespace std;
visible to all parts of the program.
const double PI = 3.14159;
double area(double radius);
//Returns the area of a circle with the specified radius.
double volume(double radius);
//Returns the volume of a sphere with the specified radius.
int main( )
{
double radius_of_both, area_of_circle, volume_of_sphere;
cout
<<radius_of_both,
"Enter a radius
to use for both
a circle\n"
Where
area_of_circle,
and volumn_of_sphere
are all
<<
"and
a
sphere
(in
inches):
";
variables local to main and not visible to other modules unless
cin
>> radius_of_both;
passed
in a function call.
41
Display 3.11 Global Named Constants
(Part 2 of 2)
area_of_circle = area(radius_of_both);
volume_of_sphere = volume(radius_of_both);
cout << "Radius = " << radius_of_both << " inches\n"
<< "Area of circle = " << area_of_circle
<< " square inches\n"
<< "Volume of sphere = " << volume_of_sphere
<< " cubic inches\n";
return 0;
}
double area(double radius)
{
return (PI * pow(radius, 2));
}
double vo lume(double radius)
{
return ((4.0/3.0) * PI * pow(radius, 3));
}
42
Call-by-value
Formal Parameters are Local Variables Formal
Parameter Used as Local Variable (Part 1 of 2)
//Law office billing program.
#include <iostream>
using namespace std;
const double RATE = 150.00; //Dollars per quarter hour.
double fee(int hours_worked, int minutes_worked);
//Returns the charges for hours_worked hours and
//minutes_worked
minutes of legal
Formal
parameters
areservices.
actually local
variables
that
are
int main(
) initialized by the call mechanism to the
{
value
of the argument. They may be used in any
int hours, minutes;
double
bill; a local variable can be used.
way
that
cout << "Welcome to the offices of\n"
<< "Dewey, Cheatham, and Howe.\n"
<< "The law office with a heart.\n"
<< "Enter the hours and minutes"
<< " of your consultation:\n";
cin >> hours >> minutes;
43
Formal Parameter Used as Local Variable (Part 2 of 2)
bill = fee(hours, minutes);
The value of minutes is not
changed by a call to fee.
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << "For " << hours << " hours and " << minutes
<< " minutes, your bill is $" << bill << endl;
return 0;
}
minutes_worked is a local variable
initialized to the value of minutes
double fee(int hours_worked, int minutes_worked)
{
int quarter_hours;
minutes_worked = hours_worked*60 + minutes_worked;
quarter_hours = minutes_worked/15;
return (quarter_hours*RATE);
}
44
Namespaces Revisited (1 of 2)
All our use of namespaces has amounted to
#include <iostream>
using namespace std;
While this is correct, we are sidestepping the reason
namespaces were introduced into C++, though we
have done this for good teaching reasons.
In short, we have been “polluting the global
namespace.”
As long as our programs are small, this is not a
problem.
This won’t always be the case, so you should learn to
put the using directive in the proper place.
45
Namespaces Revisited (2 of 2)
Placing a using directive anywhere is analogous to
putting all the definitions from the namespace
there. This is why we have been polluting the
global namespace. We have been putting all the
namespace std names from our header file in the
global namespace.
The rule, then is:
Place the namespace directive,
using namespace std;
inside the block where the names will be used. The
next slide is Display 3.13 with the namespace
directive place correctly.
46
Display 3.13 Using Namespaces (1 of 2)
//Computes the area of a circle and the volume of a sphere.
//Uses the same radius for both calculations.
Not here …
#include <iostream>
#include <cmath>//Some compilers may use math.h instead of cmath.
const double PI = 3.14159;
double area(double radius);
//Returns the area of a circle with the specified radius.
double volume(double radius);
//Returns the volume of a sphere with the specified radius.
int main( )
{
using namespace std;
but here
double radius_of_both, area_of_circle, volume_of_sphere;
cout << "Enter a radius to use for both a circle\n"
<< "and a sphere (in inches): ";
cin >> radius_of_both;
47
Display 3.13 Using Namespaces (1 of 2)
area_of_circle = area(radius_of_both);
volume_of_sphere = volume(radius_of_both);
cout << "Radius = " << radius_of_both << " inches\n"
<< "Area of circle = " << area_of_circle
<< " square inches\n"
<< "Volume of sphere = " << volume_of_sphere
<< " cubic inches\n";
return 0;
}
double area(double radius)
The behavior of this program is exactly
{
the same as that of Display 3.11
using namespace std;
return (PI * pow(radius, 2));
}
repeated here and here
double volume(double radius)
{
using namespace std;
return ((4.0/3.0) * PI * pow(radius, 3));
}
48
3.6 Overloading Function Names
C++ distinguishes two functions by
examining the function name and the
argument list for number and type of
arguments.
The function that is chosen is the function
with the same number of parameters as the
number of arguments and and that matches
the types of the parameter list sufficiently
well.
This means you do not have to generate
names for functions that have very much
the same task, but have different types.
49
Display 3.15
Overloading a Function Name (1 of 2)
//Illustrates overloading the function name ave.
#include <iostream>
double ave(double n1, double n2);
//Returns the average of the two numbers n1 and n2.
double ave(double n1, double n2, double n3);
//Returns the average of the three numbers n1, n2, and n3.
int main( )
{
using namespace std;
cout << "The average of 2.0, 2.5, and 3.0 is "
<< ave(2.0, 2.5, 3.0) << endl;
cout << "The average of 4.5 and 5.5 is "
<< ave(4.5, 5.5) << endl;
return 0;
}
50
Overloading a Function Name (2 of 2)
double ave(double n1, double n2)
{
return ((n1 + n2)/2.0);
}
Both these functions have the
same name, but have parameter
lists that are have different
numbers of parameters.
double ave(double n1, double n2, double n3)
{
return ((n1 + n2 + n3)/3.0);
}
The compiler will choose the function definition to use
according to the number of parameters sent in the call.
51
Automatic Type Conversion
We pointed out that when overloading function names,
the C++ compiler compares the number and sequence
of types of the arguments to the number and sequence
of types for candidate functions.
In choosing which of several candidates for use when
overloading function names, the compiler will choose
an exact match if one is available.
An integral type will be promoted to a larger integral
type if necessary to find a match. An integral type will
be promoted to a floating point type if necessary to get
a match.
52
Display 3.16
Overloading a function name (1 of 4)
//Determines whether a round pizza or a rectangular pizza is the best buy.
#include <iostream>
Same
names
double unitprice(int diameter, double price);
//Returns the price per square inch of a round pizza.
//The formal parameter named diameter is the diameter of the pizza
//in inches. The formal parameter named price is the price of the pizza.
double unitprice(int length, int width, double price);
//Returns the price per square inch of a rectangular pizza
//with dimensions length by width inches.
//The formal parameter price is the price of the pizza.
int main( )
{
using namespace std;
Notice the
difference in the
number and types of
parameters used.
int diameter, length, width;
double price_round, unit_price_round,
price_rectangular, unitprice_rectangular;
53
This call will go to the function:
Overloading a function name
double unitprice(int diameter, double price)(2 of 4)
{
cout << "Welcome to the Pizza Consumersconst
Union.\n";
double PI - 3.14159;
cout << "Enter the diameter in inches"
double raduis, area;
<< " of a round pizza: ";
cin >> diameter;
cout << "Enter the price of a round pizza: $";
radius = diameter/double(2);
cin >> price_round;
area = PI * radius * radius;
cout << "Enter length and width in inches\n"
<< "of a rectangular pizza: ";
return (price/area);
cin >> length >> width;
}
cout << "Enter the price of a rectangular pizza: $";
cin >> price_rectangular;
unitprice_rectangular =
unitprice(length, width, price_rectangular);
unit_price_round =
unitprice(diameter, price_round);
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
unitprice(int length, int, width, double price)
{
double area = length * width;
return (price/area); }
54
Overloading a function name (3 of 4)
cout << endl
<< "Round pizza: Diameter = "
<< diameter << " inches\n"
<< "Price = $" << price_round
<< " Per square inch = $" << unit_price_round
<< endl
<< "Rectangular pizza: length = "
<< length << " inches\n"
<< "Rectangular pizza: Width = "
<< width << " inches\n"
<< "Price = $" << price_rectangular
<< " Per square inch = $" << unitprice_rectangular
<< endl;
if (unit_price_round < unitprice_rectangular)
cout << "The round one is the better buy.\n";
else
cout << "The rectangular one is the better buy.\n";
cout << "Buon Appetito!\n";
return 0;
}
55
Chapter Summary( 1 of 2)
A good plan of attack on a problem is to decompose the problem
into smaller, more accessible problems, the decompose these into
still more manageable problems. This is known as Top-Down
Design.
A function that returns value is like a small program. Arguments
provide input and the return value provides the output.
When a subtask for a program takes some values as input and
produces a single value as its only output, then that subtask can
be implemented as a function.
A function should be defied so that it can be used as a black box.
The program author should know no more than the specification of
the client use, and the client author should know nothing more
than the specification of the implementation of the function. This
rule is the principle of procedural abstraction.
56
Chapter Summary (2 of 2)
A variable that is defined in a function is said to be local to the
function.
Global named constants are declared using the const modifier.
Declarations of global named constants are normally placed at the
start of a program after the include directives, before the function
prototypes.
Call by value formal parameters (the only kind we have discussed
so far) are local variables to the function. Occasionally a formal
parameter may be useful as a local variable.
When two or more function definitions have the same name, this is
called function name overloading. When you overload a name,
the function definitions must have different numbers of formal
parameters or formal parameters of different types.
57