0% found this document useful (0 votes)
2 views17 pages

Chapter 8 Detailed Class Notes Updated

Chapter 8 discusses functional decomposition in programming, focusing on void functions and their design principles. It emphasizes the importance of creating user-defined functions to improve code organization and maintainability, particularly in larger programs. The chapter also covers interface design, encapsulation, and the syntax and semantics of void functions in C++.

Uploaded by

turfs247
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views17 pages

Chapter 8 Detailed Class Notes Updated

Chapter 8 discusses functional decomposition in programming, focusing on void functions and their design principles. It emphasizes the importance of creating user-defined functions to improve code organization and maintainability, particularly in larger programs. The chapter also covers interface design, encapsulation, and the syntax and semantics of void functions in C++.

Uploaded by

turfs247
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Chapter 8 Detailed Class Notes

8.1 Functional Decomposition with Void Functions


Remember, the 2 kinds of subprograms
1. Value-returning functions
2. Void functions

Value-returning functions – 1. receive data through its argument list 2. compute a single function value
3. returns this function value for the calling code.

The caller invokes (calls) a value-returning function by using its name and argument list in an expression.
Ex. y = 3.8 * sqrt (x);

A void function – 1. does not return a value 2. not called from within an expression but a complete
standalone statement. Ex. get function associated with istream and ifstream – [Link](inputChar);

In this chapter, we will concentrate exclusively on creating our own void functions. Chapter 9 will be
concerning our writing of value-returning functions.

We have been designing programs as collections of modules. Many of them are naturally implemented
as user-defined void functions.

When to Use Functions?

Let’s change our previous mindsets since we are moving from simple programs to larger and more
complex programs which may involve a team of programmers to work collectively to implement and
support.

While you can code any module as a function, the decision should be based on whether the program is
easier to be understood as a result.

If a module has (1) line then of course not. It would just over complicate it to write it as a function.
Adversely, if the module has many lines of code then simplify it by writing it as a function.

Implement a short module as a function if it will be used in several places within a program
Coding it in (1) place and calling it from many places yield better design because
1. less opportunity for errors or mistakes from recoding it multiple times
2. more efficient and easier to update that module or object of code. Update in one location or
conduct a search.
Recent Industry platforms that my associates within Corporate America’s fortune 500 companies are
using: Microsoft 365 PowerApps, Dell’s Boomi LowCode NoCode – all object-oriented coding modules.

Why do Modules Need an Interface Design?


Before converting a module to a function…..

Previously and up until now, our modules have simply been a group of statements that has access to all
of the values in a program. This works for small programs but not when we have large programs with
many modules.

In large complex programs, it is a bad idea to allow every module to access every value. PRIVACY,
Security, coordination of possible duplicate programmer identifiers, etc. are a concern. For this
purpose, the module’s design aspect needs an interface.

2 Views we can take on Interface Entrances or Doors

1. External – entrance or door to the module


2. Internal – entrances or doors within the module

Analogy – within a house people leave doors open but, in a hotel, doors to each room should be locked.

Designing Interfaces
We consider a module as a separate block within a design whose implementation details are “hidden”
(walled-off) from view.

Heading: void PrintActivity (int temp)

Precondition: temp is a temperature value in a valid range

Postcondition: A message has been printed indicating an appropriate activity given temperature
temp

Implementation

From the external perspective, as long as you know what a module does and how to call it, you can use
the module without knowing how it accomplishes its task. ex. sqrt – didn’t know yet used it.

A module’s interface is the formal description of what the subprogram does and how it is invoked or
how we communicate with it.
Hiding a modules’ implementation is called encapsulation. It is hidden in a separate block within a
formally specified interface.

Advantages of Encapsulation
1. no concerns or worries that it will accidentally access the values in other modules or that other
modules will be able to change its values
2. we can make internal changes to a module, as long as the interface remains the same

One way to specify the interface to a module is to write down its purpose (its precondition and
postcondition) and the information it takes and returns. This documentation is important when working
within a team so that we can hand it to someone who could implement the module for us.

Interfaces and encapsulations are the basis for team programming.

Designing a Module can be Separated into 2 Tasks


1. Designing the External Interface
2. Designing the Internal Implementation

Designing the External Interface


For the external interface, we focus on the “What” and not the “How”. We define what it does
(behavior) and the mechanism for communicating with it.

To define the mechanism for communicating with the module, we make a list of the below:
1. Incoming values that the module receives from the caller.
2. Outgoing values that the module produces and returns to the caller.
3. Incoming/outgoing values – values that the caller has that the module changes (receives and
returns)

Designing the Internal Implementation –


Internal View of the Interface as the starting point for our implementation.
1. Choose names for identifiers (that will exist as variables inside the module) each of which
matches a value in our list. These identifiers become the parameter list of the module. These
values are either incoming to the module or outgoing to the caller or both.
2. Write the parameters in the module heading. Any other variable that the module needs are
local and declared within its body. Do this for any module we anticipate implementing as a
function.
3. As part of the module interface, document the direction of the data flow for each parameter.

Data flow is the direction of flow of information between the caller and a module through each
parameter.

Now, let’s start coding C++ modules since we know how to design a module for implementation as a
function!
Writing Modules as Void Functions

It is simple to turn a module into a void function in C++.

1. a void function looks like a main function except the function heading uses void rather than int
as the data type of the function.
2. it doesn’t have a return 0; because remember a void function doesn’t return a value to its caller.

Example, does not have parameters. Friend is returning from a long trip and we will write a program to
print “Welcome Home!” message. p. 349

int main ()
void nameofvoidfunction (parameter)

Students and Instructor typed this program during class. You can use this program as one of your many
programs to post within your Weekly Discussion Board posts for a grade.

Remember, just like other C++ identifiers, the name of a function cannot include blanks. C++ function
definitions can appear in any order.

function prototypes – here are before the main function – void Print2Lines(); and void Print4Lines()
This is necessary because identifiers must be declared before using them. Comments are included to
describe the functions so main function makes sense. →Quick Check Questions on p. 353
8.2 An Overview of User-Defined Functions
More important points of function construction and learn how to use them.

Flow of Control in Function Calls


• While function definitions can be in any order, the compiler translates in the order they physically appear.
• When the program is executed it starts with the 1st statement after main and proceeds in logical order.

Review the previous chapters: When a function call is encountered within the main function, control
passes to the 1st statement in that function’s body. All statements are then executed in logical order
within that function’s body. After it is all executed then control is passed back to main to the next
statement following that function’s call.

Because functions alters the order of execution, functions are considered control structures.

Let’s rewrite the previous program to be more efficient because the 2 void functions are so similar that
we don’t need both. They merely print a different number of lines of asterisks.

Main --------------------------------------------------------------------------------------------------------- → Level 0


• Print lines (2)
• Print “Welcome Home!”
• Print lines (4)

Print Lines (ln:numLines) --------------------------------------------------------------------------------→ Level 1


• FOR count going from 1 to numLines
• Print “*****************”
Let’s type in the program from p. 355 together.
Function Parameters
• Parameter declaration = code between the parentheses.

Example, void PrintLines(int numLines); // Looks similar to variable declarations

• Reminder, items listed in the call to a function are the arguments. which constitute the external
view of a function’s interface.
• Argument – a variable or expression listed in a call to a function. (When you invoke a call)
• Parameter – a variable declared in a function heading (and prototype or just above the body )
(This is a must understand in order to understand the rest of the semester.)

Parameters provide identifiers within the function by which we can refer to the values supplied through
the arguments. The arguments of the functions are 2 and 4 within the above program. Parameters in
the PrintLines function is named numLines.

Let’s Walk Through the Program Flow Together:


1. Main function calls PrintLines with an argument of 2.
2. numLines initialized to 2.
3. Within PrintLines the count-controlled loop executes twice and the function returns.
4. 2nd time PrintLines is called the parameter numLines is initialized to the argument value of 4.
5. The loop executes 4 times then
6. The function returns.

Below is another version of the main function, just to show that the arguments can be variables instead
of constants.

int main ()
{
int lineCount;
lineCount = 2;
PrintLines (lineCount);
cout << “ Welcome Home! “ << endl;
lineCount = 4;
PrintLines(lineCount);
return 0;
}

In this version, each time main calls PrintLines, a copy of the value in lineCount is passed to the function
to initialize the parameters numLines. As you can see, the argument and the parameter (numLines) can
have different names.

Remember, void PrintLines(int numLines); // Looks like variable declarations

Again, a function can be called from many places. If a task must be done repetitively then a function is
appropriate to avoid repetitive coding.
If more than one argument is passed to a function, the argument and parameters are matched by their
relative positions in the two lists. For example, if PrintLines are to print another character and not only
asterisks then the code would be….

void PrintLines (int numLines, char whichChar) - (declaring the prototype above main)

a call to this Function might look like this:

PrintLines (3, ‘#’);  (could be the call from within the main function – the arguments)

the first argument, 3, is matched with numLines because it is the 1st parameter. Likewise, the 2nd
argument, ‘#’, is matched with the 2nd parameter, whichChar.

Review Questions within the book on page 356.

8.3 Syntax and Semantics of Void Functions

8.3.A – Function Call (Invocation)


To call (or invoke) a void function, we use its name as a statement, which the arguments in parentheses
following the name.

Here is the Syntax Template of a Function Call to a Void Function:

FunctionName (Argument);

• The argument list is optional, but the parentheses are required even if the list is empty.
• If the list includes two or more arguments, you must separate them with commas.
Syntax template for ArgumentsList:

Expression, Expression …..

When a function call is executed, the arguments are passed to the parameters according to their
positions, left to right, and control is then transferred to the first executable statement in the function
body. When the last statement in the function has executed, control returns to the point from which
the function was called.

8.3.B – Function Declaration and Definitions


In C++, a function’s declaration must physically precede any function call. Why? (common sense says …)
The declaration gives the compiler
1. The name of the function,
1. The form of the functions return value (either void or a data type like int or float) and,
2. The data types of the parameters
Function Prototype
a function declaration without the body of the function. Ex. void PrintLines (int numLines);

Function Definition
a function declaration that includes the body of the function. Examples:

int main () or void PrintLines (int numLines)


{ {
……. for ……
} cout ……
}

The NewWelcome program contains (3) function declarations. The first one (the statement
documented as the function prototype) does not include the body of the function. The other two -
main and PrintLines included the bodies of the function so they are function definitions.

Venn Diagram illustrates that all definitions are declarations


Function but not all declarations are definitions.
declarations
In general, C++ distinguishes declarations from definitions as
it relates to memory space allocation. Since a function
Functions prototype is merely a declaration not much memory is
definitions allocated. A function definition does require more memory
(declarations allocation. The compiler allocates memory for the
with bodies) instructions in the body of the function. Makes sense.

C++ Rule → You can declare an item as many times as you wish, but you can define it only once.
For Example, in the NewWelcome program, we could include many function prototypes for PrintLines
but only (1) function definition is allowed.

8.3.B.1 – Function Prototypes


They allow us to declare functions before they are defined. C++ programmers typically define main first
but it is not required. A program will always begin with the main function no matter what.

A Function Prototype for a Void Function has the following Syntax:

void FunctionName (ParameterList);

No body is included and a semicolon terminates the declaration. The parameter list is optional, to allow
for parameterless functions. If the parameter list is present, it has the following form:
ParamentList (in a Function Prototype)

Datatype & VariableName, DataType & Variable Name …)

The ampersand (&) attached to the name of the data type is optional and has a special significance what
we will cover in a later chapter.

In a function prototype, the parameter list must specify the data types of the parameters, but their
names are optional. For example,

void DoSomething (int, float);


or
void DoSomething (int velocity, float angle);

Sometimes adding the names is useful for documentation purposes to supply names for the parameters,
but be aware that the compiler ignores them.

8.3.B.2 - Function Definitions


In Chapter 2, we learned that a function consist of 2 parts: the function heading and the function body
which is syntactically a block (compound statement).

Here is the Syntax Template for a Function Definition – specifically for a Void Function:

void FunctionName (ParameterList)


{
Statement
…..
}

Notice that the function heading does not end in a semicolon the way a function prototype does.
Putting a semicolon at the end of the line will generate a syntax error.

The syntax of the parameter list differs slightly from that of a function prototype in that you must
specify the names of the parameters. Also, its our style preference (but not a C++ language
requirement) to declare each parameter on a separate line. For example, ….

ParameterList (in a Function Definition):


Datatype & VariableName,
Datatype & Variable Name,
……

8.3.C – Local Variables


Local variables – a variable declared within a block and not accessible outside of that block.

All functions are global variables because they are declared outside of main
As far as the calling code is concerned those local variables (for the function called) do not exist within
the environment where the function is called. In fact, if you tried to print the contents of a local variable
from another function, a compile-time error such as UNDECLARED IDENTIFIER could occur. For example,
the local variable, count, in the NewWelcome program was declared within the PrintLines function.

Unlike local variables, global variables are declared outside of all the functions in a program. (more
about this in Chapter 9).

• Local variables occupy memory space only while the function is executing. At the moment, the
function is called, memory space, is created for its local variables.
• When the function returns, its local variables are destroyed. (We will see an exception to this rule in Chapter 9).
Therefore, every time the function is called, its local variables start out with their undefined.

• Because every call to a function is independent of every other call to that same function, you
must initialize the local variables within the function itself.
• Also, because local variables are destroyed when the function returns, you cannot use them to
store values between calls to the function.

This code illustrates each of the parts of the function declaration and calling mechanism:

#include <iostream>
using namespace std;

void TryThis (int, int, float); // Function Prototype for TryThis

int main () // Function definition for main


{
int int1; // Variables local to main
int int2;
float someFloat;
……
TryThis (int1, int2, someFloat); // Function call with three arguments
…..
}
void TryThis (int param1, // Function call with three parameters
int param2,
float param3)
{
int i; // Variables local to TryThis
float x;
….
}

8.3.C -- The Return Statement


The main function uses the statement → return 0;
to return the value 0 to its caller, the operating system.

The Void Function does not return a function value. Control returns from the function when it “falls off”
the end of the body after the last statement is executed.

Subprograms or void function can either not have a return statement - OR - a return statement like this

return;

This statement is valid only for void functions. As you saw in the NewWelcome program, the PrintLines
function simply prints some lines of asterisks and then returns.

• It (return;) can appear anywhere in the body of the function; it causes control to exit the
function immediately and return to the caller. For example,

void Some (int n)


{
if ( n > 50)
{
cout << “The value is out of range.”;
return;
}
n = 412 + n;
cout << n;

Another way of writing this function is to use an If-Then-Else structure:

void SomeFunc (int n)


{
if ( n > 50)
cout << “The value is out of range.”;
else
{
n = 412 * n;
cout << n;
}
}

In this example, there are (2) ways for control to exit the function. (You tell me → “How is this”?) At
function entry, the value of n is tested. If it is > 50 function prints a message and returns immediately
without executing any more statements. If n is less than or = to 50, the IF statements then clause is
skipped and control proceeds to the assignment statement. After the last statement, control returns
to the caller.

This is just a different option for you as a programmer. Use it if it makes more sense to you but use it
sparingly = recommendation. It allows for multiple exits for a function.
8.4 – Parameters
When a function is executed, it uses the arguments give to it in the function call. How is this done? It
depends on the nature of the parameters.

2 Types supported by C++ are:


1. value parameters – a parameter that receives a copy of the value of the corresponding argument.
2. reference parameters – a parameter that receives the location (memory address) of the caller’s
argument.

• With a value parameter, which is declared without an (&) ampersand at the end of the data type
name, the function receives a copy of the argument(s)’ value.

• With the reference parameter, which is declared by adding an ampersand (&) to the data type
name, the function receives the location (memory address) of the caller’s argument.

Example, function heading with a mixture of reference and value parameter declarings.

void Example (int& param1, //A reference parameter


int param2, // A value parameter
float param3) // Another value parameter

with simple data types (int, char, float … ) – a value parameter is the default (assumed) kind of
parameter.

(Pay close attention from here out so that you don’t waste time understanding the content and need to
spend more time reviewing it on your own later. Attention, look, watch, listen ….. If I get to step 8 and
you ask me to re-explain all of the previous steps then I will ask you to read this again or read the book.)

What happens if a function assigns a new value to a value parameter?


What happens if a function assigns a new value to a reference parameter?
Answers:
1. There will be 2 copies of the value. One will be changed within the function while the
value remains the same outside the function
2. It will change the location of the argument.
The value parameter stores the new value but the argument is unaffected. The
reference parameter stores the new value directly into the argument.
Value parameters - If a new value is assigned then its value will change. However, it
won't affect the original argument's value. Value parameters have two copies of data.
If a new value is assigned to a reference then the location of the original argument will
change. Reference parameters only have 1 copy of its data.
Value Parameters
In the NewWelcome program, the PrintLines function heading is

void Printlines (int numLines)

The parameter numLines is a value parameter because its data type name doesn’t end with &. If the
function is called using an argument lineCount,

PrintLines (lineCount);

then the parameter numLines receives a copy of the value of lineCount. At this moment, there are two
copies of the data – one in the argument lineCount and one in the parameter numLines. If a statement
inside the PrintLines function were to change the value of numLines, this change would not affect the
argument lineCount (remember, there are two copies of the data). As you can see, using value
parameters help us avoid unintentional changes to arguments.

Because value parameters are passed copies of their argument, anything that has a value may be passed
to a value parameter. This includes constants, variables, and even arbitrarily complicated expressions.
(The expression is simply evaluated and a copy of the result is sent to the corresponding value
parameter.) For the PrintLines function, the following function calls are all valid:

PrintLines (3);
PrintLines (lineCount);
PrintLines (2 * abs (10 – someInt) );

There must be the same number of arguments in a function call as there are parameters in the function
heading. Also, each argument should have the same data type as the parameter in the same position.
Notice how each parameter in the following example is matched to the argument in the same position
(the data type of each argument is what you would assume from its name):

Function heading: void ShowMatch (float num1, int num2, char letter)

Function call: ShowMatch ( floatVariable, intVariable, CharVariable);

If the matched items are not of the same data type, implicit type coercion takes place. For example, if a
parameter is of type int, an argument that is a float expression is coerced to an int value before it is
passed to the function. As usual in C++, you can avoid unintended type coercion by using an explicit
type cast or, better yet, by not mixing data types at all.

As it has been stressed, a value parameter receives a copy of the argument and, therefore, the caller’s
argument cannot be accessed directly or changed. When a function returns, the contents of its value
parameters are destroyed, along with the contents of its local variables. The difference between value
parameters and local variables is that the values of local variables are undefined when a function starts
to execute, whereas value parameters are automatically initialized to the values of the corresponding
arguments.
Because the contents of value parameters are destroyed when the function returns, they cannot be
used to return information to the calling code. What if we do want to return information by modifying
the caller’s arguments? We must use the second kind of parameter available in C++: reference
parameter. Let’s look at these in more detail now.

Reference Parameters
A reference parameter is one that you declare by attaching an ampersand to the name of its data type.
It is called a reference parameter because the called function can refer to the corresponding argument
directly. Specifically, the function is allowed to inspect and modify the caller’s argument.

When a function is invoked using a reference parameter, it is the location (the memory address) of the
argument – not its value – that is passed to the function. Only one copy of the information exists, and it
is used by both the caller and the called function. When a function is called, the argument and the
parameter becomes synonyms for the same location in memory. When a function returns control to its
caller, the link between the argument and the parameter is broken. They are synonymous only during a
particular call to the function. The only evidence that a matchup between the two every occurred is
that the contents of the argument may have changed. See below → Using a Reference Parameter to Access an Argument
When flow of control is in the main function,
temperature can be accessed as shown by the arrow.
temperature
int main() } Variable temperature
declared by main function

void GetTemp (int& temp)

temperature

When flow of control is in function GetTemp, every } Variable temperature


reference to temp accesses the variable temperature. declared by main function

int main()

void GetTemp (int& temp)

(Using a Reference Parameter to Access an Argument)

Whatever value is left by the called function in this location is the value that the caller will find there.
You must be careful when using a reference parameter, because any change made to it affects the
argument in the calling code. Here is an example of a heading and a call:

Function heading: void ShowMatch (float& num1, int num2, char& letter)

Function call: ShowMatch (floatVar, intVar, CharVar):


For the highlighted arguments, the addresses of floatVar and charVar are passed to num1 and letter,
respectively. Because num2 is a value parameter, it receives the value stored in intVar.

Another important difference between value and reference parameters relates to matching arguments
with parameters. With value parameters, it was stated that implicit type coercion occurs (the value of
the argument is coerced, if possible, to the data type of the parameter). In contrast, reference
parameters require that the match items must have exactly the same data type.

Earlier in this chapter, we discussed documenting data flow direction in modules. Function parameters
corresponding to Out and In/out module parameters must have an ampersand to In parameters.

The table below summarizes the usage of arguments and parameters.


Item Usage
Argument Appears in a function call. The corresponding parameter may be either a refence parameter (&)
or a value parameter.
Value parameter Appears in a function heading. Receives a copy of the value of the corresponding argument,
which will be coerced if necessary.
Reference parameter Appears in a function heading. Receives the address of the corresponding argument. Its
corresponding type must have an ampersand (&) appending to it. The type of an argument must
exactly match the type of the parameter.
If you want deeper “hands-on” experience coding these related concepts then read/code pp. 365 – 370.

Value parameters - If a new value is assigned then its value will change. However, it
won't affect the original argument's value. Value parameters have two copies of data.
If a new value is assigned to a reference then the location of the original argument will
change. Reference parameters only have 1 copy of its data.

Using Expressions with Parameters


Only a variable should be passed as an argument to a reference parameter because a function can
assign a new value to the argument. (In contrast, an arbitrarily complicated expression can be passed to
a value parameter.) Suppose that we have a function with the following heading:

void DoThis (float val, // Value parameter


int& count) // Reference parameter

Then the following function calls are all valid:

DoThis (someFloat, someInt);


DoThis (9.83, intCounter);
DoThis (4.9 * sqrt (y), myInt);

In this DoThis function, the first parameter is a value parameter, so any expression is allowed as the
argument. The second parameter is a reference parameter, so the argument must be a variable name.
The statement

DoThis (y, 3);


generates a compile-time error because the second argument isn’t a variable name. Earlier we said the
syntax template for an argument list is

ArgumentList

Expression , Expression ……

Keep in mind, however, that Expression is restricted to a variable name if the corresponding parameter
is a reference parameter.

The below table summarizes the appropriate forms of arguments.


Parameter Argument
Value parameter A variable, constant, or arbitrary expression (type coercion may take place
Reference parameter (&) A variable only, of exactly the same data type as the parameter

A Last Word of Caution About Argument and Parameter Lists


It is the programmer’s responsibility to make sure that the argument list and parameter list match up
semantically as well as syntactically.

For example, suppose we had written the modification to the LoanCalculator program as follows. Can
you spot the error?

int main ()
{
…..
GetRest (monthlyInterest, numberOfYears);
numberOfPayments = numOfYears * 12;
DeterminePayment (monthlyInterest, loanAmount,
numberOfPayments, payment);
….
}

The argument list in the last function call matches the corresponding parameter list in its number and
type of arguments, so no syntax error message would be generated. However, the output would be
wrong because the first two arguments are switched. If a function has two parameters of the same data
type, you must be careful that the arguments appear in the correct order.

Later in the textbook, we will learn how to write multifile programs and hide implementations
physically. In the meantime, conscientiously avoid writing code that depends on the internal workings
of a function.

Writing Assertions as Function Documentation


We have been talking informally about preconditions and postconditions. From now on, we include
preconditions and postconditions as comments to the document function interfaces. Example below:
void PrintAverage (float sum
int count)
// Pre: sum has been assigned and count is greater than 0
// Post: The average has been output on one line
{
cout << “Average is “ << sum / float(count) << endl;
}

The precondition is an assertion describing everything that the function requires to be true at the
moment when the caller invokes the function. The postcondition describes the state of the program at
the moment when the function finishes executing.

You can think of the precondition and the postcondition as forma a contract. The contract state that if
the precondition is true as the function entry, then the postcondition must be true at the function exit.
The caller is responsible for ensuring the precondition, and the function body must ensure the
postcondition. If the caller fails to satisfy its part of the contract (the precondition), the contract is off;
the function cannot guarantee that the postcondition will be true.

In the preceding example, the precondition warns the caller to make sure the sum has been assigned a
meaningful value and that count is positive. If this precondition is true, the function guarantees it will
satisfy the postcondition. If count isn’t positive when PrintAverage is invoked, the effect of the module
is undefined. (For example, if count equals 0, the postcondition surely isn’t satisfied – any code that
implements this module crashes!)

Sometimes the caller doesn’t need to satisfy any precondition before calling a function. In this case, the
precondition can be written as the value true or simply omitted. In the following example, no
precondition is necessary:

void Get2Ints (int& int,


int& int2)
// Post: User has been prompted to enter two intergers
// int1 is the first input value
// int2 is the second input value
{
cout << “Please enter two intergers; “ << endl;
cin >> int1 >> int2;
}

Read pages 387 – 389 for more information concerning Testing and Debugging and especially read the
Summary on page 390.

Review and challenge yourself with the end of the chapter Exam Preparation Exercises, the
Programming Warm-up Exercises, and the Programming Problems.

You might also like