What We Will Cover
Continuations
Homework Questions?
What will be output after the following C++ statements have been executed?
int count = 1;
while (count <= 3) {
cout << count << " ";
count++;
}
1 2
1 2 3
2 3
1 2 3 4
^ top
5.1: Predefined Functions
Objectives
At the end of the lesson the student will be able to:
- Create code that calls predefined functions
- Describe the flow of control of a function call
- Write code that generates random numbers
|
^ top
5.1.1: About Functions
Function -- a subprogram (method, procedure or subroutine) that executes a block of code when called.
- Programs can call functions at need, allowing repeated use of the function
- Function are often collected into libraries so they can be reused by many different programs
- C++ comes with many common libraries such as
<cmath> which contains functions like those shown in the table below
- Libraries must be "included" in a program
#include <cmath>
Newer standard libraries, such as cmath, also require the directive
using namespace std;
Library Functions in <cmath>
| Name |
Description |
Example |
Result |
| abs |
absolute value |
abs(-3.9)
abs(3.9) |
3.9
3.9 |
| exp |
exponent |
exp(1.0) |
2.71828 |
| log |
natural log |
log(10.0) |
2.30259 |
| pow |
powers |
pow(2.0, 3.0) |
8.0 |
| sqrt |
square root |
sqrt(4.0) |
2.0 |
^ top
5.1.2: Calling Functions
- Calling a method is like a boss asking a worker to do something
- In programming, the "boss" function asks a "worker" function to complete a task
- To ask a function to do something, the "boss" function uses a function call
- A function call consists of the function name and any parameters the function may need to do its task
- For example, to calculate the square root of a number, you would call the
sqrt() function:
sqrt(9.0);
When called with an argument of 9.0, the function returns a value of 3.0
Here are some more examples of function calls:
double result = pow(2.0, 3); // result is 8.0
cout << result << endl;
double num = -2.0;
double value = abs(num); // value gets 2.0
cout << value << endl;
^ top
5.1.3: Flow of Control for a Function Call
- To use functions well, you must understand their flow of control
- Consider the function call in the example shown below
1
2
3
4
5
6
7
8
9
10
|
#include <cmath>
#include <iostream>
using namespace std;
int main() {
double result = 1 + sqrt(9.0);
cout << result << endl;
return 0;
}
|
- The program starts executing in the
main() function
- The next line is an assignment statement, so the right-hand side is evaluated first
1 + sqrt(9.0)
The program evaluates the function call first since it has higher precedence than addition
When making the function call, the computer stops working on the current code and instead works on the code inside the function
The computer sends the information inside the parenthesis of the function call to the function
The function uses the data it was passed to perform its calculations
When the function is done, it returns the result of its calculation back to the code that called the function
The computer then uses the returned value to complete the computation
When the right-hand side is done, the value of the computation is saved in the variable on the left-hand side
^ top
5.1.4: Generating Random Numbers
- As an example of function calls, let us look at random numbers
- Random numbers are a series of numbers whose order cannot be predicted
- Many computational problems need to use random numbers
- Hard to find truly random numbers, even in real life
- Dice never perfect
- Cards never shuffled completely randomly
- Computers can only handle numbers within a finite range and limited precision
- The best that can be done in most cases is to generate pseudorandom numbers
- Sufficiently random for the task at hand
- rand() is a library function that produces series of psuedorandom numbers
- Range is
0 up to and including RAND_MAX
- Returns an "random"
int value
- For example:
cout << rand() << endl;
Initializing the Random Number Sequence
- If your program prints a random number, you will notice that it prints the same number every time the program runs
- To make the random numbers more random, you need to "seed" the random number generator
- For this you use the srand() function
- For instance:
srand(time(0));
The expression time(0) returns the number of seconds since January 1, 1970
The srand() function tells the computer to start with another number in the sequence
Since the time changes every time we run our program, the sequence of random numbers changes as well
^ top
5.1.5: Example Use of Random Numbers: Dice Simulation
- Let us use random numbers to simulate die rolling
- We need a number between 1 and 6, but
rand() returns a number between 0 and RAND_MAX
- We need only random numbers for a die and so we scale the range of
RAND_MAX using the % operator
- Now we can generate random integer numbers between 0 and 5
- To get a number between 1 and 6, we shift the numbers by adding 1
- Our code to simulate a single die with random numbers is now:
int die = 1 + rand() % 6;
cout << die << endl;
We can generalize our formula for producing integer random numbers to:
SHIFTING_VALUE + rand() % SCALING_FACTOR;
Let us use our code to simulate rolling a pair of dice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <iostream>
using namespace std;
int main() {
srand(time(0));
int die1 = 1 + rand() % 6;
int die2 = 1 + rand() % 6;
cout << "You rolled a " << die1
<< " and a " << die2 << endl;
return 0;
}
|
- Note how the program simulates rolling 2 dice using 1 die at a time
- You would get a different result if you just generated a random number between 2 and 12
- What would you change to roll the two dice 10 times?
^ top
5.1.6: Summary
- A function is a block of code get executed when called
- C++ has many predefined functions in several libraries
- Libraries must be "included" in a program
#include <cmath>
Newer standard libraries, such as cmath, also require the directive
using namespace std;
One of the library functions generate "random" numbers: rand()
To seed the random number generator, you use the srand() function
We can use these functions to simulate the rolling of a die
srand(time(0));
int die = 1 + rand() % 6;
cout << die << endl;
Check Yourself
- What is a function?
- How do you call a function?
- What is a random number?
- How do you code a random number that simulates rolling a die?
^ top
Exercise 5.1
In this exercise we look at the randomness of the rand() function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <iostream>
using namespace std;
int main() {
srand(time(0));
int die1 = 1 + rand() % 6;
int die2 = 1 + rand() % 6;
cout << "You rolled a " << die1
<< " and a " << die2 << endl;
return 0;
}
|
Specifications
- Save the code as
dice.cpp
- Change the code by adding a loop that rolls the two dice 10 times.
- Display the output of the roll each time through the loop.
- Submit your program along with your other exercises for this lesson.
Example Output
You rolled a 1 and a 1
You rolled a 4 and a 5
You rolled a 5 and a 6
You rolled a 3 and a 6
You rolled a 2 and a 4
You rolled a 4 and a 6
You rolled a 3 and a 4
You rolled a 1 and a 5
You rolled a 4 and a 5
You rolled a 4 and a 6
^ top
5.2: Coding Functions that Return Values
Objectives
At the end of the lesson the student will be able to:
- Defining functions
- Pass arguments to functions
- Return a value from a function
- Describe what is meant by a local variable
|
^ top
5.2.1: Declaring and Defining Functions
Function -- a subprogram (method, procedure or subroutine) that executes a block of code when called.
- Rather than using a predefined function, you can write your own functions
- Writing functions becomes more important as your programs become larger
- The reason is that writing small programs is easier than writing large programs
- Writing a 20 line program is easier than writing a 1000 line program
- We can write, test and understand small functions independently of one other
- These correctly working functions become the building blocks of larger programs
- We use these "building-block" functions to make a larger program
Syntax
- There are two parts to defining your own functions in C++
- Function declaration (prototype)
- Function definition
- Function prototype syntax:
returnType functionName(type1 param1, type2 param2, ...);
Function definition syntax:
returnType functionName(type1 param1, type2 param2, ...) {
// statements
}
Both begin with the data type of the value that will be returned
- Return types include:
char, int, double, String, etc.
After specifying the data type, give the function a name
Following the name, add a set of parentheses: ( )
Within parenthesis specify the parameters for any arguments passed by the function call
Function prototypes end in a semi-colon ';'
Function definitions have a set of curly braces {...}
The block of code executed by the function is enclosed in the curly braces
Note that the first line of a method is called the function heading
The code within the curly brackets is called the function body
For Example
- The following code defines two functions
- Note that functions prototypes must precede a call to the function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <iostream>
using namespace std;
// Function declaration (prototype)
double square(double number);
int main() {
double number = 5;
double result = square(number);
cout << result << endl;
return 0;
}
// Function definition
double square(double number) {
double result = number * number;
return result;
}
|
- Function
main() calls function square(), passing the value of the variable number
- This value gets copied to the parameter named
number in the function definition
- A parameter is a variable that get initialized from the function call
- Function
square() uses the parameter to compute the result and then returns that result
^ top
5.2.2: Passing Arguments
- When a program makes a function call, it sends the information inside the parenthesis to the function
square(number)
The value of each argument is copied to its corresponding parameter
double square(double number) {
...
}
The function call must include an argument for every parameter
In addition, the data type of each argument must be compatible with the data type of the parameter
Thus, in our previous example, the data type of the variable number must be compatible with the data type of the parameter number
C++ will automatically cast some types to another type
However, C++ cannot convert some types automatically
For instance, you cannot pass a string when a number is expected
For Example
- Following program has a method named
pow()for calculating powers of numbers with positive int exponents
- Method
pow() has two parameters: base and exponent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
using namespace std;
// Function prototype
long pow(int base, int exponent);
int main() {
long value = pow(2, 3);
cout << value << endl;
return 0;
}
long pow(int base, int exponent) {
if (exponent == 0) {
return 1;
}
int loopCounter = 1;
long result = base;
while (loopCounter < exponent) {
result = result * base;
loopCounter++;
}
return result;
}
|
Common Pitfall
- Common Mistake: declaring parameters 'again' inside a function:
double pow(int base, int exponent) {
int loopCounter; // local variable
int base; // NO!
}
Compiler error: "Redefinition error"
Parameters ARE local variables -- except they are initialized from arguments in the function call
^ top
5.2.3: Returning a Value
- Functions that return a value must execute a
return statement
return result;
For instance, in our original example, function square() had a return statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <iostream>
using namespace std;
// Function declaration (prototype)
double square(double number);
int main() {
double number = 5;
double result = square(number);
cout << result << endl;
return 0;
}
// Function definition
double square(double number) {
double result = number * number;
return result;
}
|
- Sometimes you do not want to execute all the code in a function
- You can use
return statement to stop execution and return from anywhere
- Control returns immediately from a function whenever a
return is reached
- We saw this in our second example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
using namespace std;
// Function prototype
long pow(int base, int exponent);
int main() {
long value = pow(2, 3);
cout << value << endl;
return 0;
}
long pow(int base, int exponent) {
if (exponent == 0) {
return 1;
}
int loopCounter = 1;
long result = base;
while (loopCounter < exponent) {
result = result * base;
loopCounter++;
}
return result;
}
|
^ top
5.2.4: Local Variables and Scope
- Variables and parameters declared in a function can only be used within that function
- This is known as a variables scope
- When the function finishes executing, local variables disappear
- Trying to use a local variable outside a function cause a compile error
For Example
- Using our second example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
using namespace std;
// Function prototype
long pow(int base, int exponent);
int main() {
long value = pow(2, 3);
cout << value << endl;
return 0;
}
long pow(int base, int exponent) {
if (exponent == 0) {
return 1;
}
int loopCounter = 1;
long result = base;
while (loopCounter < exponent) {
result = result * base;
loopCounter++;
}
return result;
}
|
- The local variable
exponent declared in function pow() cannot be used inside the main() function
- For instance, if we tried to print the variable
exponent in main()
int main() {
long value = pow(2, 3);
cout << value << endl;
cout << exponent << endl;
return 0;
}
We would get a compiler error like:
power.cpp:10: error: `exponent' undeclared
^ top
5.2.5: Programming Style Requirements for Functions
- Consider again our first example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <iostream>
using namespace std;
// Function declaration (prototype)
double square(double number);
int main() {
double number = 5;
double result = square(number);
cout << result << endl;
return 0;
}
// Function definition
double square(double number) {
double result = number * number;
return result;
}
|
- Note the placement of the curly braces
- When making up a name for a function, use verbs since functions perform an action
- There are two common naming styles you may use:
- Start with a lower-case letter and use uppercase letters as separators. Do not use underbars (
'_').
int myFunction()
- Use all lower case letters and use underbars (
'_') as separators.
int my_function()
- For your homework, every function must have a block comment before the name
- OK if formal parameter names are the same as argument names
Example of Fully Commented Function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/**
* CS-11 Asn 3
* square5.cpp
* Purpose: Print the square of the number 5.
*
* @author Ed Parrish
* @version 1.0 9/28/05
*/
#include <iostream>
using namespace std;
const int NUMBER = 5;
/**
* Calculate the square of a number.
*
* @param number The number to square.
* @return The square of the number.
*/
double square(double number);
int main() {
double number = NUMBER;
double result = square(number);
cout << result << endl;
return 0;
}
double square(double number) {
double result = number * number;
return result;
}
|
Further Information
^ top
5.2.6: Summary
- Writing functions is an important technique for breaking up your code into understandable pieces
- There are two parts to defining your own functions
- Function declaration (prototype)
- Function definition
- For example, a function might have the following prototype:
long pow(int base, int exponent);
Functions are defined with the same function heading but includes a list of statements inside curly braces:
long pow(int base, int exponent) {
if (exponent == 0) {
return 1;
}
int loopCounter = 1;
long result = base;
while (loopCounter < exponent) {
result = result * base;
loopCounter++;
}
return result;
}
Values are passed to a function by putting values of a compatible type, in the same order, inside the parentheses of the function call
pow(2, 3);
Values are copied from the arguments to the parameters when the function is called
Functions return a value of the type declared
To return a value, you use a return statement
return result;
Variables and parameters declared in a function can only be used within that function
When the function finishes executing, local variables disappear
Trying to use a local variable outside a function cause a compile error
Functions have style requirements you must follow
For instance, you must have a block comment before the name
Check Yourself
- How does writing functions contribute to good programming?
- What is the syntax for writing functions?
- What is meant by the term argument? parameter?
- What statement is used to return values from functions?
- Why should block comments be placed before function headings?
- What makes up a block comment for functions?
^ top
Exercise 5.2
The absolute value of a number is the number itself if the number is positive and the negative of the number if the number is negative. For instance, the absolute value of 1 is 1 and the absolute value of -1 is also 1.
The following code is the start of a program to convert numbers to their absolute value. You need to complete the program by finishing the calcAbs() function and including a function declaration.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <iostream>
using namespace std;
// Add function prototype here
int main() {
double num = 0.0;
cout << "Number to convert: ";
cin >> num;
cout << "Absolute value is: " << calcAbs(num) << endl;
return 0;
}
// Add function definition
double calcAbs(double value) {
// Insert statements here
return value; // change the return statement too!
}
|
Specifications
- Save the above code as
absvaluemaker.cpp
- Complete the program by writing a method named
calcAbs() that accepts a parameter of type double, computes the absolute value of the parameter, and returns the absolute value.
- Submit your program along with your other exercises for this lesson.
^ top
5.3: Local Variables and Scope Rules
Objectives
At the end of the lesson the student will be able to:
- Describe the scope of local and global variables
- Write global constants
|
^ top
5.3.1: Blocks and Scope
- Scope is the term used to define where you can access a variable
- A variable declared inside a pair of curly braces is local to that block of code
- Blocks begin at an opening brace ({) and end at a closing brace (})
- Variables declared inside a block are known only inside that block
- When the block finishes executing, local variables disappear
- References to local variables outside their block cause a compile-time error
- For example, what is printed by the following?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <iostream>
using namespace std;
int main() {
int x = 1;
cout << "x=" << x << endl;
{
cout << "x=" << x << endl;
int x = 2;
cout << "x=" << x << endl;
}
cout << "x=" << x << endl;
return 0;
}
|
Block Scope in Conditional and Loop Statements
- Note that block scope rules apply to conditional and loop statements as well
- For example, will the following code compile?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <iostream>
using namespace std;
double square(double x);
int main() {
double x = 0;
cout << "Enter a number: ";
cin >> x;
square(x);
cout << "The square of " << x
<< " is " << xSquared << endl;
return 0;
}
double square(double x) {
double xSquared = x * x;
return xSquared;
}
|
- How would you correct this code?
^ top
5.3.2: Function Scope and Local Variables
- Variables defined in functions can only be accessed within that function
- Thus, they are known as local variables
- Local variables cannot be used outside the function in which they are declared
- Variables declared in
main() cannot be used inside another function
- Variables declared in another function cannot be used inside
main()
- Also note that parameters are just local variables with a special initialization mechanism
For Example
- What is displayed by the following code??
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <iostream>
using namespace std;
// Function prototype
double square(double x);
int main() {
double x = 2.0;
double x2 = square(x);
cout << "x^2 = " << x2 << endl;
return 0;
}
double square(double x) {
double x2 = x * x;
return x2;
}
|
^ top
5.3.3: Using Global Constants
- Available to all functions
- Declared outside any function body
- Declared before any function that uses it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <iostream>
using namespace std;
const double PI = 3.14159;
// Returns the area of a circle with the specified radius.
double area(double radius);
// Returns the volume of a sphere with the specified radius.
double volume(double radius);
int main() {
double radiusOfBoth, areaOfCircle, volumeOfSphere;
cout << "Enter a radius to use for both a circle\n"
<< "and a sphere (in inches): ";
cin >> radiusOfBoth;
areaOfCircle = area(radiusOfBoth);
volumeOfSphere = volume(radiusOfBoth);
cout << "Radius = " << radiusOfBoth << " inches\n"
<< "Area of circle = " << areaOfCircle
<< " square inches\n"
<< "Volume of sphere = " << volumeOfSphere
<< " cubic inches\n";
return 0;
}
double area(double radius) {
return (PI * pow(radius, 2));
}
double volume(double radius) {
return ((4.0 / 3.0) * PI * pow(radius, 3));
}
|
^ top
5.3.4: About Global Variables
- Declared just like a global constant without the
const
- Makes programs more difficult to understand and maintain
- Do not use in your programs for this course
^ top
5.3.5: Summary
- Scope is the term used to define where you can access a variable
- A variable inside a pair of curly braces is local to that block of code
- Blocks begin at an opening brace ({) and end at a closing brace (})
- This includes functions and other statements that use curly braces
- Thus, variables declared in one function are not available in any other function
- Global variables are variables declared outside of any function
- Do NOT use global variables in your programs for this course
- Global constants, on the other hand, are the preferred way to declare constants
Check Yourself
- What is meant by the term scope?
- What is a block of code?
- When variables are declared in a block, where are they accessible?
- Why are global variables considered a poor programming practice?
- Why are global constants considered a good programming practice?
^ top
Exercise 5.3
The following program does not compile due to a scope error.
Specifications
- Save the following code as
scope.cpp.
- Fix the program so that it compiles and runs correctly.
- Submit your program along with your other exercises for this lesson.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <iostream>
using namespace std;
double square(double x);
int main() {
double x = 0;
cout << "Enter a number: ";
cin >> x;
square(x);
cout << "The square of " << x
<< " is " << xSquared << endl;
return 0;
}
double square(double x) {
double xSquared = x * x;
return xSquared;
}
|
^ top
5.4: Designing a Function
Objectives
At the end of the lesson the student will be able to:
- Use top down design to create algorithms
- Write functions following the black-box analogy
|
^ top
5.4.1: Top Down Design
- Recall that programming is about solving problems using a computer program
- The first phase of writing a program is the problem solving phase
- The output of the problem solving phase is an algorithm
- A good approach for designing algorithms is to break down the task to be accomplished into a few subtasks
- Then you break down each subtask into smaller subtasks as needed
- Eventually, the tasks are so trivial that they are easy to implement in C++
- This technique is called top down design (also stepwise refinement or divide and conquer)
Using Functions in Top Down Design
- Preserving your top down design in your C++ code makes your programs:
- Easier to understand
- Easier to write, test and debug
- Easier to change when needed
- The way to preserve your top down design is to implement the structure in functions
- One advantage of using functions to structure your code is that different people can work on different subtasks
- When producing large programs, this sort of teamwork is important
- Many people can work together to produce a program faster
- However, this technique only works if the work is divided in a structured way
- This design approach provides much of the structure needed to produce large programs
^ top
5.4.2: Designing Functions Using the Black Box Analogy
- A key concept in designing functions is called the black-box analogy
- A black box is something that we know how to use but not how it operates
- An example might be a cell phone or an iPod
- These devices have controls that we know how to operate
- However, we really do not know how they work
Functions as Black Boxes
- A function should be designed like a black box
- The function has a job to do
- For example: find the square root of a number
- As a programmer using the function, you need to know what the function's job is so you can use it
- However, you do not need to know how the function does its job
- This is known as, "treating the function like a black box"
- Calling something a black box is a figure of speech
- It is intended to convey the image of a physical device that we know how to use but not how it operates
- If a function is well designed, then a programmer can use it as if it were a black box
- All a programmer needs to know is that if correct arguments are passed to the function then a correct value will come out of the black box
- Thus, when we call the function
sqrt(9.0), we know we will get 3.0 back
cout << sqrt(9.0) << endl;
A programmer should not have to look at a function's code to know what will come back
Function Comment Blocks
- An important technique for providing information about a function to the programmer is the function comment block
- A function comment block should tell the programmer all the information needed to use the function
- The format of the function comment block is shown in the How-To's for Documenting and Organizing C++ Code
- Every function must have a comment block before the function prototype declaration
- Following this format allows you to run a program that creates web pages explaining how to use the function
^ top
5.4.3: Case Study: Buying Pizza
- Let's apply top down design and the black box analogy to a case study
Adapted from: Problem Solving with C++, 5/e, Walter Savitch, Addison Wesley, ISBN 0-321-26865-2, pp.120-127
- Often times the large "economy" size of a product is not always a better buy than the smaller size
- This is often true when buying pizza
- Pizza sizes are given in diameters
- However, the amount of pizza you get is really the area of the pizza
- Which is proportional to the square of the radius
- The problem is: which size of pizza gives the lowest cost per square inch?
- We need to write a program that gives us the price per area of any two pizza sizes
^ top
5.4.4: Case Study: Problem Analysis
- To better understand the problem we are solving, we ask some questions:
- What output do we want?
- A decision on which size is the best buy
- Based on the cost per square inch for each size of pizza
- What data do we have to work with?
- Diameter of two sizes of pizza
- Cost of the same two sizes of pizza
- What formulas do we need?
- area = πr2
- cost per inch = price / area
- What if the cost per square inch is the same?
- The smaller size will be the better buy
^ top
5.4.5: Case Study: Algorithm Design
- We use top-down design to break down the overall task into steps or subtasks
- Looking at the tasks, what do you notice?
- Subtask 1: Get the input data for each size of pizza
- Subtask 2: Compute the price per inch for smaller pizza
- Subtask 3: Compute the price per inch for larger pizza
- Subtask 4: Determine which size is the better buy
- Subtask 5: Output the results
- Subtask 1 is straightforward
- Just ask for the input values and store them in variables
- Similarly subtasks 4 and 5 are easy
- To determine the best buy in subtask 4, we just compare the cost/inch of the two pizzas using an
if statement
- Subtask 5 just prints the result
- However, notice subtasks 2 and 3
- Subtasks 2 and 3 are the same task with the only difference being the data used for the calculation
- Both of these tasks take the same type of input and return the same type of result
- Whenever you see a subtask take some values (like numbers) and return a single value, it is easy to make a function out of them
- Whenever two or more subtasks make the same computation, you should make a function out of them
- For our program, we make a function named
calcUnitPrice()
/**
* Calculates the price per square inch of a pizza
*
* @param diameter The diameter of the pizza in inches.
* @param price The price of the pizza in dollars.
* @return The price per square inch of a pizza.
*/
double calcUnitPrice(int diameter, double price);
Notice that our function is designed so that it can be treated as a black box
A programmer knows what values can be sent to the function and what to expect back from the function without needing to see the function code
calcUnitPrice Algorithm Design
- Now we design the algorithm for
calcUnitPrice
- The hard part of the algorithm is determining the area of the pizza
- Once we know the area, then we compute the price per inch using the formula:
price / area
- Since a pizza is roughly a circle, we can use the area formula:
- Thus, our algorithm for
calcUnitPrice is:
- Compute the radius of the pizza
- Compute the area of the pizza using πr2
- Return the value of:
(price / area)
- To get more detail and precision, we convert the algorithm to pseudocode
- Pseudocode is a mixture of C++ and ordinary English (or any natural language)
- With pseudocode, you can make your algorithms precise without worrying about the details of C++ syntax
- Our pseudocode is:
radius = diameter / 2;
area = π * radius * radius
return (price / area)
With the pseudocode defined, translation to C++ is easy
^ top
5.4.6: Coding and Testing
- To start translating our program into C++, we start with our template
1
2
3
4
5
6
7
8
|
#include <iostream>
using namespace std;
int main() {
// Enter code here
return 0;
}
|
- We save the file as
pizza.cpp, and then compile and run it to make certain everything works
- Next we add the code for subtask 1 to our program
- After adding each task, we compile and run the program to make sure every still works
- If we find an error, we correct it before continuing
- Since we have coded these types of tasks before, I leave this subtask for you to do so we can focus on the new material
- In
main(), we implement subtasks 2 and 3 as calls to calcUnitPrice
- We save the results of the function calls in two variables as shown:
unitPriceSmall = calcUnitPrice(diameterSmall, priceSmall);
unitPriceLarge = calcUnitPrice(diameterLarge, priceLarge);
- Next we "stub out" the function and then compile and run the program to make sure every still works
- Stubs are the outline of a function but without the algorithm implemented
- Since the function must return a value, we return a "dummy" value
double calcUnitPrice (int diameter, double price) {
return 1; // dummy value
}
With our subtasks 2 and 3 in place, we go on to implement subtasks 4 and 5
Again, since we have coded these types of tasks before, I leave these subtasks for you to do so we can focus on the new material
After we complete our main() function, we come back and implement the algorithm for calcUnitPrice
Coding calcUnitPrice
- We translate our pseudocode into C++ and obtain the following:
double calcUnitPrice(int diameter, double price) {
const double PI = 3.14159;
double radius, area;
radius = diameter / 2;
area = PI * radius * radius;
return (price / area);
}
What do you notice about the code?
The following statement looks right but is a serious mistake
radius = diameter / 2;
We want the radius to include the fractional part of the size
However, integer division truncates the remainder
How do we fix the problem?
double calcUnitPrice(int diameter, double price) {
const double PI = 3.14159;
double radius, area;
radius = diameter / static_cast<double>(2);
area = PI * radius * radius;
return (price / area);
}
Now radius will include fractional parts
radius = diameter / 2.0;
Here is a link to our completed program: pizza.cpp
Testing
- Just because a program compiles and runs does not mean that it is correct
- To verify that you program returns the correct answers, you should test it with known values and compare it with known results
- You can get known values and results by using pencil and paper or a calculator
- Once you have checked your program with a few known values, then you can have more confidence that it is correct
^ top
5.4.7: Summary
- Top-down design is a technique for creating algorithms
- The ideas is to break down the tasks into subtasks
- Then you break down each subtask into smaller subtasks as needed
- Eventually, the tasks are so trivial that they are easy to code
- A black box refers to something that we know how to use, but not how it operates
- A programmer who uses a function needs to know what the function does, not how it does it
- You want to write functions so that the function declaration and block comments are all a programmer needs to use the function
- We applied top-down design to the problem of buying the best size of a pizza
- Along the way, we made sure to design our functions as black boxes
Check Yourself
- What is meant by the term top-down design?
- What does it mean to say that a programmer should be able to treat a function as a black box?
- What is the purpose of the comment that accompanies a function declaration?
- What is the purpose of testing code that compiles?
^ top
Exercise 5.4
- Start a text file named exercise5.txt.
- Prepare the exercise header as described in the HowTo on submitting exercises
- Label this exercise: Exercise 5.4
- Record the answers to the following questions in exercise5.txt.
Questions
- What does top-down design mean?
- What does it mean to say that a programmer should be able to treat a function as a black box?
- What is the purpose of the comment that accompanies a function declaration?
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Day Schedule
| Eve Schedule
Course info
| Help
| FAQ's
| HowTo's
| Links
Last Updated: October 13 2005 @15:30:55
|