1 / 37

ACS 168 Structured Programming Using the Computer

ACS 168 Structured Programming Using the Computer. Chapter 4 by Joaquin Vila Prepared by Shirley White. Chapter 4 Functions for All Subtasks. In Chapter 3 we covered how to write functions that return one value. Here we see how to design functions that perform other kinds of subtasks.

sanaa
Download Presentation

ACS 168 Structured Programming Using the Computer

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ACS 168Structured Programming Using the Computer Chapter 4 by Joaquin Vila Prepared byShirley White

  2. Chapter 4 Functions for All Subtasks • In Chapter 3 we covered how to write functions that return one value. • Here we see how to design functions that perform other kinds of subtasks.

  3. 4.1 void-Functions • Void functions returnno values at all. • Such a function is called a void-function. The essential point is demonstrated here: void Print( double value) { using namespace std; cout << value << endl; } 3

  4. Definition of void-Functions • A C++ void-function is defined similarly to functions that return a value. • There are three differences between value returning functions and void-functions. • void type • There is no “returnexpression;” statement. • A call to a void-function is an executable statement, rather than being part of an expression. 4

  5. Code from Page 175 void show_results(double f_degrees, double c_degrees) { using namespace std; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(1); cout << f_degrees << “ degrees Fahrenheit is equavalent to\n” << c_degrees << “ degrees Celsius\n”; }

  6. Calling (invoking) the function “show_results”show_results(32.5, 0.3);32.5 degrees Fahrenheit is equivalent to0.3 degrees Celsius.

  7. Display 4.1 Syntax for a void-Function Definition //void-Function Prototype void Function_Name(Parameter_List); //void-Function Definition void Function_Name(Parameter_List)Function header { Declaration_1; You may intermix declarations Declaration_2; and executable statements. . . . Declaration_Last; Executable_1; Executables may or may not Executable_2; include one or more return; . . . statements. Executable_Last; }

  8. return-Statements in void-Functions • In C++ both void functions and value-returning functions can have return statements. • In value-returning functions the return is required and must have an argument. In void-functions, the return is optional and must NOT have an argument. • There is an implicit (compiler generated) return statement at the final closing brace of a void function. This does not mean you neverneed a return; in a void-function. 8

  9. Display 4.2 void-Function (1 of 4) //Program to convert a Fahrenheit temperature to a Celsius temperature. #include <iostream> void initialize_screen( ); //Separates current output from the output //of the previously run program. double celsius(double fahrenheit); //Converts a Fahrenheit temperature to a Celsius temperature. void show_results(double f_degrees, double c_degrees); //Displays output. Assumes that c_degrees //Celsius is equivalent to f_degrees Fahrenheit. int main( ) { using namespace std; double f_temperature, c_temperature; initialize_screen( );

  10. Display 4.2 void-Function (2 of 4) cout << "I will convert a Fahrenheit temperature" << " to Celsius.\n" << "Enter a temperature in Fahrenheit: "; cin >> f_temperature; c_temperature = celsius(f_temperature); show_results(f_temperature, c_temperature); return 0; }

  11. Display 4.2 void-Function (3 of 4) //Definition uses iostream: void initialize_screen( ) { using namespace std; cout << endl; return; This return is optional. } double celsius(double fahrenheit) { return ((5.0/9.0)*(fahrenheit - 32)); This return is required. }

  12. Display 4.2 void-Function (4 of 4) //Definition uses iostream: void show_results(double f_degrees, double c_degrees) { using namespace std; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(1); cout << f_degrees << " degrees Fahrenheit is equivalent to\n" << c_degrees << " degrees Celsius.\n"; return; // This return is optional. }

  13. 4.2 Call-by-Reference Parameters • Often we need to return multiple values and for that we need another mechanism … Call-by-Reference. • With a Call-by-Value parameter, the corresponding argument is only read for its value. The argument can be a variable, but this is not necessary. The parameter is initialized with the value of the value-parameter and changing it within the function does not effect the value in the calling function. • With Call-by-Reference, the corresponding argument must be a variable, and the behavior of the function is as if the variable were substituted for the parameter. This is like making a copy of the variable’s value and passing it to the function. The copy may be changed, but that does not effect the original value. This is like passing the actual variable to the function. When changes are made they effect the actual variable. 13

  14. A first view of Call-by-reference • To make a parameter a call-by-reference, parameter, an ampersand ( & ) is placed between the type name and the variable name in the function header and in the prototype that is used to declare this function. • a call-by-reference parameter Example: void Get_Input( double & f_variable) { using namespace std; cout << “Enter a Fahrenheit temp, I will return Celsius\n”; cin >> f_variable;} 14

  15. Display 4.4Call by Reference parameters (1 of 2) //Program to demonstrate call-by-reference parameters. #include <iostream> void get_numbers(int& input1, int& input2); //Reads two integers from the keyboard. void swap_values(int& variable1, int& variable2); //Interchanges the values of variable1 and variable2. void show_results(int output1, int output2); //Shows the values of variable1 and variable2, in that order. int main( ) { int first_num, second_num; get_numbers(first_num, second_num); swap_values(first_num, second_num); show_results(first_num, second_num); return 0; } The ampersands used here indicate these functions use call-by-reference This function is a call-by-value. Notice no ampersand appears in the calls.

  16. Call by Reference parameters(2 of 2) //Uses iostream: void get_numbers(int& input1, int& input2) { using namespace std; cout << "Enter two integers: "; cin >> input1 >> input2; } void swap_values(int& variable1, int& variable2) { int temp; temp = variable1; variable1 = variable2; variable2 = temp; } //Uses iostream: void show_results(int output1, int output2) { using namespace std; cout << "In reverse order the numbers are: " << output1 << " " << output2 << endl; } The ampersands were used in the prototypes AND the function headers.

  17. Call-by-Reference in Detail • A call-by-value parameter actually requires the value stored in the varialbe to be copied (taking up additional memory space) and transferred into the parameter. • Saying that a call-by-reference parameter has the argument variable copied into the parameter isn’t completely true. • The whole truth is – the address of the argument is used in place of the parameter, and the address is used to fetch values from the argument as well as to write to the argument. • This does not take additional memory space, but it does mean the function has direct access to the place where the variable value is stored. That is why changes are permanent. 17

  18. Parameters and Arguments (1 of 2) If you keep these points in mind, you can handle all the parameter passing language. 1. The formal parameters for a function are listed in the function prototype and function definition header. A formal parameter is a place holder that is filled at the time the function is called. 2. Arguments appear in a comma separated list in the call to the function, and are used to fill in the corresponding formal parameters. When the function is called, 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. 18

  19. Parameters and Arguments (2 of 2) • In the call-by-value method, the arguments are read, and the parameters are initialized using a copy of the value of the argument. • I can give you a copy of my book to write in, but my book remains unchanged no matter what you do. • In the call-by-reference method, the argument must be a variable. The behavior is exactly as if the argument were substituted for the parameter. Here if the function changes the parameter, the original argument is also changed. • If I give you my book, any changes you make are there when you return it to me. • The address of the argument is passed so the receiving function knows where the argument is stored. When the value is changed in the function, the argument’s actual storage location is where the writing is done. 19

  20. Mixed Parameter Lists It is entirely feasible to have value parameters (call-by-value parameter) mixed in with reference parameters (call-by-reference parameters). (We tend to use short cuts in the language.) Example: void good_stuff(int& par1, int par2, double & par3); Call: good_stuff( arg1, 17, arg3); Here 17 is permissible because par2 is a value parameter. This code may (but by no means must) change arg1 and arg3. 20

  21. PITFALL:Inadvertent Local Variables Omitting an ampersand (&) when you intend to use a reference parameter is a mistake that bites twice. First it makes your code run incorrectly but the compiler probably won’t catch it. Second the error is very difficult to find because it looks right. 21

  22. Display 4.7Inadvertent local variables //Inadvertent local variables. Shows what happens when you omit & //Program to demonstrate call-by-reference parameters. #include <iostream> void get_numbers(int& input1, int& input2); //Reads two integers from the keyboard. Forgot the & here void swap_values(int variable1, int variable2); //Interchanges the values of variable1 and variable2. void show_results(int output1, int output2); //Shows the values of variable1 and variable2, in that order. int main( ) { using namespace std; int first_num, second_num; get_numbers(first_num, second_num); swap_values(first_num, second_num); show_results(first_num, second_num); return 0; }

  23. Inadvertent local variables (2 of 2) void swap_values(int variable1, int variable2) { int temp; temp = variable1; Forgot the & here, which variable1 = variable2; Makes these inadvertent local variables variable2 = temp; } //Uses iostream: void get_numbers(int& input1, int& input2) { using namespace std; cout << "Enter two integers: "; cin >> input1 >> input2; } //Uses iostream: void show_results(int output1, int output2) { using namespace std; cout << "In reverse order the numbers are: " << output1 << " " << output2 << endl; }

  24. //Program to demonstrate a function calling another function. #include <iostream> void get_input(int& input1, int& input2); //Reads two integers from the keyboard. void swap_values(int& variable1, int& variable2); //Interchanges the values of variable1 and variable2. void order(int& n1, int& n2); //Orders the numbers in the variables n1 and n2 //so that after the function call n1 <= n2. void give_results(int output1, int output2); //Outputs the values in output1 and output2. //Assumes that output1 <= output2 int main( ) { int first_num, second_num; get_input(first_num, second_num); order(first_num, second_num); give_results(first_num, second_num); return 0; } Start in main Declare variables Call get_input() where the values for input1 and input2 are returned to first_num and second_num (in main) Call order() If n1 > n2 then call swap_values() which trades the order of the variables then returns to order(), which returns the values to main Call give_results() which prints the values in increasing order and returns to main Where the program ends. Display 4.8 Function Calling Another Function(1 of 2)

  25. //Uses iostream: void get_input(int& input1, int& input2) { using namespace std; cout << "Enter two integers: "; cin >> input1 >> input2; } void swap_values(int& variable1, int& variable2) { int temp; temp = variable1; variable1 = variable2; variable2 = temp; } void order(int& n1, int& n2) { if (n1 > n2) swap_values(n1, n2); } //Uses iostream: void give_results(int output1, int output2) { using namespace std; cout << "In increasing order " << "the numbers are: " << output1 << " " << output2 << endl; } Function Calling Another Function(2 of 2)

  26. Preconditions and Postconditions • The Prototype comment should be broken into a precondition and a postcondition. • The precondition is what is required to be true when the function is called. • The postcondition describes the effect of calling the function, including any returned value and any effect on reference parameters.

  27. Preconditions and Postconditions Example Pre - and Post-conditions. // square root function, sqrt // Prototype: double sqrt( double arg); // Pre: arg >= 0; // Post: returned value squared == arg If the Precondition is satisfied the function promises to put the Postcondition true. If the precondition is not satisfied, the function’s behavior is not constrained in any way.

  28. 4.4 Testing and Debugging Functions • Every function should be designed, coded and tested as a separate unit from the rest of the program. • Every new function should be tested in a program in which every other function in that program has already been completely tested and debugged. • Therefore you need a tested and working framework to develop and test your functions. • This is the essence of the top-down design strategy. • How do you test a function? By writing a simple, short program called a driver that calls the function. The driver should be simple enough that we can confirm its correctness by inspection.

  29. Stubs and Drivers • How do you test a program that needs a function, before you have written the function? • By writing a simple, short program called a stub that provides the the program with the same prototype, and provides enough data to the caller so the caller can be tested. • Again,the stub should be simple enough that we can confirm its correctness by inspection.

  30. Stubs and Drivers • First, write stubs for all the functions. • Then write the real functions, putting them into the program one at a time. • This way the complete program and already written code continues to be tested, while the new functions are written and tested until the final program is produced.

  31. Fundmental Rule for Testing Functions • Every function should be tested in a program in which every other function in that program has already been completely tested and debugged.

  32. Display 4.11Program that uses a Stub(part 1 of 4) //Determines the retail price of an item according to //the pricing policies of the Quick-Shop supermarket chain. #include <iostream> void introduction( ); //Postcondition: Description of program is written on the screen. void get_input(double& cost, int& turnover); //Precondition: User is ready to enter values correctly. //Postcondition: The value of cost has been set to the //wholesale cost of one item. The value of turnover has been //set to the expected number of days until the item is sold. double price(double cost, int turnover); //Precondition: cost is the wholesale cost of one item. //turnover is the expected number of days until sale of the item. //Returns the retail price of the item.

  33. Program that uses a Stub(part 2 of 4) void give_output(double cost, int turnover, double price); //Precondition: cost is the wholesale cost of one item; turnover is the //expected time until sale of the item; price is the retail price of the item. //Postcondition: The values of cost, turnover, and price have been //written to the screen. int main( ) { double wholesale_cost, retail_price; int shelf_time; introduction( ); get_input(wholesale_cost, shelf_time); retail_price = price(wholesale_cost, shelf_time); give_output(wholesale_cost, shelf_time, retail_price); return 0; }

  34. Program that uses a Stub(part 3 of 4) //Uses iostream: void introduction( ) { using namespace std; cout << "This program determines the retail price for\n" << "an item at a Quick-Shop supermarket store.\n"; } //Uses iostream: void get_input(double& cost, int& turnover) { using namespace std; cout << "Enter the wholesale cost of item $"; cin >> cost; cout << "Enter the expected number of days until sold: "; cin >> turnover; }

  35. Program that uses a Stub (part 4 of 4) //Uses iostream: void give_output(double cost, int turnover, double price) { using namespace std; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(2); cout << "Wholesale cost = $" << cost << endl << "Expected time until sold = " << turnover << " days" << endl << "Retail price= $" << price << endl; } //This is only a stub: double price(double cost, int turnover) { return 9.99; //Not correct, but good enough for some testing. }

  36. Summary (1 of 2) • All subtasks in a program can be implemented as functions, either as void-functions or value-returning functions. • A formal parameter is a kind of place holder that is filled with a function argument when the function is called. The two mechanisms for filling are call-by-value and call-by-reference. • In call-by-value, the value of the argument is copied into the parameter. With call-by-reference the argument must be a variable, and the effect is as if the variable had been substituted for the parameter. • The syntax to make a parameter call-by-reference is to insert an ampersand (&) between the type and the parameter in the function prototype and function header. • An argument corresponding to a call-by-value parameter will not be changed by the call. An argument corresponding to a call-by-reference parameter may be changed by the call, but this is not necessary. To make a function change an argument, the corresponding parameter must be call-by-reference.

  37. Summary (2 of 2) • Function prototype comments should be divided into Preconditions and Postconditions. The precondition describes the requirements that must be in effect when the function is called, and the postconditions describe the effect of the call, including any returned value and/or changed arguments. • Every function should be tested in a completely tested and debugged program. • A driver program is a short program that does nothing but test a function. • A stub is a simplified function used in place of a function definition that has not yet been tested (perhaps not written) so that the rest of the program can be tested.

More Related