1. Trang chủ
  2. » Công Nghệ Thông Tin

Absolute C++ (4th Edition) part 17 ppt

10 453 1

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 286,29 KB

Nội dung

162 Parameters and Overloading //of coins of denomination coinValue cents that can be obtained //from amountLeft cents. amountLeft has been decreased by the //value of the coins, that is, decreased by number*coinValue. You can check that the precondition holds for a function invocation, as shown by the following example: assert((0 < currentCoin) && (currentCoin < 100) && (0 <= currentAmountLeft) && (currentAmountLeft < 100)); computeCoin(currentCoin, number, currentAmountLeft); If the precondition is not satisfied, your program will end and an error message will be output. The assert macro is defined in the library cassert, so any program that uses the assert macro must contain the following: #include <cassert> One advantage of using assert is that you can turn assert invocations off. You can use assert invocations in your program to debug your program, and then turn them off so that users do not get error messages that they might not understand. Doing so reduces the overhead performed by your program. To turn off all the # define NDEBUG assertions in your program, add #define NDEBUG before the include directive, as follows: #define NDEBUG #include <cassert> Thus, if you insert #define NDEBUG in your program after it is fully debugged, all assert invocations in your program will be turned off. If you later change your pro- gram and need to debug it again, you can turn the assert invocations back on by deleting the #define NDEBUG line (or commenting it out). Not all comment assertions can easily be translated into C++ Boolean expressions. Preconditions are more likely to translate easily than postconditions are. Thus, the assert macro is not a cure-all for debugging your functions, but it can be very useful. ■ STUBS AND DRIVERS Each function should be designed, coded, and tested as a separate unit from the rest of the program. When you treat each function as a separate unit, you transform one big task into a series of smaller, more manageable tasks. But how do you test a function outside the program for which it is intended? One way is to write a special program to do the testing. For example, Display 4.9 shows a program to test the function unit- Price that was used in the program in Display 4.5. Programs like this one are called driver programs. These driver programs are temporary tools and can be quite mini- mal. They need not have fancy input routines. They need not perform all the calcula- tions the final program will perform. All they need do is obtain reasonable values for turning off assert #define NDEBUG driver program 04_CH04.fm Page 162 Wednesday, August 13, 2003 12:49 PM Testing and Debugging Functions 163 Display 4.9 Driver Program (part 1 of 2) 1 2 //Driver program for the function unitPrice. 3 #include <iostream> 4 using namespace std; 5 double unitPrice(int diameter, double price); 6 //Returns the price per square inch of a pizza. 7 //Precondition: The diameter parameter is the diameter of the pizza 8 //in inches. The price parameter is the price of the pizza. 9 int main( ) 10 { 11 double diameter, price; 12 char ans; 13 do 14 { 15 cout << "Enter diameter and price:\n"; 16 cin >> diameter >> price; 17 cout << "unit Price is $" 18 << unitPrice(diameter, price) << endl; 19 cout << "Test again? (y/n)"; 20 cin >> ans; 21 cout << endl; 22 } while (ans == ’y’ || ans == ’Y’); 23 return 0; 24 } 25 26 double unitPrice(int diameter, double price) 27 { 28 const double PI = 3.14159; 29 double radius, area; 30 radius = diameter/static_cast<double>(2); 31 area = PI * radius * radius; 32 return (price/area); 33 } 04_CH04.fm Page 163 Wednesday, August 13, 2003 12:49 PM 164 Parameters and Overloading the function arguments in as simple a way as possible—typically from the user—then execute the function and show the result. A loop, as in the program shown in Display 4.9, will allow you to retest the function on different arguments without having to rerun the program. If you test each function separately, you will find most of the mistakes in your pro- gram. Moreover, you will find out which functions contain the mistakes. If you were to test only the entire program, you would probably find out if there were a mistake, but you may have no idea where the mistake is. Even worse, you may think you know where the mistake is, but be wrong. Once you have fully tested a function, you can use it in the driver program for some other function. Each function should be tested in a program in which it is the only untested function. However, it’s fine to use a fully tested function when testing some other function. If a bug is found, you know the bug is in the untested function. It is sometimes impossible or inconvenient to test a function without using some other function that has not yet been written or has not yet been tested. In this case, you can use a simplified version of the missing or untested function. These simplified func- tions are called stubs. These stubs will not necessarily perform the correct calculation, but they will deliver values that suffice for testing, and they are simple enough that you can have confidence in their performance. For example, the following is a possible stub for the function unitPrice: //A stub. The final function definition must still be written. double unitPrice(int diameter, double price) { return (9.99);//Not correct but good enough for a stub. } Using a program outline with stubs allows you to test and then flesh out the basic program outline, rather than write a completely new program to test each function. For Display 4.9 Driver Program (part 2 of 2) S AMPLE D IALOGUE \ Enter diameter and price: 13 14.75 Unit price is: $0.111126 Test again? (y/n): y Enter diameter and price: 2 3.15 Unit price is: $1.00268 Test again? (y/n): n stub 04_CH04.fm Page 164 Wednesday, August 13, 2003 12:49 PM Chapter Summary 165 Self-Test Exercises this reason, a program outline with stubs is usually the most efficient method of test- ing. A common approach is to use driver programs to test some basic functions, such as input and output, and then use a program with stubs to test the remaining functions. The stubs are replaced by functions one at a time: One stub is replaced by a complete function and tested; once that function is fully tested, another stub is replaced by a full function definition, and so forth, until the final program is produced. 11. What is the fundamental rule for testing functions? Why is this a good way to test functions? 12. What is a driver program? 13. What is a stub? 14. Write a stub for the function whose declaration is given below. Do not write a whole pro- gram, only the stub that would go in a program. ( Hint: It will be very short.) double rainProb(double pressure, double humidity, double temp); //Precondition: pressure is the barometric pressure in inches of mercury, //humidity is the relative humidity as a percentage, and //temp is the temperature in degrees Fahrenheit. //Returns the probability of rain, which is a number between 0 and 1. //0 means no chance of rain. 1 means rain is 100% certain ) ■ A formal parameter is a kind of placeholder that is filled in with a function argu- ment when the function is called. In C++, there are two methods of performing this substitution, call by value and call by reference, and so there are two basic kinds of parameters: call-by-value parameters and call-by-reference parameters. ■ A call-by-value formal parameter is a local variable that is initialized to the value of its corresponding argument when the function is called. Occasionally, it is useful to use a formal call-by-value parameter as a local variable. ■ In the call-by-reference substitution mechanism, the argument should be a variable, and the entire variable is substituted for the corresponding argument. T HE F UNDAMENTAL R ULE FOR T ESTING F UNCTIONS Every function should be tested in a program in which every other function in that program has already been fully tested and debugged. Chapter Summary 04_CH04.fm Page 165 Wednesday, August 13, 2003 12:49 PM 166 Parameters and Overloading ■ The way to indicate a call-by-reference parameter in a function definition is to attach the ampersand sign, &, to the type of the formal parameter. (A call-by-value parameter is indicated by the absence of an ampersand.) ■ An argument corresponding to a call-by-value parameter cannot be changed by a function call. An argument corresponding to a call-by-reference parameter can be changed by a function call. If you want a function to change the value of a variable, then you must use a call-by-reference parameter. ■ You can give multiple definitions to the same function name, provided that the dif- ferent functions with the same name have different numbers of parameters or some parameter position with differing types, or both. This is called overloading the func- tion name. ■ You can specify a default argument for one or more call-by-value parameters in a function. Default arguments are always in the rightmost argument positions. ■ The assert macro can be used to help debug your program by checking whether or not assertions hold. ■ Every function should be tested in a program in which every other function in that program has already been fully tested and debugged. ANSWERS TO SELF-TEST EXERCISES 1. A call-by-value parameter is a local variable. When the function is invoked, the value of a call- by-value argument is computed and the corresponding call-by-value parameter (which is a local variable) is initialized to this value. 2. The function will work fine. That is the entire answer, but here is some additional informa- tion: The formal parameter inches is a call-by-value parameter and, as discussed in the text, is therefore a local variable. Thus, the value of the argument will not be changed. 3. 10 20 30 1 2 3 1 20 3 4. Enter two integers: 5 10 In reverse order the numbers are: 5 5 5. void zeroBoth(int& n1, int& n2) { n1 = 0; n2 = 0; } 04_CH04.fm Page 166 Wednesday, August 13, 2003 12:49 PM Answers to Self-Test Exercises 167 6. void addTax(double taxRate, double& cost) { cost = cost + (taxRate/100.0)*cost; } The division by 100 is to convert a percentage to a fraction. For example, 10% is 10/100.0, or one-tenth of the cost. 7. par1Value in function call = 111 par2Ref in function call = 222 n1 after function call = 1 n2 after function call = 2 8. The one with one parameter would be used because the function call has only one parameter. 9. The first one would be used because it is an exact match, namely, two parameters of type double. 10. This cannot be done (at least not in any nice way). The natural ways to represent a square and a round pizza are the same. Each is naturally represented as one number, which is the radius for a round pizza and the length of a side for a square pizza. In either case the func- tion unitPrice would need to have one formal parameter of type double for the price and one formal parameter of type int for the size (either radius or side). Thus, the two function declarations would have the same number and types of formal parameters. (Spe- cifically, they would both have one formal parameter of type double and one formal parameter of type int.) Thus, the compiler would not be able to decide which definition to use. You can still defeat this evil pizza parlor’s strategy by defining two functions, but they will need to have different names. 11. The fundamental rule for testing functions is that every function should be tested in a pro- gram in which every other function in that program has already been fully tested and debugged. This is a good way to test a function because if you follow this rule, then when you find a bug, you will know which function contains the bug. 12. A driver program is a program written for the sole purpose of testing a function. 13. A stub is a simplified version of a function that is used in place of the function so that other functions can be tested. 14. //THIS IS JUST A STUB. double rainProb(double pressure, double humidity, double temp) { return 0.25; //Not correct, //but good enough for some testing. } Different 04_CH04.fm Page 167 Wednesday, August 13, 2003 12:49 PM 168 Parameters and Overloading PROGRAMMING PROJECTS 1. Write a program that converts from 24-hour notation to 12-hour notation. For example, it should convert 14:25 to 2:25 P.M. The input is given as two integers. There should be at least three functions: one for input, one to do the conversion, and one for output. Record the A.M./P.M. information as a value of type char, ’A’ for A.M. and ’P’ for P.M. Thus, the function for doing the conversions will have a call-by-reference formal parameter of type char to record whether it is A.M. or P.M. (The function will have other parameters as well.) Include a loop that lets the user repeat this computation for new input values again and again until the user says he or she wants to end the program. 2. The area of an arbitrary triangle can be computed using the formula where a, b, and c are the lengths of the sides, and s is the semiperimeter. Write a void function that uses five parameters: three value parameters that provide the lengths of the edges, and two reference parameters that compute the area and perimeter (not the semiperimeter). Make your function robust. Note that not all combinations of a, b, and c produce a triangle. Your function should produce correct results for legal data and reasonable results for illegal combinations. 3. Write a program that tells what coins to give out for any amount of change from 1 cent to 99 cents. For example, if the amount is 86 cents, the output would be something like the following: 86 cents can be given as 3 quarter(s) 1 dime(s) and 1 penny(pennies) Use coin denominations of 25 cents (quarters), 10 cents (dimes), and 1 cent (pennies). Do not use nickel and half-dollar coins. Your program will use the following function (among others): void computeCoin(int coinValue, int& number, int& amountLeft); //Precondition: 0 < coinValue < 100; 0 <= amountLeft < 100. //Postcondition: number has been set equal to the maximum number //of coins of denomination coinValue cents that can be obtained //from amountLeft cents. amountLeft has been decreased by the //value of the coins, that is, decreased by number*coinValue. For example, suppose the value of the variable amountLeft is 86. Then, after the following call, the value of number will be 3 and the value of amountLeft will be 11 (because if you take three quarters from 86 cents, that leaves 11 cents): computeCoins(25, number, amountLeft); area s s a–()sb–()sc–()= sabc++()2⁄= 04_CH04.fm Page 168 Wednesday, August 13, 2003 12:49 PM Programming Projects 169 Include a loop that lets the user repeat this computation for new input values until the user says he or she wants to end the program. (Hint: Use integer division and the % operator to implement this function.) 4. Write a program that will read in a length in feet and inches and output the equivalent length in meters and centimeters. Use at least three functions: one for input, one or more for calculating, and one for output. Include a loop that lets the user repeat this computa- tion for new input values until the user says he or she wants to end the program. There are 0.3048 meters in a foot, 100 centimeters in a meter, and 12 inches in a foot. 5. Write a program like that of the previous exercise that converts from meters and centime- ters into feet and inches. Use functions for the subtasks. 6. (You should do the previous two programming projects before doing this one.) Write a program that combines the functions in the previous two programming projects. The pro- gram asks the user if he or she wants to convert from feet and inches to meters and centi- meters or from meters and centimeters to feet and inches. The program then performs the desired conversion. Have the user respond by typing the integer 1 for one type of conver- sion and 2 for the other conversion. The program reads the user’s answer and then executes an if-else statement. Each branch of the if-else statement will be a function call. The two functions called in the if-else statement will have function definitions that are very similar to the programs for the previous two programming projects. Thus, they will be fairly complicated function definitions that call other functions. Include a loop that lets the user repeat this computation for new input values until the user says he or she wants to end the program. 7. Write a program that will read in a weight in pounds and ounces and will output the equiv- alent weight in kilograms and grams. Use at least three functions: one for input, one or more for calculating, and one for output. Include a loop that lets the user repeat this com- putation for new input values until the user says he or she wants to end the program. There are 2.2046 pounds in a kilogram, 1000 grams in a kilogram, and 16 ounces in a pound. 8. Write a program like that of the previous exercise that converts from kilograms and grams into pounds and ounces. Use functions for the subtasks. 9. (You should do the previous two programming projects before doing this one.) Write a program that combines the functions of the previous two programming projects. The pro- gram asks the user if he or she wants to convert from pounds and ounces to kilograms and grams or from kilograms and grams to pounds and ounces. The program then performs the desired conversion. Have the user respond by typing the integer 1 for one type of conver- sion and 2 for the other. The program reads the user’s answer and then executes an if- else statement. Each branch of the if-else statement will be a function call. The two functions called in the if-else statement will have function definitions that are very simi- lar to the programs for the previous two programming projects. Thus, they will be fairly complicated function definitions that call other functions in their function bodies. Include a loop that lets the user repeat this computation for new input values until the user says he or she wants to end the program. 04_CH04.fm Page 169 Wednesday, August 13, 2003 12:49 PM 170 Parameters and Overloading 10. (You should do Programming Projects 6 and 9 before doing this programming project.) Write a program that combines the functions of Programming Projects 6 and 9. The pro- gram asks the user if he or she wants to convert lengths or weights. If the user chooses lengths, then the program asks the user if he or she wants to convert from feet and inches to meters and centimeters or from meters and centimeters to feet and inches. If the user chooses weights, a similar question about pounds, ounces, kilograms, and grams is asked. The program then performs the desired conversion. Have the user respond by typing the integer 1 for one type of conversion and 2 for the other. The program reads the user’s answer and then executes an if-else statement. Each branch of the if-else statement will be a function call. The two functions called in the if-else statement will have func- tion definitions that are very similar to the programs for Programming Projects 6 and 9. Thus, these functions will be fairly complicated function definitions that call other func- tions; however, they will be very easy to write by adapting the programs you wrote for Programming Projects 6 and 9. Notice that your program will have if-else statements embedded inside of if-else statements, but only in an indirect way. The outer if-else statement will include two function calls, as its two branches. These two function calls will each in turn include an if-else statement, but you need not think about that. They are just function calls and the details are in a black box that you create when you define these functions. If you try to create a four-way branch, you are probably on the wrong track. You should only need to think about two-way branches (even though the entire program does ultimately branch into four cases). Include a loop that lets the user repeat this computation for new input values until the user says he or she wants to end the program. 04_CH04.fm Page 170 Wednesday, August 13, 2003 12:49 PM For additional online Programming Projects, click the CodeMate icons below. 1.7 5 Arrays 5.1 INTRODUCTION TO ARRAYS 172 Declaring and Referencing Arrays 172 Tip: Use for Loops with Arrays 175 Pitfall: Array Indexes Always Start with Zero 175 Tip: Use a Defined Constant for the Size of an Array 175 Arrays in Memory 176 Pitfall: Array Index Out of Range 177 Initializing Arrays 178 5.2 ARRAYS IN FUNCTIONS 181 Indexed Variables as Function Arguments 181 Entire Arrays as Function Arguments 182 The const Parameter Modifier 185 Pitfall: Inconsistent Use of const Parameters 187 Functions That Return an Array 188 Example: Production Graph 188 5.3 PROGRAMMING WITH ARRAYS 194 Partially Filled Arrays 194 Tip: Do Not Skimp on Formal Parameters 194 Example: Searching an Array 197 Example: Sorting an Array 199 5.4 MULTIDIMENSIONAL ARRAYS 204 Multidimensional Array Basics 204 Multidimensional Array Parameters 205 Example: Two-Dimensional Grading Program 207 CHAPTER SUMMARY 211 ANSWERS TO SELF-TEST EXERCISES 212 PROGRAMMING PROJECTS 216 05_CH05.fm Page 171 Wednesday, August 13, 2003 12:51 PM . Referencing Arrays 172 Tip: Use for Loops with Arrays 175 Pitfall: Array Indexes Always Start with Zero 175 Tip: Use a Defined Constant for the Size of an Array 175 Arrays in Memory 176 Pitfall:. program. 04_CH04.fm Page 170 Wednesday, August 13, 2003 12:49 PM For additional online Programming Projects, click the CodeMate icons below. 1.7 5 Arrays 5.1 INTRODUCTION TO ARRAYS 172 Declaring. for the Size of an Array 175 Arrays in Memory 176 Pitfall: Array Index Out of Range 177 Initializing Arrays 178 5.2 ARRAYS IN FUNCTIONS 181 Indexed Variables as Function Arguments 181 Entire Arrays

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

TỪ KHÓA LIÊN QUAN

w