Absolute C++ (4th Edition) part 15 pptx

10 384 1
Absolute C++ (4th Edition) part 15 pptx

Đang tải... (xem toàn văn)

Thông tin tài liệu

142 Parameters and Overloading As 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 function 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 call-by-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! 04_CH04.fm Page 142 Wednesday, August 13, 2003 12:49 PM Parameters 143 Self-Test Exercises Tip T HINK OF A CTIONS , N OT C ODE 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; } 04_CH04.fm Page 143 Wednesday, August 13, 2003 12:49 PM 144 Parameters and Overloading 4. 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 determined 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. P ARAMETERS AND A RGUMENTS 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. 04_CH04.fm Page 144 Wednesday, August 13, 2003 12:49 PM Parameters 145 Tip It 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. W HAT K IND OF P ARAMETER TO U SE Display 4.3 illustrates the differences between how the compiler treats call-by-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 04_CH04.fm Page 145 Wednesday, August 13, 2003 12:49 PM 146 Parameters and Overloading Pitfall I NADVERTENT L OCAL V ARIABLES 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 04_CH04.fm Page 146 Wednesday, August 13, 2003 12:49 PM Parameters 147 Example Tip 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. C HOOSING F ORMAL P ARAMETER N AMES 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. B UYING P IZZA 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. 04_CH04.fm Page 147 Wednesday, August 13, 2003 12:49 PM 148 Parameters and Overloading Display 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 } 25 The definitions of getNumbers and 26 showResults are the same as in Display 4.2. 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 04_CH04.fm Page 148 Wednesday, August 13, 2003 12:49 PM Parameters 149 Display 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 04_CH04.fm Page 149 Wednesday, August 13, 2003 12:49 PM 150 Parameters and Overloading Display 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! 04_CH04.fm Page 150 Wednesday, August 13, 2003 12:49 PM Overloading and Default Arguments 151 Self-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 04_CH04.fm Page 151 Wednesday, August 13, 2003 12:49 PM . function 04_CH04.fm Page 149 Wednesday, August 13, 2003 12:49 PM 150 Parameters and Overloading Display 4.5 Buying Pizza (part 2 of 2) 40 cout.setf(ios::fixed); 41 cout.setf(ios::showpoint); 42. small one is the better buy. Buon Appetito! 04_CH04.fm Page 150 Wednesday, August 13, 2003 12:49 PM Overloading and Default Arguments 151 Self-Test Exercises 7. What would be the output of the. 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

Ngày đăng: 04/07/2014, 05:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan