You might be tempted to think the function definition could be simplified to the following: To see that this alternative definition cannot work, consider what would happen with this defi
Trang 1As shown in Display 4.2, the definition of the function swapValues uses a local variable called
temp This local variable is needed You might be tempted to think the function definition could
be simplified to the following:
To see that this alternative definition cannot work, consider what would happen with this defini-tion and the funcdefini-tion call
swapValues(firstNum, secondNum);
The variables firstNum and secondNum would be substituted for the formal parameters
variable1 and variable2 so that with this incorrect function definition, the function call would be equivalent to the following:
firstNum = secondNum;
secondNum = firstNum;
This code does not produce the desired result The value of firstNum is set equal to the value of
secondNum, just as it should be But then, the value of secondNum is set equal to the changed value of firstNum, which is now the original value of secondNum Thus, the value of second-Num is not changed at all (If this is unclear, go through the steps with specific values for the vari-ables firstNum and secondNum.) What the function needs to do is save the original value of
firstNum so that value is not lost This is what the local variable temp in the correct function definition is used for That correct definition is the one in Display 4.2 When that correct version is used and the function is called with the arguments firstNum and secondNum, the function call
is equivalent to the following code, which works correctly:
temp = firstNum;
firstNum = secondNum;
secondNum = temp;
■ CONSTANT REFERENCE PARAMETERS
We place this subsection here for reference value If you are reading this book in order, you may as well skip this section The topic is explained in more detail later in the book.
If you place a const before a reference parameter’s type, you get a call-by-reference parameter that cannot be changed For the types we have seen so far, this has
no advantages However, it will turn out to be an aid to efficiency with array and class type parameters We will discuss these constant parameters when we discuss arrays and when we discuss classes.
void swapValues(int& variable1, int& variable2) {
variable1 = variable2;
variable2 = variable1;
}
This does not work!
Trang 2Self-Test Exercises
Tip
THINK OF ACTIONS, NOT CODE
Although we can explain how a function call works in terms of substituting code for the function call, that is not the way you should normally think about a function call You should instead think
of a function call as an action For example, consider the function swapValues in Display 4.2 and
an invocation such as
swapValues(firstNum, secondNum);
It is easier and clearer to think of this function call as the action of swapping the values of its two arguments It is much less clear to think of it as the code
temp = firstNum;
firstNum = secondNum;
secondNum = temp;
3 What is the output of the following program?
#include <iostream>
using namespace std;
void figureMeOut(int& x, int y, int& z);
int main( ) {
int a, b, c;
a = 10;
b = 20;
c = 30;
figureMeOut(a, b, c);
cout << a << " " << b << " " << c << endl;
return 0;
}
void figureMeOut(int& x, int y, int& z) {
cout << x << " " << y << " " << z << endl;
x = 1;
y = 2;
z = 3;
cout << x << " " << y << " " << z << endl;
}
Trang 34 What would be the output of the program in Display 4.2 if you omitted the ampersands (&) from the first parameter in the function declaration and function heading of swapVal-ues? The ampersand is not removed from the second parameter Assume the user enters numbers as in the sample dialogue in Display 4.2
5 Write a void function definition for a function called zeroBoth that has two call-by-reference parameters, both of which are variables of type int, and sets the values of both variables to 0
6 Write a void function definition for a function called addTax The function addTax has two formal parameters: taxRate, which is the amount of sales tax expressed as a percent-age; and cost, which is the cost of an item before tax The function changes the value of cost so that it includes sales tax
■ MIXED PARAMETER LISTS
Whether a formal parameter is a call-by-value parameter or a call-by-reference parame-ter is deparame-termined by whether there is an ampersand attached to its type specification If the ampersand is present, the formal parameter is a call-by-reference parameter If there
is no ampersand associated with the formal parameter, it is a call-by-value parameter.
PARAMETERS AND ARGUMENTS
All the different terms that have to do with parameters and arguments can be confusing How-ever, if you keep a few simple points in mind, you will be able to easily handle these terms
1 The formal parameters for a function are listed in the function declaration and are used in the body of the function definition A formal parameter (of any sort) is a kind of blank or place-holder that is filled in with something when the function is called
2 An argument is something that is used to fill in a formal parameter When you write down a function call, the arguments are listed in parentheses after the function name When the func-tion call is executed, the arguments are plugged in for the formal parameters
3 The terms call-by-value and call-by-reference refer to the mechanism that is used in the plugging-in process In the call-by-value method only the value of the argument is used In this call-by-value mechanism, the formal parameter is a local variable that is initialized to the value of the corresponding argument In the call-by-reference mechanism the argument is a variable and the entire variable is used In the call-by-reference mechanism the argument variable is substituted for the formal parameter so that any change that is made to the formal parameter is actually made to the argument variable
Trang 4It is perfectly legitimate to mix call-by-value and call-by-reference formal parameters
in the same function For example, the first and last of the formal parameters in the fol-lowing function declaration are call-by-reference formal parameters, and the middle one is a call-by-value parameter:
void goodStuff(int& par1, int par2, double& par3);
Call-by-reference parameters are not restricted to void functions You can also use them in functions that return a value Thus, a function with a call-by-reference param-eter could both change the value of a variable given as an argument and return a value
WHAT KIND OF PARAMETER TO USE
Display 4.3 illustrates the differences between how the compiler treats value and call-by-reference formal parameters The parameters par1Value and par2Ref are both assigned a value inside the body of the function definition Because they are different kinds of parameters, however, the effect is different in the two cases
par1Value is a call-by-value parameter, so it is a local variable When the function is called as follows,
doStuff(n1, n2);
the local variable par1Value is initialized to the value of n1 That is, the local variable
par1Value is initialized to 1 and the variable n1 is then ignored by the function As you can see from the sample dialogue, the formal parameter par1Value (which is a local variable) is set to
111 in the function body, and this value is output to the screen However, the value of the argu-ment n1 is not changed As shown in the sample dialogue, n1 has retained its value of 1
On the other hand, par2Ref is a call-by-reference parameter When the function is called, the variable argument n2 (not just its value) is substituted for the formal parameter par2Ref So when the following code is executed,
par2Ref = 222;
it is the same as if the following were executed:
n2 = 222;
Thus, the value of the variable n2 is changed when the function body is executed, so, as the dia-logue shows, the value of n2 is changed from 2 to 222 by the function call
If you keep in mind the lesson of Display 4.3, it is easy to decide which parameter mechanism to use If you want a function to change the value of a variable, then the corresponding formal parameter must be a call-by-reference formal parameter and must be marked with the amper-sand sign, & In all other cases, you can use a call-by-value formal parameter
mixing call-by-reference and call-by-value parameters
Trang 5Pitfall INADVERTENT LOCAL VARIABLES
If you want a function to change the value of a variable, the corresponding formal parameter must be a call-by-reference parameter and therefore must have the ampersand, &, attached to its type If you carelessly omit the ampersand, the function will have a call-by-value parameter where you meant to have a call-by-reference parameter When the program is run, you will
Display 4.3 Comparing Argument Mechanisms
1 //Illustrates the difference between a call-by-value
2 //parameter and a call-by-reference parameter
3 #include <iostream>
4 using namespace std;
5 void doStuff(int par1Value, int& par2Ref);
6 //par1Value is a call-by-value formal parameter and
7 //par2Ref is a call-by-reference formal parameter
8 int main( )
9 {
10 int n1, n2;
11
12 n1 = 1;
13 n2 = 2;
14 doStuff(n1, n2);
15 cout << "n1 after function call = " << n1 << endl;
16 cout << "n2 after function call = " << n2 << endl;
17 return 0;
18 }
19 void doStuff(int par1Value, int& par2Ref)
20 {
21 par1Value = 111;
22 cout << "par1Value in function call = "
23 << par1Value << endl;
24 par2Ref = 222;
25 cout << "par2Ref in function call = "
26 << par2Ref << endl;
27 }
S AMPLE D IALOGUE
par1Value in function call = 111
par2Ref in function call = 222
n1 after function call = 1
n2 after function call = 222
Trang 6Tip
discover that the function call does not change the value of the corresponding argument, because
a formal call-by-value parameter is a local variable If the parameter has its value changed in the function, then, as with any local variable, that change has no effect outside the function body This is an error that can be very difficult to see because the code looks right
For example, the program in Display 4.4 is similar to the program in Display 4.2 except that the ampersands were mistakenly omitted from the function swapValues As a result, the formal parameters variable1 and variable2 are local variables The argument variables firstNum
and secondNum are never substituted in for variable1 and variable2; variable1 and
variable2 are instead initialized to the values of firstNum and secondNum Then, the values of
variable1 and variable2 are interchanged, but the values of firstNum and secondNum are left unchanged The omission of two ampersands has made the program completely wrong, yet it looks almost identical to the correct program and will compile and run without any error messages
CHOOSING FORMAL PARAMETER NAMES
Functions should be self-contained modules that are designed separately from the rest of the pro-gram On large programming projects, different programmers may be assigned to write different functions The programmer should choose the most meaningful names he or she can find for formal parameters The arguments that will be substituted for the formal parameters may well be variables
in another function or in the main function These variables should also be given meaningful names, often chosen by someone other than the programmer who writes the function definition This makes
it likely that some or all arguments will have the same names as some of the formal parameters This
is perfectly acceptable No matter what names are chosen for the variables that will be used as argu-ments, these names will not produce any confusion with the names used for formal parameters
BUYING PIZZA
The large “economy” size of an item is not always a better buy than the smaller size This is partic-ularly true when buying pizzas Pizza sizes are given as the diameter of the pizza in inches How-ever, the quantity of pizza is determined by the area of the pizza, and the area is not proportional
to the diameter Most people cannot easily estimate the difference in area between a ten-inch pizza and a twelve-inch pizza and so cannot easily determine which size is the best buy—that is, which size has the lowest price per square inch Display 4.5 shows a program that a consumer can use to determine which of two sizes of pizza is the better buy
Note that the functions getData and giveResults have the same parameters, but since getData
will change the values of its arguments, its parameters are call-by-reference On the other hand,
giveResults only needs the values of its arguments, and so its parameters are call-by-value Also note that giveResults has two local variables and that its function body includes calls to the function unitPrice Finally, note that the function unitPrice has both local variables and
a locally defined constant
Trang 7Display 4.4 Inadvertent Local Variable
1 //Program to demonstrate call-by-reference parameters
2 #include <iostream>
3 using namespace std;
4 void getNumbers(int& input1, int& input2);
5 //Reads two integers from the keyboard
6 void swapValues(int variable1, int variable2);
7 //Interchanges the values of variable1 and variable2
8 void showResults(int output1, int output2);
9 //Shows the values of variable1 and variable2, in that order
10 int main( )
11 {
12 int firstNum, secondNum;
13 getNumbers(firstNum, secondNum);
14 swapValues(firstNum, secondNum);
15 showResults(firstNum, secondNum);
16 return 0;
17 }
18 void swapValues(int variable1, int variable2)
19 {
20 int temp;
21 temp = variable1;
22 variable1 = variable2;
23 variable2 = temp;
24 }
S AMPLE D IALOGUE
Enter two integers: 5 6
In reverse order the numbers are: 5 6
Forgot the & here
Forgot the & here
Inadvertent local variables
Error due to inadvertent local variables
Trang 8Display 4.5 Buying Pizza (part 1 of 2)
1 //Determines which of two pizza sizes is the best buy
2 #include <iostream>
3 using namespace std;
4 void getData(int& smallDiameter, double& priceSmall,
5 int& largeDiameter, double& priceLarge);
6 void giveResults(int smallDiameter, double priceSmall,
7 int largeDiameter, double priceLarge);
8 double unitPrice(int diameter, double price);
9 //Returns the price per square inch of a pizza
10 //Precondition: The diameter parameter is the diameter of the pizza
11 //in inches The price parameter is the price of the pizza
12 int main( )
13 {
14 int diameterSmall, diameterLarge;
15 double priceSmall, priceLarge;
16 getData(diameterSmall, priceSmall, diameterLarge, priceLarge);
17 giveResults(diameterSmall, priceSmall, diameterLarge, priceLarge);
18 return 0;
19 }
20 void getData(int& smallDiameter, double& priceSmall,
21 int& largeDiameter, double& priceLarge)
22 {
23 cout << "Welcome to the Pizza Consumers Union.\n";
24 cout << "Enter diameter of a small pizza (in inches): ";
25 cin >> smallDiameter;
26 cout << "Enter the price of a small pizza: $";
27 cin >> priceSmall;
28 cout << "Enter diameter of a large pizza (in inches): ";
29 cin >> largeDiameter;
30 cout << "Enter the price of a large pizza: $";
31 cin >> priceLarge;
32 }
33
34 void giveResults(int smallDiameter, double priceSmall,
35 int largeDiameter, double priceLarge)
36 {
37 double unitPriceSmall, unitPriceLarge;
38 unitPriceSmall = unitPrice(smallDiameter, priceSmall);
39 unitPriceLarge = unitPrice(largeDiameter, priceLarge);
The variables diameterSmall, diameterLarge, priceSmall, and priceLarge are used to carry data from the function getData to the function giveResults
One function called within another function
Trang 9Display 4.5 Buying Pizza (part 2 of 2)
40 cout.setf(ios::fixed);
41 cout.setf(ios::showpoint);
42 cout.precision(2);
43 cout << "Small pizza:\n"
44 << "Diameter = " << smallDiameter << " inches\n"
45 << "Price = $" << priceSmall
46 << " Per square inch = $" << unitPriceSmall << endl
47 << "Large pizza:\n"
48 << "Diameter = " << largeDiameter << " inches\n"
49 << "Price = $" << priceLarge
50 << " Per square inch = $" << unitPriceLarge << endl;
51 if (unitPriceLarge < unitPriceSmall)
52 cout << "The large one is the better buy.\n";
53 else
54 cout << "The small one is the better buy.\n";
55 cout << "Buon Appetito!\n";
56 }
57 double unitPrice(int diameter, double price)
58 {
59 const double PI = 3.14159;
60 double radius, area;
61 radius = diameter/static_cast<double>(2);
62 area = PI * radius * radius;
63 return (price/area);
64 }
S AMPLE D IALOGUE
Welcome to the Pizza Consumers Union
Enter diameter of a small pizza (in inches): 10
Enter the price of a small pizza: $7.50
Enter diameter of a large pizza (in inches): 13
Enter the price of a large pizza: $14.75
Small pizza:
Diameter = 10 inches
Price = $7.50 Per square inch = $0.10
Large pizza:
Diameter = 13 inches
Price = $14.75 Per square inch = $0.11
The small one is the better buy
Buon Appetito!
Trang 10Self-Test Exercises
7 What would be the output of the program in Display 4.3 if you changed the function dec-laration for the function doStuff to the following and you changed the function header to match, so that the formal parameter par2Ref were changed to a call-by-value parameter?
void doStuff(int par1Value, int par2Ref);
Overloading and Default Arguments
“ and that shows that there are three hundred and sixty-four days when you might get un-birthday presents—”
“Certainly,” said Alice.
“And only one for birthday presents, you know There’s glory for you!”
“I don’t know what you mean by ‘glory,’ ” Alice said.
Humpty Dumpty smiled contemptuously, “Of course you don’t—till I tell you I mean ‘there’s a nice knock-down argument for you!’ ”
“But ‘glory’ doesn’t mean ‘a nice knock-down argument,’ ” Alice objected.
“When I use a word,” Humpty Dumpty said, in rather a scornful tone, “it means just what I choose it to mean—neither more nor less.”
“The question is,” said Alice, “whether you can make words mean so many different things.”
“The question is,” said Humpty Dumpty, “which is to be master—that’s all.”
Lewis Carroll, Through the Looking-Glass
C++ allows you to give two or more different definitions to the same function name, which means you can reuse names that have strong intuitive appeal across a variety of situations For example, you could have three functions called max: one that computes the largest of two numbers, another that computes the largest of three numbers, and yet another that computes the largest of four numbers Giving two (or more) function
definitions for the same function name is called overloading the function name
■ INTRODUCTION TO OVERLOADING
Suppose you are writing a program that requires you to compute the average of two numbers You might use the following function definition:
double ave(double n1, double n2) {
return ((n1 + n2)/2.0);
}
4.2
overloading