if
StatementOne of the easiest ways to make a program user-friendly is to make it menu driven. That is, rather than prompting the user in some vague sort of way, we present them with a menu of the choices available to them. This provides a friendly interface for the user, thus making the program easy to use.
For example, a simple 4-function calculator program might prompt the user by providing the following menu:
The menu tells the user exactly what to enter.Please enter: + to add two numbers. - to subtract two numbers. * to multiple two numbers. / to divide two numbers.
This lab's exercise is to complete such a program, and at the same time learn about some of the C++ control structures for selection and repetition.
calculate.cpp
contains some of the code to get started. You should download/copy this file
into whatever directory/folder/project you are using for this lab exercise.
main()
that
outputs your name, course, assignment information and any other
information required by your instructor.
if
StatementThe general pattern for an if
statement is:
if (Condition
)Statement1
[elseStatement2
]
Either Statement1
or Statement2
, but not both, is executed based on the value of
Condition
. If Condition
is true
,
then Statement1
is executed; otherwise (i.e.,
Condition
is false
), Statement2
is executed.
The square brackets [...]
in the pattern indicates that the
else
clause is optional. Sometimes a simple if
, without an else
, is all that is needed.
if
StatementWe can also chain several if
s together into one statement
by making Statement2
an
if
statement. If we do this several
times, we get a sequence of "nested if
s — one
if
inside another if
inside another . . . In this
case, we usually reformat it so that the various alternatives are clearly
seen and to emphasize that in this multi-alternative structure,
exactly one of the alternatives will be selected:
if (Condition1
)Statement1
else if (Condition2
)Statement2
... else if (ConditionN
)Statementn
elseStatementn+1
Exactly one of the Statementi
will be
executed. It will be the first Statementi
where Conditioni
is true
. All of the conditions that precede it must be false.
If all conditions fail, then the
fail-safe Statementn+1
is executed.
Helpful hint: Include a fail-safe else
in a multibranchif
— for example, an output statement that displays an error message.
Also, there is no condition in this fail-safe statement.
Helpful hint: The last else
in anyif
statement should not have a condition test.
The patterns above for the if
and multi-branch if
statements used the singular noun
"Statement
",
not "Statements
." We may put only one statement in those places in the
patterns.
But what if we need more than one statement? C++ allows us to wrap several statements in curly braces and the compiler will treat them as one statement:
{Statement1
Statement2
...Statementn
}
calculate.cpp
that uses
assert()
with an if
statement to check
if a legitimate operation was entered by the user.
If none was entered, an error message should be displayed that informs the
user of this (in a more friendly manner that the rather cryptic message
produced by assert()
) and then use exit(1);
to stop execution.Take a few moments to study calculate.cpp
, especially the
code in main()
. Make sure you understand the
purpose of each statement before continuing on with this lab.
Ignoring its error-checking code, we can describe the behavior of
main()
follows:
Our program should display on the screen a greeting, followed by a menu of permissible operations. It should then prompt the user for one of these operations and then input that operation from the keyboard. Next, it should then prompt the user for the two operands for that operation and then input those operands from the keyboard. It should then compute the result of applying the user-specified operation to the two operands. It should conclude by displaying that result on the screen with appropriate labeling.
All of this behavior has been coded in main()
except for the
sentence written in boldface. Since there is no predefined C++
capability to directly perform that operation, we must write the code
for this ourselves.
Behavior.
Our code must apply the operation toop1
andop2
and assign the resulting value to the variableresult
. More specifically, if the operation is'+'
, it should calculate the sum of the two operands and assign this sum toresult
. Otherwise, if the operation is'-'
, it should calculate their difference and assign that toresult
. Otherwise, if the operation is'*'
, our code should calculate the product of the two operands and assign it toresult
. Otherwise, if the operation is'/'
, it should calculate their quotient and assign this toresult
. And if it's none of these, it should just display an appropriate error message and stop execution.
Algorithm.
We can rewrite this description of behavior as follows so that it reads more like an algorithm:Ifoperation
is '+':
Assign the sum of the operands toresult
.
Otherwise, ifoperation
is '-':
Assign the difference of the operands toresult
.
Otherwise, ifoperation
is '*':
Assign the producte of the operands toresult
.
Otherwise, ifoperation
is '/':
Check if the denominator is zero.
If it is, display an appropriate error message and assign 0 toresult
;
otherwise, assign the quotient of the operands toresult
.
From this algorithm it is clear that a multi-branch
if
is needed and that a "nested"if
will be needed in the last alternative,
Coding.
calculate.cpp
, replace the comment
//***CALCULATE THE RESULT OF op1 operation op2
with a multi-branch if
statement that implements our
algorithm.
Testing and Debugging.
Coming Later ... an Aternative Selection Structure
The if
statement used in our calculator has one
drawback: it takes longer to reach the last alternative than it does
earlier ones.
(operation == '+')
.(operation == '+')
and (operation == '-')
.(operation == '+')
, (operation == '-')
, and (operation == '*')
.In general, selecting Statementi
using a multi-branch
if
statement requires the evaluation of i conditions.
This can be good because we can assume that the failed tests did, in
fact, fail. When testing for ranges of values, this is very
useful (and even necessary).
On the other hand, the evaluation of each condition consumes time,
statements that occur later in the multi-branch if
statement
take longer to execute than do statements that occur earlier. An alternative
that avoids this in certain cases is the switch
statement that
we will consider later.
for
and while
StatementsWe have seen that C++'s if
statement
selectively execute statements. In addition to selection
structures, most programming languages also provide statements that make it
possible to execute statements repeatedly, a programming
construct commonly referred to as a loop.
Let's consider our calculator example. In it's present form, if we have several operations we want to perform, we must re-execute the program each time. It would certainly be more convenient if we could do several calculations during a single execution.
C++ provides various kinds of loops and in this lab exercise we will consider two of them:
for
loop,while
loop,This part of the lab exercise will add more functionality to our calculator program and make it more user-friendly.
First, however, we will add another operation to the menu of operations
that our calculator can perform: an exponentiation operation that we
will denote by '^
'. It will calculate xn
where the operands x and n are entered by the user.
To simplify our task, we will assume that n is a nonnegative
integer.
Note: As we know, exponentiation is available in C++ via the
function pow()
in the cmath
library, but for this
lab, we will not use it so that we can practice writing loops.
When faced with a new problem that involves general objects, it is often helpful to solve it by hand first with some specific examples. To illustrate, 2^0, 2^1, 2^2, 2^3, 2^4 — i.e., 20, 21, 22, 23, 24 — by hand, we might write out expressions for these computations:
2^0 = 20 = 1
2^1 = 21 = 2 * 1
2^2 = 22 = 2 * 2
2^3 = 23 = 2 * 2 * 2
2^4 = 24 = 2 * 2 * 2 * 2
The first case defines our starting point. The other cases make explicit what we already know: for xn, n tells us how many times we need to use x as factor. How do you know we have enough factors? You count them! Now, if we could only count in our programs!
Behavior. We can describe what we want to happen as follows:
The user will enter a base value op1 and an exponent value op2. Our code should begin by initializing result to one, and then repeatedly multiply result by the base value, with the number of repetitions being the exponent value.
Although we could worry about negative exponents and real-number exponents, for simplicity, we won't. So we won't check for this but simply include it for information in the prompt for entering operands; and we will simply allow whatever "garbage" value gets computed as the result.
Exer. 4.6 Add an exponentiation operation tocalculate.cpp
as follows:
- Add another item to
MENU
about exponentiation.
- Modify the
if
statement that checks the validity of the operation entered by the user so that it includes exponentiation.
- Modify the prompt to enter the operands by adding a comment that the exponent should be a nonnegative integer for ^.
- Add another alternative to the
if-eise if ...
in the//*** CALCULATE THE RESULT OF op1 operation op2
section to implement the ^ operation. For now, just have it setresult
to 1.
- Compile and execute your code to check that these additions are working correctly.
Implementing the Exponentiation Operation Using C++'s
for
Loop.
We can rewrite the description of the behavior of the exponentiation
operation as the following algorithm:
The C++ for
loop is designed to facilitate the counting
behavior required by step 2. The pattern for such a counting
for
loop is:
wherefor (type
variable
=start_value
;variable
<=stop_value
;variable
++)statement
type
is a C++ numeric type,
variable
is the loop control variable used to do the
counting, start_value
is
the first value, and stop_value
is the last value.
For example, if we wanted to print x
20 times, we might
write the following algorithm:
for (int i = 1; i <= 20; i++) cout << x;
Exer. 4.7 Now complete the implementation begun in Exer. 4.6 of the algorithm above for the exponentiation operator. You already have implemented Step 1 of the algorithm so you need only add the for loop to implement Step 2.Be sure to compile and test your program. Test exponentiation with several values. Make sure you test 0 as an exponent. Try values larger than 2 and 3 as both bases and exponents.
The pattern for a C++ for
loop is actually more general:
for (
where initializationExpr
; condition
; stepExpr
)
statement
initializationExpr
is any initialization expression,
condition
is any boolean expression, and stepExpr
is an arbitrary expression.
If for some reason we wanted to count downwards and output the multiples of 12 from 1200 to 12, then we'd have this algorithm
i
.for (int i = 100; i >= 1; i--) cout << 12 * i << endl;
The condition
controls the loop. As long as it is true
when it is tested, then the loop statement
is executed.
C++ for
loops are controlled by conditions, just as if
statements are controlled by conditions. As we shall see, each
of the other C++ loop statements are also controlled by conditions.
A loop is categorized by when it evaluates its condition:
The for
loop is a pretest loop, because it evaluates its
condition before the loop's statement is executed.
The for
loop is designed primarily for problems that involve
counting through ranges of numbers, or problems in which the number
of repetitions can be determined in advance. The other C++ loops are
general-purpose loops, designed for problems where the
number of repetitions is not known in advance. We will use one of these
— the while
loop —
to modify the program so that the user can do more than one
calculation with each execution.
The algorithm that our program is using is basically as follows:
To incorporate the loop, we modify our algorithm:
'q'
) by which the user can indicate that they want to
quit. The condition (operation == 'q')
evaluates to true if the user wishes to quit.
Since checking this condition requires prior selection from the menu, our test for termination must be made after the user has made a selection. So we might modify our algorithm by moving "Loop:" down one line:
'q'
as the first operation, the loop will be an
infinite loop unless it includes another operation to be selected.
And where should this be done? After the previous operation has been
processed and the result displayed. So, we repeat instruction 2 again
at the bottom of the loop:
while (
where condition
)
statement
condition
is a boolean expression.
Exer. 4.8. Modify your source program to incorporate this approach. Then compile and test your program to ensure that it works correctly. Be sure to test each operator, including illegal ones.Exer. 4.9. Extend
calculate.cpp
into a six-function calculator, as follows:Again, be sure to test the operators to ensure that they work correctly.
- Add a factorial operation
!
that, given an integer n, computes n! = 1 * 2 * ... * (n-1) * n.- Redesign the exponentiation operator so that it handles negative exponents.
Hand In:
- A listing of your program
- Execution(s) with all of the operations and 'q'.
For the division operation, include executions with both zero and nonzero denominators.- An execution with an invalid operation
- An execution where the user selects 'q' first.