You are on page 1of 58

Chapter XIV

Parameter Functions II

Chapter XIV Topics


14.1 Introduction

14.2 Void Functions that Return Values

14.3 One-Way, Two-Way, and Mixed-Way Parameters

14.4 Parameter Vocabulary

14.5 Parameters, a Technical Explanation

14.6 Test Your Parameter Knowledge

14.7 Parameters Without Identifiers

14.8 Inline Functions

14.9 Overloaded Functions

14.10 Parameter Rules

14.11 Worked-Out Exercises

Chapter XIV Parameter Functions II 14.1


14.1 Introduction

Functions must be bothering you by now. Many chapters ago you were
introduced to simple functions. Life was good back then. There was minimal
headaches about parameters, and modularity was the main concern. Now you are
getting bombarded by functions and the end does not seem to be in sight yet.

The last chapter introduced user-defined functions that used parameters. You
used both void and return functions. The name of the parameters in those
functions were called value parameters. A value is passed to a function. The
function makes a copy of the passed value, and processes information according
to the program statements in the function.

Now there is still more function business. In this chapter we will talk about
variable or reference parameters. This type of parameter is very different from
the earlier value type. It appears that this parameter has the ability to pass
information back to the calling program segment.

Take all this parameter business seriously. You need a very thorough, solid,
understanding of parameters. It will be the foundation of everything that follows
in future chapters. Whether you continue computer science in high school or
whether you continue in college or the business world, computer science will
expect a thorough knowledge of parameters.

So what is the story on these variable-whatever-reference parameters? Well,


consider this. Right now the way to get information from a function is with a
return function. This works very well in many situations, but there is a serious
limitation. A return function returns a single value. Frequently, there is a need to
return multiple values from a function. How is that accomplished? You guess
very well. It is done with these nifty variable/reference parameters, which is the
main focus of this chapter.

One word of warning before you plunge into this chapter. You need to be on
fairly solid ground with void functions and return functions. If you have casually
glanced through the previous chapter or if you are unsure, even after serious
studying, go back. Adding the information in this chapter on top of existing
function-confusion will not be real productive. Study the previous chapter some
more, get extra help, but whatever you do, learn the previous material first.

Chapter XIV Parameter Functions II 14.2


14.2 Void Functions that Return Values

Simple void functions can only pass information with global variables. That is a
serious nono. Ugly, yukky, side effects can creep into your programs with global
variable information passing. You did use that approach for a while for the sake
of going through a gentle introduction to program modularity. That stage has now
passed and you are entering the proper world of programming development.

Void functions with value parameters pass information in one direction. The
program segment that calls the function sends information to the function. The
void function is on the receiving end of the parameter passing business. We also
have return functions that have the ability to return information from the function.
These functions receive information - usually with value parameters - digest the
information and return some value. We could call these return functions, two-
way information functions.

There is yet another information passing approach. You can also use void
functions that are two-way information functions. The purpose of this section is
to investigate how it is possible - and why it is desirable - to use void functions
for any two-way information schemes.

Take a quick look at two return functions that were shown in the previous chapter.
Program PROG1401.CPP and PROG1402.CPP use functions that return the
next integer and the upper-case of a lower-case letter. These programs are
repeated for comparison reasons.

// PROG1401.CPP
// This program uses a return function to get the next
integer.

#include <iostream.h>
#include <conio.h>

int NextInt(int Nr);

void main()
{
clrscr();
int Number;
cout << "ENTER AN INTEGER ===>> ";

Chapter XIV Parameter Functions II 14.3


cin >> Number;
cout << endl;
cout << "NEXT INTEGER IS " << NextInt(Number) <<
endl;
getch();
}

int NextInt(int Nr)


{
Nr++;
return Nr;
}

PROG1401.CPP OUTPUT

ENTER AN INTEGER ===>> 19

NEXT INTEGER IS 20

// PROG1402.CPP
// This program uses a return function to change a
lower-case
// letter to an upper-case letter.

#include <iostream.h>
#include <conio.h>

char UpCase(char Ltr);

void main()
{
char Letter;
clrscr();
cout << "ENTER A LOWER CASE LETTER ===>> ";
cin >> Letter;
cout << endl;
cout << "UPPER CASE LETTER (IF POSSIBLE) IS "
<< UpCase(Letter);
cout << endl;
getch();
}

char UpCase(char Ltr)


{

Chapter XIV Parameter Functions II 14.4


if ((Ltr >= 'a') && (Ltr <= 'z'))
Ltr = Ltr - 32;
return Ltr;
}

PROG1402.CPP OUTPUT

ENTER A LOWER CASE LETTER ===>> a

UPPER CASE LETTER (IF POSSIBLE) IS A

Program PROG1403.CPP uses a void function to accomplish the same process


as the earlier program did with a return function. Check out the program below
and observe any differences compared to the previous return functions.

// PROG1403.CPP
// This program uses a void function to get the next
integer.

#include <iostream.h>
#include <conio.h>

void NextInt(int &Nr);

void main()
{
clrscr();
int Number;
cout << "ENTER AN INTEGER ===>> ";
cin >> Number;
cout << endl;
NextInt(Number);
cout << "NEXT INTEGER IS " << Number << endl;
getch();
}

void NextInt(int &Nr)


{
Nr++;
}

Chapter XIV Parameter Functions II 14.5


PROG1403.CPP OUTPUT

ENTER AN INTEGER ===>> 19

NEXT INTEGER IS 20

Void function NextInt is different from the return function NextInt because of
the difference between void and return functions. That is not new. Both the
function syntax and the function calling approach is different between void and
return functions. These differences can be reviewed in the last chapter. The
difference you should have observed is an odd looking ampersand (&) in the
function heading of NextInt.

void NextInt(int &Nr)

The output of the program indicates that it does provide the next integer to the
main function. Try the program yourself, you will find that it works correctly and
apparently behaves in the same manner as the earlier program with the return
function.

Now look at program PROG1404.CPP and see if you can detect any type of
pattern. This program alters a lower-case letter to an upper-case letter. You can
trust the provided output, but better yet, type the program in yourself and test
yourself to see that the output matches your expectations.

// PROG1404.CPP
// This program uses a void function to change a lower-
case
// letter to an upper-case letter.

#include <iostream.h>
#include <conio.h>

void UpCase(char &Ltr);

Chapter XIV Parameter Functions II 14.6


void main()
{
char Letter;
clrscr();
cout << "ENTER A LOWER CASE LETTER ===>> ";
cin >> Letter;
cout << endl;
UpCase(Letter);
cout << "UPPER CASE LETTER (IF POSSIBLE) IS " <<
Letter;
cout << endl;
getch();
}

void UpCase(char &Ltr)


{
if ((Ltr >= 'a') && (Ltr <= 'z'))
Ltr = Ltr - 32;
}

PROG1404.CPP OUTPUT

ENTER A LOWER CASE LETTER ===>> a

UPPER CASE LETTER (IF POSSIBLE) IS A

Is an pattern noticeable? There should be ... by looking at the function heading.


Once again, an odd & is noticed in the function heading next to the parameter.
The function headings really look pretty much like regular void function headings
that use value parameters, first introduced in the last chapter. Everything is the
same, except for the &.

void NextInt(int &Nr)

void UpCase(char &Ltr)

Chapter XIV Parameter Functions II 14.7


The innocent looking (&) has a tremendous impact on parameters Nr and Ltr.
Suddenly Nr and Ltr are no longer value parameters, limited in receiving
information in one direction from the corresponding parameters in the function
calls. Nr and Ltr are now variable parameters. It is now possible to pass
information in both directions. The magic (&) not only allows information to be
passed to the function. Some process can then occur in the function like
computing the next integer, and yes information can then be passed from the
function back to the calling segment.

You are entirely unimpressed. Right now it seems that void functions with the
assistance of a weirdly placed (&) manage to accomplish the same task as the
return function already did in the last chapter. Furthermore, you were much more
impressed with the return function’s approach. Each return function performed its
required process and at the conclusion of the function, the clever return statement
passed the appropriate value back to the calling program segment.

Now computer scientists as a rule are a logical bunch of people. The inclusion
and creation of some feature is normally for the purpose of accomplishing
something that cannot be done some other way. At least the required task cannot
be done as efficiently without the newly included feature.

You see, return functions have one very important limitation: return functions
only return one value. The examples that were used returned the next integer and
the upper-case letter. Consider all the common math functions, like square root,
absolute value and rounding off. All such functions only return a single value. In
each one of those situations you should use a return function. But there are other
situations and a good example is function Swap. This functions requires that two
parameters exchange their values. In other words, two values need to be returned
to the calling program segment. In this case the return function politely bows its
head and allows some other function to do the job.
Program PROG1405.CPP demonstrates how to exchange values with a Swap
void function that uses two variable parameters.

// PROG1405.CPP
// This program returns two altered parameters.
// It demonstrates a swap function.

#include <iostream.h>
#include <conio.h>

void Display(int A, int B);


void Swap(int &A, int &B);

Chapter XIV Parameter Functions II 14.8


void main()
{
int N1 = 5, N2 = 7;
clrscr();
Display(N1,N2);
Swap(N1,N2);
Display(N1,N2);
getch();
}

void Display(int A, int B)


{
cout << endl << endl;
cout << "A = " << A << endl;
cout << "B = " << B << endl;
}

void Swap(int &A, int &B)


{
int T;
T = A;
A = B;
B = T;
}

PROG1405.CPP OUTPUT

A = 5
B = 7

A = 7
B = 5

The Swap function does not show any special magic. The same & business
shown with NextInt and UpCase is now done with Swap. The & is used twice
because we are using two variable parameters, but logically the concept is the
same. This type of function is precisely why void functions with two-way
parameters exist. Try swapping with a return function. You will need some
serious imagination to accomplish that trick.

Chapter XIV Parameter Functions II 14.9


We can even get fancier and use three variable parameters. How about function
Sort that uses three integer parameters and returns the three parameters neatly
sorted? That would be pretty impressive. A function that sorts data is a classic
example of the use of variable parameters. An unsorted set of numbers is passed
to the function and a nicely sorted list is returned to the calling program segment.
You may question the practicality of sorting only three numbers, but right now the
thought is what counts. Sorting numbers is such a nice example of using two-way
parameters and real practical sorting requires features that will be introduced in
later chapters. Right now we will keep it simple by sorting three numbers.

By the way, note how program PROG1406.CPP cleverly uses the Swap
function that we introduced in the previous program. In one program we use two
void functions that use two-way parameter passing. Pretty impressive stuff. The
actual code in function Sort can be altered. There are a variety of techniques to
sort data. The sorting approach demonstrated works, and the main point of the
function is to show an example of using two-way parameter passing.

// PROG1406.CPP
// This program sorts three numbers from smallest to
largest.

#include <iostream.h>
#include <conio.h>

void Display(int A, int B, int C);


void Swap(int &X, int &Y);
void Sort(int &A, int &B, int &C);

void main()
{
clrscr();
int N1,N2,N3;
cout << "Enter three integers ===>> ";
cin >> N1 >> N2 >> N3;
Display(N1,N2,N3);
Sort(N1,N2,N3);
Display(N1,N2,N3);
getch();
}

Chapter XIV Parameter Functions II 14.10


void Display(int A, int B, int C)
{
cout << endl << endl;
cout << A << " " << B << " " << C << endl;
}

void Sort(int &A, int &B, int &C)


{
if (A > B)
Swap(A,B);
if (C < A)
Swap(A,C);
if (B > C)
Swap(B,C);
}

void Swap(int &X, int &Y)


{
int T;
T = X; X = Y; Y = T;
}

PROG1406.CPP OUTPUT

Enter three integers ===>> 3 1 2

3 1 2

1 2 3

14.3 One-Way, Two-Way and Mixed-Way


Parameters

Chapter XIV Parameter Functions II 14.11


The last chapter introduced one-way parameters. They are the value parameters
that pass information from the function call to the function. No information can
be returned or passed back via the value parameter. Return functions do return
information, but not with the value parameter.

This chapter introduced the new idea of using void functions with two-way
parameters. Information is passed from the function call to the function and after
some process - such as sorting - altered information is passed back to the program
segment of the function call. All the program examples have used functions that
either used value (one-way) parameters exclusively or used only variable (two-
way) parameters exclusively. It is also possible to mix both types of parameters
in one function. In this section we will look at a simple payroll program and
observe what types of parameters will be used in each function. Along the way,
you will note that it is very normal to have functions that use a combination of
value and variable parameters.

The payroll program will also demonstrate how to pass information in a program.
You will note that all information that is passed between the functions is passed
by parameters. Passing information with global variables was a temporary stage
in your computer science development. As a matter of fact, it will be wise not to
mention this stage to other computer science people. Many folks in the computer
science community will be shocked that you were exposed to evil, global,
information passing.

Program PROG1407.CPP Main function

The first step is to consider the main function of the payroll program. At this
stage you decide what information is required to and from each function called in
the main program function. At every stage, ask the question if the information
will change or if the information is now fixed and will no longer be altered. That
answer will determine if a parameter becomes a value or variable parameter. Do
not turn the page too quickly. See if you can pick the proper parameters yourself.

// PROG1407.CPP
// This program computes a simple payroll.
// It demonstrates value, reference and mixed
parameters.

void main()
{
int HoursWorked; // hours worked per week
double HourlyRate; // payrate per hour
double GrossPay; // pay before deductions
double Deductions; // tax deductions

Chapter XIV Parameter Functions II 14.12


double NetPay; // total take-home pay

EnterData(HoursWorked,HourlyRate);
CompGross(HoursWorked,HourlyRate,GrossPay);
CompDeduct(GrossPay,Deductions);
CompNet(GrossPay,Deductions,NetPay);

DisplayData(HoursWorked,HourlyRate,GrossPay,Deductions,
NetPay);
}

Payroll Program, Main Function and Prototypes

The next level of our payroll program identifies the value and variable
parameters. This is a good example of the virtue of using prototypes. Placing the
prototypes ahead of the main function allows you to view the communication
between the main function and the major functions in the program. This makes it
easier to decide on the nature of each parameter.

// PROG1407.CPP
// This program computes a simple payroll..
// It demonstrates value, reference and mixed parameters.

#include <iostream.h>
#include <conio.h>
#include <iomanip.h>

void EnterData(int &HW, double &HR);


void CompGross(int HW, double HR, double &GP);
void CompDeduct(double GP, double &DD);
void CompNet(double GP, double DD, double &NP);
void DisplayData(int Hw, double HR, double GP, double DD, double NP);

void main()
{
int HoursWorked; // hours worked per week
double HourlyRate; // payrate per hour
double GrossPay; // pay before deductions
double Deductions; // tax deductions
double NetPay; // total take-home pay

EnterData(HoursWorked,HourlyRate);
CompGross(HoursWorked,HourlyRate,GrossPay);
CompDeduct(GrossPay,Deductions);
CompNet(GrossPay,Deductions,NetPay);
DisplayData(HoursWorked,HourlyRate,GrossPay,Deductions,NetPay);
}

Chapter XIV Parameter Functions II 14.13


Function EnterData is called first. Parameters HoursWorked and HourlyRate
will receive information entered at the keyboard in the EnterData function. This
means that both parameters will change, and must be variable parameters.
Student frequently have difficulty here. It is natural to view this situation as one-
way parameter passing from the function to the calling segment. This is true in
the useful information-passing-sense. It is not true in the technical sense. Once
HoursWorked and HourlyRate are defined in the main function, some arbitrary
value will be assigned in each memory location. This means that HW and HR
start out with some unknown values. However, these unknown value do change.
They vary and as such we must use variable parameters in this function.

The next function call needs to compute the gross pay of the employee. This is
done with function CompGross. In this function HW and HR will be used to
compute the gross pay, GP. This means that HW and HR will not change and are
value parameters. GP does change and must be a variable parameter.

We now follow the same logic with function CompDeduct. This function takes
the gross pay, GP, and computes deductions, DD, based on total earnings. GP
now does change and is a value parameter. Deductions, DD, does change and
becomes a variable parameter.

You have figured it out, right? In function CompNet, the only parameter that
changes is the net pay, NP. Parameters GP and DD are used to compute NP, and
will not change.

In the final function, DisplayData, every parameter is a value parameter. Only


information is shown. Nothing is processed and nothing changes.

General Parameter Selection Rule

Programs, generally speaking, consist of input, process, and


output type of functions.

Parameters in an input function normally use two-way


information passing with variable parameters.

Chapter XIV Parameter Functions II 14.14


Parameters in a process function normally use mixed-way
information passing with a combination of value and
variable parameters.

Parameters in an output function normally use one-way


information passing with value parameters.

The Complete Payroll Program

Check out the complete payroll program now. In particular, trace the information
as it is passed between the different program modules. Stick with this program
until it is clear to you why parameters are value or why they are variable.

// PROG1407.CPP
// This program computes a simple payroll.
// It demonstrates value, reference and mixed
parameters.

#include <iostream.h>
#include <conio.h>
#include <iomanip.h>

void EnterData(int &HW, double &HR);


void CompGross(int HW, double HR, double &GP);
void CompDeduct(double GP, double &DD);
void CompNet(double GP, double DD, double &NP);
void DisplayData(int Hw, double HR, double GP, double DD, double NP);

void main()
{
int HoursWorked; // hours worked per week
double HourlyRate; // payrate per hour
double GrossPay; // pay before deductions
double Deductions; // tax deductions
double NetPay; // total take-home pay

Chapter XIV Parameter Functions II 14.15


EnterData(HoursWorked,HourlyRate);
CompGross(HoursWorked,HourlyRate,GrossPay);
CompDeduct(GrossPay,Deductions);
CompNet(GrossPay,Deductions,NetPay);

DisplayData(HoursWorked,HourlyRate,GrossPay,Deductions,
NetPay);
}

void EnterData(int &HW, double &HR)


{
clrscr();
cout << "Enter hours worked ===>> ";
cin >> HW;
cout << "Enter hourly rate ===>> ";
cin >> HR;
}

void CompGross(int HW, double HR, double &GP)


{
GP = HW * HR;
}

void CompDeduct(double GP, double &DD)


{
double Tax; // federal tax
double SS; // social security and medicare
deductions
Tax = GP * 0.15;
SS = GP * 0.0765;
DD = Tax + SS;
}

void CompNet(double GP, double DD, double &NP)


{
NP = GP - DD;
}

void DisplayData(int HW, double HR, double GP, double DD, double NP)

Chapter XIV Parameter Functions II 14.16


{
cout << endl << endl;
cout << setprecision(2);
cout << "Hours Worked: " << HW << endl;
cout << "Hourly Rate: " << HR << endl;
cout << "Gross Pay: " << GP << endl;
cout << "Deductions: " << DD << endl;
cout << "Net Pay: " << NP << endl;
getch();
}

PROGRAM PROG1407.CPP

Enter hours worked ===>> 17


Enter hourly rate ===>> 6.85

Hours Worked: 17
Hourly Rate: 6.85
Gross Pay: 116.45
Deductions: 26.38
Net Pay: 90.07

14.4 Parameter Vocabulary

We are not finished with this function business, but before we move on you need
to have a good, solid grasp of the vocabulary used with parameters. You will be
better prepared for future computer science courses, and my job will be simpler in
future chapters when I can assume a strong foundation in parameter terminology.

The complexity with parameter vocabulary is the result of two facts. First, there
are a variety of names for the exact same concepts, and you need to be sure that

Chapter XIV Parameter Functions II 14.17


you know all those names. It is silly to try to figure out the difference between
two types of parameters that turn out to be the same ones. Second, parameters
have two sets of names, which identify parameters according to location or
according to the purpose of the parameters.

Do not get flustered by this. Look at high school students and see how many
names are given to the same person. First, let's name according to class. Fine,
you are Sophomore, Junior or Senior. Second, let's name according to grades.
This makes you an A, B, or C student. (computer science students do not fail)
Third, let's name according to activities like band, tennis team, Mu Alpha Theta,
JETS, student council, etc. And, let's not forget to name according to first name
like Joe, Sue, Kathy, Tom, Mary, etc. The point here is that placing a label on a
person depends on the category of the label.

Naming Parameters According to Location

Parameters do a poor job hiding. You will find them in only two locations. A
parameter is either in a function call or a function heading. There is no other
place that a parameter can visit. We wish to label these two locations.
Parameters in a function call are actual parameters and parameters in a function
heading are formal parameters.

Naming Parameters According to Location

A parameter in a function call is named actual parameter.

Frequently, actual parameters are also called arguments.

A parameter in a function heading is named formal parameter.

Look at program PROG1405.CPP again. The program is incomplete. It is only


necessary to look at the main function with the function calls and the proto-types,
which are identical to the function headings. (do not sweat the semi-colons)

// PROG1405.CPP
// This program returns two altered parameters.
// It demonstrates a swap function.

#include <iostream.h>
#include <conio.h>

void Display(int A, int B);

Chapter XIV Parameter Functions II 14.18


void Swap(int &A, int &B);

void main()
{
int N1 = 5, N2 = 7;
clrscr();
Display(N1,N2);
Swap(N1,N2);
Display(N1,N2);
getch();
}

In this program, N1 and N2 are actual parameters. Both parameters are used in
function calls Display and Swap. A and B are formal parameters, located in the
functions headings. Technically, the formal parameters in Display and Swap are
in a totally different scope. It is customary to give them the same name, because
formal parameters A and B work with the same actual parameters N1 and N2.

Naming Parameters According to Purpose

Parameters exist for the purpose of passing information in a program. In that


department we have different parameters. A parameter may only pass
information in one direction. This is casually called a one-way parameter. More
precisely, such a parameter is called a value parameter because the function is
invoked call-by-value.

This chapter introduced the fancy parameters that can pass information in both
direction, which are casually called two-way parameters. The more precise
terminology is variable parameter, or even more precisely preferred, reference
parameter, because the function is invoked call-by-reference. The next section
will explain why the name reference parameter is very appropriate.

Naming Parameters According to purpose

A parameter that passes information in one direction is called


a one-way parameter, value parameter or call-by-value.

A parameter that passes information in two directions ( so it


appears) is called a two-way parameter, variable parameter,
reference parameter or call-by-reference.

Chapter XIV Parameter Functions II 14.19


If you look at program PROG1405.CPP, yet one more time, you will see a
different story. Parameters A and B in function heading Display are value
parameters. However, in function Swap parameters A and B each show a
conspicuous ampersand (&), indicating them to be variable or reference
parameters in this case.

// PROG1405.CPP
// This program returns two altered parameters.
// It demonstrates a swap function.

#include <iostream.h>
#include <conio.h>

void Display(int A, int B);


void Swap(int &A, int &B);

void main()
{
int N1 = 5, N2 = 7;
clrscr();
Display(N1,N2);
Swap(N1,N2);
Display(N1,N2);
getch();
}

Perhaps I can also explain why a formal parameter is called formal. In this case,
formal has nothing to do with formal in the tuxedo sense. Think of it as the form
of the parameter. Consider this: can you look at a function call and always
determine by those actual parameters if information is passed by value or by
reference? No, that is not possible in every case. If the actual parameter is a
constant, you can conclude that it must be a value parameter, but otherwise you
do not have a clue.
The parameters in a function heading are another story. Here the parameters
appear with or without the (&) operator. Without (&) means value parameter
and with (&) means variable parameter. In other words, you can determine the
form of the parameter in the function heading. Hence the term formal parameter.

Chapter XIV Parameter Functions II 14.20


14.5 Parameters, a Technical
Explanation

As a rule, precise, technical information tends to intimidate and scare away


students who are new to computer science. The combination of new terminology,
strange concepts, and complex ideas can be unnerving. There are also times when
the very preciseness of a technological explanation is exactly what helps to clarify
what is going on in a bewildering topic. Right now this is one of these moments.

First, you need to take a closer look at memory locations. Since the early chapters
you have been told that data is stored in memory. Different data occupies
different amounts of memory, but somewhere the data is stored. With C++ it is
possible to find the exact memory location where a variable stores its information.
It can be done with the reference operator. In this chapter the & has been used to
indicate that a parameter is a variable or reference parameter. You are about to
learn a more technical side to the humble reference (&) operator. We can stick an
& in front of any variable and display the memory of that variable.

Program PROG1408.CPP defines four variables: 2 integers and 2 floats. The


program first displays the values assigned to each variable, and then displays the
memory location of each variable.

// PROG1408.CPP
// This program demonstrates memory locations of
variables.

#include <iostream.h>
#include <conio.h>

void main()
{
int IntVar1 = 1000;
int IntVar2 = 2000;
float FloatVar1 = 3.14159;
float FloatVar2 = 1.23456;
clrscr();
cout << "IntVar1 is " << IntVar1 << endl;
cout << "IntVar2 is " << IntVar2 << endl;
cout << "FloatVar1 is " << FloatVar1 << endl;
cout << "FloatVar2 is " << FloatVar2 << endl;
cout << endl;

Chapter XIV Parameter Functions II 14.21


cout << "Address of IntVar1 is " << &IntVar1 <<
endl;
cout << "Address of IntVar2 is " << &IntVar2 <<
endl;
cout << "Address of FloatVar1 is " << &FloatVar1 <<
endl;
cout << "Address of FloatVar2 is " << &FloatVar2 <<
endl;
getch();
}

PROG1408.CPP OUTPUT

IntVar1 is 1000
IntVar2 is 2000
FloatVar1 is 3.14159
FloatVar2 is 1.23456

Address of IntVar1 is 0x8f420ffe


Address of IntVar2 is 0x8f420ffc
Address of FloatVar1 is 0x8f420ff8
Address of FloatVar2 is 0x8f420ff4

This first memory example program demonstrates two things. First, you do notice
the hexadecimal (base 16) memory addresses. It does prove that the reference
(&) operator can provide us with memory addresses.

Something else can be seen. C++ grabs adjacent memory locations, whenever
possible. Observe the memory locations. The output helps to show that float
occupies 4 bytes in memory and int reserves 2 bytes.

The numbering sequence may seem odd at first. Do keep in mind that memory is
allocated from a higher memory address down to lower addresses. Also keep in
mind that in base 16 the (base 10) values 10, 11, 12, 13, 14, 15 are represented
with a, b, c, d, e, and f. Frankly, for the purpose of this chapter, it matters little if
you know base 16 from mushroom pizza. The program examples in this section
display memory locations. Some memory addresses are the same number,
indicating that they occupy the same location. Other memory addresses have
different numbers, indicating that they are different locations.

The most important concept to understand in this section is how it is possible for
more than one identifier to store information in the same memory location. A
significant consequence of two variables occupying the same memory location is

Chapter XIV Parameter Functions II 14.22


that a change in the value of one variable simultaneously alters the value of the
other variable.
Perhaps you do not see any connection between parameter passing and memory
locations, and that is fine. Right now we need to establish the ability of the (&)
reference operator to display memory, as well as reference memory. The next
program will get down to the nitty-gritty of parameter passing.

Program PROG1409.CPP has an artificial function CheckMem. The function


performs no purpose besides displaying the memory of its parameters. In this
program we first display the memory locations of the main function variables.
These are the memory locations of the actual parameters Ref1 and Val1. They
have been named intentionally to represent reference and value parameters.

In function CheckMem there are corresponding Ref2 and Val2 parameters that
represent the local, formal parameters of the function. The memory locations of
those parameters will also be investigated.

Check the program source code and also check the output. Does the output make
sense? If it does great, if not read on and fine tune your brain.

// PROG1409.CPP
// This program demonstrates parameter memory
locations.

#include <iostream.h>
#include <conio.h>

void CheckMem(int &Ref2, int Val2);

void main()
{
int Ref1;
int Val1;
clrscr();
cout << "Address of Ref1 is " << &Ref1 << endl;
cout << "Address of Val1 is " << &Val1 << endl;
CheckMem(Ref1,Val1);
getch();
}

void CheckMem(int &Ref2, int Val2)

Chapter XIV Parameter Functions II 14.23


{
cout << endl << endl;
cout << "Address of Ref2 is " << &Ref2 << endl;
cout << "Address of Val2 is " << &Val2 << endl;
}

PROG1409.CPP OUTPUT

Address of Ref1 is 0x8f5a0ffe


Address of Val1 is 0x8f5a0ffc

Address of Ref2 is 0x8f5a0ffe


Address of Val2 is 0x8f5a0ffa

Variable Val1 has it own private memory location. The value stored at that
memory location is copied to the memory location of Val2. Once this copy is
made, all changes will be stored in a different memory location. The actual
parameter (in the function call) and the formal parameter (in the function
heading) each have their own memory location. Now notice that both Ref1 and
Ref2 have the exact same memory location. The value of Ref1 is not passed to
the function. A reference to the memory location of the actual parameter is
passed. This is a tremendously important difference with the call-by-value-
parameter-passing approach. The value of the actual (Ref1) parameter is not
copied in the function. It is not even passed to the function. The only thing that
the function gets is a reference to the memory location of the actual parameter.

Perhaps the name variable parameter made sense because the parameter can
change. Hopefully, this technical explanation shows that the name reference
parameter is not only appropriate, it is more descriptive than variable parameter.
From now on we shall use the name reference parameter.

The Secret of Two-Way Parameter Passing Unveiled

Now you can see how this all works. You have been fooled. There is no
information passed to a function, altered, and then passed back. The approach is
actually much simpler and very memory efficient. What do we want? We want
any changes in the formal parameter to cause a change in the actual parameter. If
the actual parameters are a list of unsorted numbers, then we want the formal
parameters in the function to bring about a nicely sorted list. Once the process is
accomplished we want the results back at the actual parameter site. Terrific, keep

Chapter XIV Parameter Functions II 14.24


it simple, and arrange for actual and formal parameters to camp out at the same
memory location. Now you start with some actual parameter value. This same
value is known to the formal parameter. Why? They are at the same location.
Great, we move on and do something to the formal parameter. The value of the
formal parameter changes in memory. But wait, the actual parameter is at the
same location and automatically gets changed also.

This is very slick and it might have slipped right passed you. You see, sometimes
it helps to be technical. It is normal to feel on shaky understanding ground at this
stage. No problem, read on and work with this stuff. I promise that suddenly
lights will become very bright.

Scope Revisited

Scope was explained in the last chapter. This scope business is not directly
related to the reference parameters discussed in this chapter. However, the
business at hand is to take a technical look at parameter passing. It will be helpful
to also get a better understanding of information that is stored in a program
without the use of parameters.

The program that follows was shown in the last chapter to explain the scope of
many X identifiers. Every identifier has the same name, X, but every identifier
has a different scope. We will return to this program, and this time not display the
value of each identifier, but the memory location of every X. The newly found
reference operator will accomplish this task, and you will note four different
memory locations for four X identifiers in four different scopes.

// PROG1410.CPP
// This program explains scope by looking at memory
locations.

#include <iostream.h>
#include <conio.h>

int X = 100;

void Function1();
void Function2();

void main()

Chapter XIV Parameter Functions II 14.25


{
clrscr();
cout << "Global X Memory = " << &X << endl;
int X = 200;
cout << endl;
cout << "Main Function X Memory = " << &X << endl;
Function1();
cout << endl;
cout << "Main Function X Memory = " << &X << endl;
Function2();
getch();
}

void Function1()
{
int X = 300;
cout << endl;
cout << "Function1 X Memory = " << &X << endl;
if (X == 300)
{
int X = 400;
cout << endl;
cout << "Very Local X Memory = " << &X <<
endl;
}
cout << endl;
cout << "Function1 X Memory = " << &X << endl;
}

void Function2()
{
cout << endl;
cout << "Global X Memory = " << &X << endl;
}

PROG1410.CPP OUTPUT

Global X Memory = 0x8ee00094


Main Function X Memory = 0x8f4f0ffe
Function1 X Memory = 0x8f4f0ff6
Very Local X Memory = 0x8f4f0ff4
Function1 X Memory = 0x8f4f0ff6
Main Function X Memory = 0x8f4f0ffe

Chapter XIV Parameter Functions II 14.26


Global X Memory = 0x8ee00094

14.6 Test Your Parameter Knowledge

This section has four quiz programs. Each program has a Guess function that
looks very similar to the Guess functions in the other programs. Be assured that
the functions are different and each program creates different output. It will be
very easy for you to type in the program, check the result, and then with great
bravado announce to the world the obvious answer. After all, anybody whose
brain generates enough energy for body life support systems can figure out
something so simple.
This approach may be lovely for ego stroking but it does not check if you know
what is happening. The answers to these programs are intentionally not shown.
For once, you are encouraged not to check the programs. This should be an
exercise in mental computing. Check each program out prior to the class where
these programs will be discussed. Figure the answer out by tracing through the
execution sequence. You are the computer. Your teacher will discuss the
answers of each program with you in class.

Do not get fooled by the simplicity of the programs. You need to understand
parameters very well to get the correct answers to all four programs. So look at
the programs carefully. Hopefully, these quiz programs will help to confirm or
perhaps clear up some lingering confusion.

// PROG1411.CPP
// Quiz 1

#include <iostream.h>
#include <conio.h>

void Guess1(int X, int Y)


{

Chapter XIV Parameter Functions II 14.27


X++;
cout << "X = " << X << endl;
Y++;
cout << "Y = " << Y << endl;
}

void main()
{
clrscr();
int Number1 = 10;
int Number2 = 20;
Guess1(Number1,Number2);
cout << "Number1 = " << Number1 << endl;
cout << "Number2 = " << Number2 << endl;
getch();
}

Do not get fooled. The first few program examples are quite straight forward and
hopefully every student will get the correct answer. The later quiz programs will
become more challenging. The majority of students tend not to get all quiz
programs correct. Be warned and be careful. It is trickier than it looks.

// PROG1412.CPP
// Quiz 2

#include <iostream.h>
#include <conio.h>

void Guess2(int X, int Y)


{
X++;
cout << "X = " << X << endl;
Y++;
cout << "Y = " << Y << endl;
}

void main()
{
clrscr();

Chapter XIV Parameter Functions II 14.28


int Number = 10;
Guess2(Number,Number);
cout << "Number = " << Number << endl;
getch();
}

// PROG1413.CPP
// Quiz 3

#include <iostream.h>
#include <conio.h>

void Guess3(int &X, int &Y)


{
X++;
cout << "X = " << X << endl;
Y++;
cout << "Y = " << Y << endl;
}

void main()
{
clrscr();
int Number1 = 10;
int Number2 = 20;
Guess3(Number1,Number2);
cout << "Number1 = " << Number1 << endl;
cout << "Number2 = " << Number2 << endl;
getch();
}

// PROG1414.CPP
// Quiz 4

#include <iostream.h>
#include <conio.h>

Chapter XIV Parameter Functions II 14.29


void Guess4(int &X, int &Y)
{
X++;
cout << "X = " << X << endl;
Y++;
cout << "Y = " << Y << endl;
}

void main()
{
clrscr();
int Number = 10;
Guess4(Number,Number);
cout << "Number = " << Number << endl;
getch();
}

14.7 Parameters Without Identifiers

The prototype of a function appears to be completely identical as the function


heading that follows later, with the exception of a semicolon. You will now see
that the difference can be greater. It is not necessary to use any identifier in a
function prototype.

At first this seems odd, but there is considerable logic to make sense of this
feature. The purpose of a prototype is to warn the compiler that an identifier is
going to be used of a certain function, and that the full details of that function will
come later. The prototype does provide the compiler with the necessary
parameter information. This parameter information is important because the
compiler will check if the actual and formal parameters match correctly.

This brings up an interesting point. The names of the actual and formal
parameters do not need to be the same. It is required that the function call and the
function heading contain the same number of parameters.

Chapter XIV Parameter Functions II 14.30


Furthermore, it is required that these parameters have identical data types. In
other words, the identifier of the formal parameters is not important at all in the
prototype and it is strictly optional.

Prototype Fact

The identifiers of the parameters in a prototype are optional.

Prototype
void GrossPay(int HW, double HR, double &GP);

can also be written as:


void GrossPay(int, double, double &);

This style is permitted, but it is not recommended. Using


identifiers will make your program more readable.

Program PROG1415.CPP is the earlier payroll program. This time the


prototypes have no parameter identifiers. Note that the actual function
implementations do use parameter identifiers. In this program the function
implementation only use stubs. This simplifies matters and does not distract from
the concept that is explained here.

// PROG1415.CPP
// This program demonstrates that prototypes do not
require
// parameter identifiers, only parameter data types and
// an ampersand if a reference parameter is used.
// Ignore all the warnings about not using variables.

#include <iostream.h>
#include <conio.h>
#include <iomanip.h>

void EnterData(int &, double &);


void CompGross(int, double, double &);
void CompDeduct(double, double &);

Chapter XIV Parameter Functions II 14.31


void CompNet(double, double, double &);
void DisplayData(int, double, double, double, double);

void main()
{
int HoursWorked; // hours worked per week
double HourlyRate; // payrate per hour
double GrossPay; // pay before deductions
double Deductions; // tax deductions
double NetPay; // total take-home pay

EnterData(HoursWorked,HourlyRate);
CompGross(HoursWorked,HourlyRate,GrossPay);
CompDeduct(GrossPay,Deductions);
CompNet(GrossPay,Deductions,NetPay);

DisplayData(HoursWorked,HourlyRate,GrossPay,Deductions,
NetPay);
getch();
}

void EnterData(int &HW, double &HR)


{
}

void CompGross(int HW, double HR, double &GP)


{
}

void CompDeduct(double GP, double &DD)


{
}

void CompNet(double GP, double DD, double &NP)


{
}

void DisplayData(int HW, double HR, double GP, double


DD,

Chapter XIV Parameter Functions II 14.32


double NP)
{
}

APCS Examination Alert

It is very likely that students will encounter function prototypes


without parameter identifiers on the case study and/or the
the AP Computer Science Examination.

The remainder of this book will include examples of function


prototypes that do not use parameter identifiers. This is done
for the sake of familiarization and exam preparation.

You are still recommended to write programs with matching


identifiers. It is quicker, and it is more readable.

You might wonder how it is possible that writing more is quicker. The reason has
to do with block copying. You write the prototypes, complete with identifiers,
block copy the whole lot, and paste them below the main function. Now you
remove the semicolons, adds some parenthesis, and you have a stub program that
compiles. This approach actual takes more time if you have to remove, or later
add, the parameter identifiers.

But then you knew that because I am sure you are a believer in block copying
what can be block copied. Just be careful. I have made some considerable
booboos in book writing and test writing by block copying. The efficiency of
block copying also makes duplication of mistakes more efficient.

Chapter XIV Parameter Functions II 14.33


14.8 Inline Functions

Program modularity was introduced many chapters ago, and you have no doubt
benefited from the use of functions. In the process of using functions it is
sometimes possible to create an “unwanted” inefficiency. Calling a function takes
more execution time than executing inline code. Now breaking a program into
logical segments and calling each one of these segment will not cause a penalty in
execution time that is even noticeable.
It is another story when the same function is called thousands or even millions of
times in a program. This situation can easily happen in nested loop structures,
where deep inside the inner loop, functions are called a large number of times.

C++ allows an interesting compromise. You can make a special bargain. I will
trade you some memory for execution time. C++ can create inline functions.
These functions place the actual function code in the place of the function call.
The result is that the execution time penalty does not happen. This is very
beneficial if you have few locations with a function call, but that function call is
repeated numerous times inside a loop. On the other hand, if you have the same
function call spread many, many times all over the program, you will then get a
penalty in memory usage from all the code that is copied. Inline functions
traditionally, are very small functions, and they are frequently written on one line
of code. Do not confuse a function written on one line with an inline function.
Program PROG1416.CPP has three functions that all occupy one line.

// PROG1416.CPP
// This program demonstrates small functions written on
one line.
// These are not "inline" functions.

#include <iostream.h>
#include <conio.h>

void Module1() { cout << "Module1" << endl; }


void Module2() { cout << "Module2" << endl; }
void Module3() { cout << "Module3" << endl; }

Chapter XIV Parameter Functions II 14.34


void main()
{
clrscr();
Module1();
Module2();
Module3();
getch();
}

PROG1416.CPP OUTPUT

Module1
Module2
Module3

The secret of inline functions is the reserved word inline that must precede the
function heading. Program PROG1417.CPP is almost identical to the previous
program. It does produce the same output, but this time genuine inline functions
are used.

// PROG1417.CPP
// This program demonstrates small functions written on
one line
// preceded by the inline reserved word.
// These are "inline" functions.

#include <iostream.h>
#include <conio.h>

inline void Module1() { cout << "Module1" << endl; }


inline void Module2() { cout << "Module2" << endl; }
inline void Module3() { cout << "Module3" << endl; }

void main()
{
clrscr();
Module1();

Chapter XIV Parameter Functions II 14.35


Module2();
Module3();
getch();
}

PROG1417.CPP OUTPUT

Module1
Module2
Module3

Industrial Strength C++

C++ includes many, many features. The language has evolved


to be an industrial strength programming language, which
allows professional programmers complete freedom in program
development. This freedom allows you to write some very
bizarre programs.

Inline functions are one example. This feature is meant to


be used for very short functions that are called very frequently.

Program PROG1418.CPP demonstrates correct syntax with inline functions that


use prototypes. Notice that the reserved word inline, only is used with the
prototype, not the function implementation. This program also demonstrates that
inline functions are not required to be one line.

This example demonstrates proper syntax, and simultaneously it shows precisely


when you should not be using inline functions. Each function is called only once
in this case. There is nothing useful gained in this situation to use inline
functions. In some later chapters I will present a variety of practical program
algorithms that call the same functions very frequently. For now, be happy with
the syntax.

// PROG1418.CPP
// This program demonstrates a variety of inline
functions.
// It also demonstrates that inline functions are not
based on
// one line but the inline reserved word.

Chapter XIV Parameter Functions II 14.36


#include <iostream.h>
#include <conio.h>

inline void EnterData(int &N1, int &N2);


inline int AddData(int N1, int N2);
inline void DisplayData(int N1, int N2, int Sum);

void main()
{
int Nbr1,Nbr2;
EnterData(Nbr1,Nbr2);
DisplayData(Nbr1,Nbr2,AddData(Nbr1,Nbr2));
}

void EnterData(int &N1, int &N2)


{
clrscr();
cout << "Enter two integers ===>> ";
cin >> N1 >> N2;
}

int AddData(int N1, int N2)


{
return N1 + N2;
}

void DisplayData(int N1, int N2, int Sum)


{
cout << endl << endl;
cout << N1 << " + " << N2 << " = " << Sum <<
endl;
getch();
}

PROG1418.CPP OUTPUT

Enter two integers ===>> 12 13

12 + 13 = 25

Chapter XIV Parameter Functions II 14.37


14.9 Overloaded Functions

This section title should look very suspicious. “Overloading” a function sounds
pretty strange. Is the function too large? Does the function process too much?
Does it require too much memory? These are logical questions, but they are
totally unrelated to the topic at hand. Even though we are not jumping into Object
Oriented Programming (OOP) yet, the topic of overloading is one of the
important elements in OOP.

Let us start by considering some function shortcomings. Imagine that you have
the need to swap data. Not just one type of data, but integers, characters and real
numbers. The knowledge that you have right now should lead you to a program
style similar to the one shown in program PROG1419.CPP. Three different
functions are created to swap three different types of data. Function Swap1
exchanges integers, function Swap2 exchanges characters, and function Swap3
takes care of real numbers.

// PROG1419.CPP
// This program swaps three different data types with
three
// different swap functions.

#include <iostream.h>
#include <conio.h>

void Swap1(int &, int &);


void Swap2(char &, char &);
void Swap3(double &, double &);

void main()

Chapter XIV Parameter Functions II 14.38


{
int IVar1 = 10, IVar2 = 20;
char CVar1 = 'A', CVar2 = 'Z';
double DVar1 = 1.111, DVar2 = 9.999;
clrscr();
cout << "Integers: " << IVar1 << "\t\t" << IVar2
<< endl;
cout << "Characters: " << CVar1 << "\t\t" << CVar2
<< endl;
cout << "Doubles: " << DVar1 << "\t" << DVar2 <<
endl;
Swap1(IVar1,IVar2);
Swap2(CVar1,CVar2);
Swap3(DVar1,DVar2);
cout << endl;
cout << "Integers: " << IVar1 << "\t\t" << IVar2
<< endl;
cout << "Characters: " << CVar1 << "\t\t" << CVar2
<< endl;
cout << "Doubles: " << DVar1 << "\t" << DVar2 <<
endl;
getch();
}

void Swap1(int &I1, int &I2)


{
int Temp;
Temp=I1; I1=I2; I2=Temp;
}

void Swap2(char &C1, char &C2)


{
char Temp;
Temp=C1; C1=C2; C2=Temp;
}

void Swap3(double &D1, double &D2)


{
double Temp;
Temp=D1; D1=D2; D2=Temp;
}

Chapter XIV Parameter Functions II 14.39


This style of programming works, and we can add more Swap functions as the
need arises. It will become tedious to keep track of the many different functions
that all perform the same action. There is an improvement in clarity by changing
the function names to SwapInt, SwapChar and SwapDouble, but all these
multiple names are quite tedious. Would it not be lovely if we could just call one
function - with the simple name Swap - and be done with the problem?

This capability exists in C++, and we can accomplish the desired - single name
identifier - by using overloading. So what is overloading? It has nothing to do
with loading really. Overloading enables you to use the same program features
for different purposes. This can apply to operators and it can apply to functions.
You have already used this business with operators, and you did not give it a
second thought. Consider the following two statements:

100 + 100 = 200 (arithmetic addition)

”100” + ”100” = ”100100” (string concatenation)

The same ( + ) operator is used for arithmetic addition and also for string
concatenation. Computer science people would say: “The + operator is
overloaded.”

Overloading

Overloading enables you to use the same program features for


different purposes.

In C++ operators and functions can be overloaded.

Understanding the basic overloading principle is a


prerequisite to learning Object Oriented Programming (OOP)

Overloading Example:

int X,Y;
apstring First,Last,Complete;
X = 100;
Y = 200;
Sum = X + y;

Chapter XIV Parameter Functions II 14.40


First = ”Kathy”;
Last = ”Denver”;
Complete = First + Last;

In this example the plus (+) operator is overloaded for


arithmetic addition and for string concatenation.

Program PROG1420.CPP uses three functions that exchange integers, characters


and real numbers. Each one of the functions has the same identifier Swap.

// PROG1420.CPP
// This program swaps three different data types with
three
// different swap functions that all have the same
name.

#include <iostream.h>
#include <conio.h>

void Swap(int &, int &);


void Swap(char &, char &);
void Swap(double &, double &);

void main()
{
int IVar1 = 10, IVar2 = 20;
char CVar1 = 'A', CVar2 = 'Z';
double DVar1 = 1.111, DVar2 = 9.999;
clrscr();
cout << "Integers: " << IVar1 << "\t\t" << IVar2
<< endl;
cout << "Characters: " << CVar1 << "\t\t" << CVar2
<< endl;
cout << "Doubles: " << DVar1 << "\t" << DVar2 <<
endl;
Swap(IVar1,IVar2);
Swap(CVar1,CVar2);
Swap(DVar1,DVar2);

Chapter XIV Parameter Functions II 14.41


cout << endl;
cout << "Integers: " << IVar1 << "\t\t" << IVar2
<< endl;
cout << "Characters: " << CVar1 << "\t\t" << CVar2
<< endl;
cout << "Doubles: " << DVar1 << "\t" << DVar2 <<
endl;
getch();
}

void Swap(int &I1, int &I2)


{
int Temp;
Temp=I1; I1=I2; I2=Temp;
}

void Swap(char &C1, char &C2)


{
char Temp;
Temp=C1; C1=C2; C2=Temp;
}

void Swap(double &D1, double &D2)


{
double Temp;
Temp=D1; D1=D2; D2=Temp;
}

PROG1420.CPP OUTPUT

10 20
A Z
1.111 9.999

20 10
Z A
9.999 1.111

It is quite possible that the overloaded function business leaves you wondering
about all the hype. It sounds good, but the bottom line is that you still have to
write as many swap functions as there are data types to exchange. This true, but it

Chapter XIV Parameter Functions II 14.42


certainly should be nice that no matter what gets swapped, the same Swap
identifier takes care of the job.

This gets us to the main point. How about duplicate identifier errors? It is easy to
convince yourself that this will not happen by running the program example. The
C++ compiler has no difficulty determining which function is called. The secret
is in parameter matching. Each Swap function has a different set of parameters
and choice of actual parameters in the function call determines where the program
execution continues.

The point of this overloaded-match-by-parameters will be illustrated with the next


program example. Program PROG1421.CPP does not accomplish anything. It
is a short program that displays three different messages. The program also is
kind of bizarre. Function Display seems to have a heading with a parameter - at
least a type for a parameter - but the function body does not use any parameters at
all. Is it very strange or does it makes sense to you?

The main function of the program will be shown first with the output. You will
note that the same function (at least same function identifier) is called three times
with three different actual parameter types. Three different messages result.

PROG1421.CPP MAIN FUNCTION AND OUTPUT

void main()
{
clrscr();
Display(1);
Display('A');
Display(1.1);
getch();
}

INTEGER DISPLAY

CHARACTER DISPLAY

DOUBLE DISPLAY

// PROG1421.CPP
// This program displays three different messages
depending

Chapter XIV Parameter Functions II 14.43


// on the parameters provided in the display function.

#include <iostream.h>
#include <conio.h>

void Display(int);
void Display(char);
void Display(double);

void main()
{
clrscr();
Display(1);
Display('A');
Display(1.1);
getch();
}

void Display(int)
{
cout << endl << endl;
cout << "INTEGER DISPLAY" << endl;
}

void Display(char)
{
cout << endl << endl;
cout << "CHARACTER DISPLAY" << endl;
}

void Display(double)
{
cout << endl << endl;
cout << "DOUBLE DISPLAY" << endl;
}

What you see here is an interesting different use of function parameters. In this
case, information is not passed to a function for any type of process. The only job
of the actual parameter is to help identify which Display function will be
executed next. The main reason for showing this program is to help understand
how overloaded functions can be properly selected.

Chapter XIV Parameter Functions II 14.44


A secondary reason is to show a parameter capability that will show up in a later
OOP chapter for a specific purpose. It will help in the future chapter if this
function ability already has been introduced, even if very briefly.

14.10 Function Parameter Rules

There have been two chapters of parameter functions and a very heavy chunk of
information has been thrown at you. It is time to summarize this parameter
function business with a variety of rules. These rules are numbered only for
reference. The rule numbers have no relationship to any rule numbers that exist
in the computer science community or in C++.

Function Parameter Rule #1

The number of actual and formal parameters must match.

Example:

void Rule1(int X, int Y, int Z)


{
}

Rule1(10,20,30);

Chapter XIV Parameter Functions II 14.45


Function Parameter Rule #2

The data types of the actual and formal parameters must


match according to their position in the function call and the
function heading.

Example:

void Rule2(int X, char Y, double Z)


{
}

Rule2(100,’A’,123.321);

Function Parameter Rule #3

Value parameters can use constants, expressions, or


variables for actual parameters.

Example:

void Rule3(int X, int Y, int Z)


{
}

int Number = 500;


Rule3(100,200+300,Number);

Chapter XIV Parameter Functions II 14.46


Function Parameter Rule #4

Variable parameters may only use variables for


actual parameters,

Example:

void Rule4(int &X, char &Y)


{
}

int Number = 500;


char Letter = ’Q’;
Rule4(Number,Letter);

Function Parameter Rule #5

The use of parameter identifiers is optional in function


prototypes.

void Rule5(int, char, double);

int Number = 500;


char Letter = ’Q’;
double Real = 123.321;
Rule5(Number,Letter,Real);

void Rule5(int N, char L, double R)


{
}

Note: You may also write function implementations without


parameters if the intention is to use overloaded functions with
different signatures, and the parameter is not used in the
function body.

Chapter XIV Parameter Functions II 14.47


Function Parameter Rule #6

The formal parameter in a function determines if the


information will be passed by value or by reference.
The use of an ampersand (&) next to the data type of
a formal parameter indicates a reference parameter.

void Rule6(int, char &, double &);

int Number = 500;


char Letter = ’S’;
double Real = 123.321;
Rule6(Number,Letter,Real);

void Rule6(int N, char &C, double &R)


{
}

Function Parameter Rule #7

The identifiers of actual parameters and their corresponding


formal parameters can be identical or different.

void Rule7(apstring Tom, apstring Sue);

apstring Tom, Sue;


apstring Kathy, George;
Rule7(Tom,Sue);
Rule7(Kathy, George);

Many people believe that actual and formal parameters


should intentionally use different names, even if it is
not required by the C++ compiler.

Chapter XIV Parameter Functions II 14.48


This summary of rules is very important to remember, and more important to
apply in practice. Any time my students asks for help on some logic problem, I
always check their parameters first. You will be surprised at the large number of
programs that are totally finished - at least the students thinks so - with multiple
parameter errors.

The Track Relay Analogy

Let us summarize this parameter business, with a real life analogy that may help
some students. The analogy that follows explains some of the parameter rules in
a totally different manner. Imagine that you are at a track meet and you watching
a relay race. In this relay race the starters run 100 meters and then pass a baton to
the next runner in their team.

In the first relay race example, the race official checks the track and announces
that the race is not ready. A look at Race1 shows there are four starters ready in
their lanes, but only three runners at the 100 meter baton passing mark. A runner
from the Netherlands (NL) is missing.

Race1
US US

GB GB

FR FR

NL

Race2 presents another situation with a different problem. This times the number
of runners is correct. There are four starters and there are also four runners at the
100 meter mark ready to receive a baton. However two runners at the 100 meter
mark are standing in the wrong lane. The track official announces that the race
cannot start unless the runners change lanes and are ready to receive the batons
from their own country men.

Race2

Chapter XIV Parameter Functions II 14.49


US US

GB GB

FR NL

NL FR

Race3 is not a problem situation. This race demonstrates an analogy to help


explain the naming of actual and formal parameters. In Race3, runner John starts
for the United States (US) and passes to William. George starts for Great Britain
(GB) and passes to Thomas. Gerard starts for France (FR) and passes to Louis.
Finally, Hans starts for the Netherlands and passes to another Hans.

Race3
US (John) US (William)

GB (George) GB (Thomas)

FR (Gerard) FR (Louis)

NL (Hans) NL (Hans)

The point of this analogy is that the names do not matter. What matters is that
there are the same number of runners at the passing mark as there are in the
starting blocks. It also matters that everybody stays in their lanes and that the
runners receiving batons are on the same team as the starters.

The batons are passed not based on the names of the runners, but
on the lanes they run in.

14.11 Worked-Out Exercises

Chapter XIV Parameter Functions II 14.50


Make the same assumptions as done with previous worked-out exercises. The
functions presented are part of a complete program. All necessary function
libraries are included in the program and all necessary variables are declared.
Each function starts with a correct function call from somewhere in a theoretical
program.

All the functions in this section are void functions. The concern with each
function is the resulting value of the parameter(s) in the function call. A function
with appropriate parameters is provided with each exercise.

In the trace table an & is placed in front of any reference parameter, and the
variable of the function call that references the same memory address is listed in
parenthesis.

Exercise 01
void Ex1401(int &N)
{
for (int K = 1; K < 5; K++)
if (N % 2 == 0)
N++;
else
N+=3;
}

int P = 4;
Ex1401(P);
P K N % 2 == 0 &N (P)
4 4
1 true 5
2 false 8
3 true 9
4 false 12
After Function P = 12
Call

Chapter XIV Parameter Functions II 14.51


Exercise 02
void Ex1402(int &X, int Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
int Q = 6;
Ex1402(P,Q);
P Q &X (P) Y
5 6 5 6
15 21
After Function P = 15 Q=6
Call

Exercise 03
void Ex1403(int X, int &Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
int Q = 6;
Ex1403(P,Q);
P Q X &Y (Q)
5 6 5 6
15 21
After Function P=5 Q = 21
Call

Chapter XIV Parameter Functions II 14.52


Exercise 04
void Ex1404(int &X, int &Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
int Q = 6;
Ex1404(P,Q);
P Q &X (P) &Y (Q)
5 6 5 6
15 21
After Function P = 15 Q = 21
Call

Exercise 05
void Ex1405(int &X, int Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
Ex1405(P,P);
P &X (P) Y
5 5 5
15 20
After Function P = 15
Call

Chapter XIV Parameter Functions II 14.53


Exercise 06
void Ex1406(int X, int &Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
Ex1406(P,P);
P X &Y (Q)
5 5 5
15 20
After Function P = 20
Call

Exercise 07
void Ex1407(int &X, int &Y)
{
X += 10;
cout << "X = " << X << endl;
Y += X;
cout << "Y = " << Y << endl;
}

int P = 5;
Ex1407(P,P);
P &X (Q) &Y (Q)
5 15 15
30 30
After Function P = 30

Chapter XIV Parameter Functions II 14.54


Call

Exercise 08
Consider the following function.

void Hello(int &A, int &B)


{
while (A != B && B >=0)
{
A++;
B--;
}
}

Assume that X and Y are integers. What is the output of the


following program segment?

X = 3;
Y = 6;
Hello(X,Y);
cout << X << " " << Y;

(A) 9 0
(B) 9 -1
(C) 10 0
(D) 10 -1
(E) There is no output. Function Hello never terminates.

X = 3;
Y = 6;
Hello(X,Y);
X Y &A (X) &B (Y)
3 6 3 6
4 5

Chapter XIV Parameter Functions II 14.55


5 4
6 3
7 2
8 1
9 0
10 -1
After Function X = 10 Y = -1
Call
Answers is (D)

Exercise 09
Consider the following function.

void Hello(int &A, int &B)


{
while (A != B && B >=0)
{
A++;
B--;
}
}

For which values of A and B will function Hello terminate?

(A) Function Hello will never terminate.


(B) For all integer values of A and B, such that A > B is true
(C) For all integer values of A and B, such that A <= B is true
(D) For all integer values of A and B, such that A <> B is true
(E) For all integer values of A and B

Answer is (E)

In the compound statement (A != B && B >= 0) the


first condition can be ignored. Strictly looking at B >= 0
combined with the logical and, the function will always
terminate.

If B < 0 the while loop starts out as false and the function
will terminate immediately.

Chapter XIV Parameter Functions II 14.56


If B >= 0 then the loop is entered and the statement B--
will guarantee that B eventually becomes negative.

APCS Examination Alert

There are a large selection of multiple choice questions that


involve computing the output or return value. You will also find
that some questions ask you to determine some general
property of a function, such as Exercise 09 above.

Frequently, such questions can be determined by trying a set of


test data so that a pattern can be observed. The pattern will
usually indicate the general case. Compare this question to the
previous exercise that used the same function.

Exercise 10
void Ex1410(int &X)
{
int Y;
while (X < 10)
{
Y = 1;
while (Y <= 10)
{
Y++;
X += 2;
}
X += Y;
}
}

int P = 5;
Ex1410(P);
P Y X (P)
5 5
1
2 7
3 9
4 11

Chapter XIV Parameter Functions II 14.57


5 13
6 15
7 17
8 19
9 21
10 23
11 25
36
After Function P = 36
Call

Chapter XIV Parameter Functions II 14.58

You might also like