180 likes | 313 Views
Chapter 5. Functions For All Subtasks. Void functions. Do not return a value. Keyword void is used as the return type in the function prototype to show it returns nothing. Syntax: void Function_Name (Parameter_List) ;. When to use void functions. Output
E N D
Chapter 5 Functions For All Subtasks
Void functions • Do not return a value. • Keyword void is used as the return type in the function prototype to show it returns nothing. • Syntax: voidFunction_Name(Parameter_List);
When to use void functions • Output void show_results (double fDegree, double cDegree) { cout.setf(ios::fixed) cout.setf(ios::showpoint); cout.precision(1); cout <<fDegree<<“ degrees Fahrenheit is equivalent to \n” <<cDegree<<“ degrees Celcius.\n”; return; //optional } • instructions to user(which has no input variables) void instruct () { cout<< “This program computes the volume of a “ <<”right circular cone\n”; return; // This is optional } • when we want to change more than 1 variable (call-by reference)
return Statements in void Functions • Syntax: return; • Is optional • Usually used when need to break out of the function. void UnitPrice (double total, int units) { if (!units) // units == 0 return; cout << “The unit price is ” << total/units << endl; }
Call-by-Reference • When we want to make changes to variables in the caller program inside a function. • Call-by-value sends in a copy of a value stored. It cannot change the value of variable in the caller program. • If we need to make changes to more than 1 value. • A function can only return one value. • We need to be able to go to the memory location and change the value there for a permanent change.
Implementing Call-by-reference • To change the stored value, we need to pass in the address. • Use & to designate “the address of” • & is shown only in function prototype/definition, not in function call. • Must pass in variables so computer knows address and can change. Cannot pass in constants. • Formal Parameters : Placeholders in the function code. These are not declared and don’t represent any memory location. • Arguments: Used in the function call. An actual value or location in memory where a value is stored. This information is passed into the formal parameters in the function code and used in the function computations.
Call-by-reference Example #include <iostream> using namespace std; void swap (int&, int&); // Function prototype int main () { int x, y; // Declare two variables to hold integers cout << "Enter two integers .. seperated by a space: ";// User prompt cin >> x >> y; cout << "The initial values of two numbers: x=" << x << “, y=" << y << “.\n“; swap (x, y); // Function call cout << "The current values of two numbers: x=" << x << “, y=" << y << “.\n“; return 0; // This program requires a return integer value } void swap_values (int& first_num, int& second_num) // header { // body first_num = second_num; second_num = first_num; } 1000 x y first second ? 3 2000 ? 4 The initial values of two numbers: x=3, y=4 ? 1000 x=4, y=4 The current values of two numbers: ? 2000
Call-by-reference Example #include <iostream> using namespace std; void swap (int&, int&); // Function prototypes int main () { int x, y; // Declare two variables to hold integers cout << "Enter two integers .. seperated by a space: ";// User prompt cin >> x >> y; cout << "The initial values of two numbers: x=" << x << “ y=" << y << “.\n“; swap (x, y); // Function call cout << "The current values of two numbers: x=" << x << “ y=" << y << “.\n“; return 0; // This program requires a return integer value } void swap_values (int& first_num, int& second_num) // header { //body int temp = first_num ; first_num = second_num; second_num = temp; }
Mixed parameter lists • We can have both call-by-reference and call-by-value within a function. void SalaryCalculate(float rate, float& salary, int years); • You need to decide whether the function will be changing the data. If it is changing the data, the data MUST be call-by-reference.
Call-by-reference vs. Call-by-value • Call-by-value (IN) • variable information is to be used, not changed • variable is to be temporarily changed • Ex: double SalesTax (double price, double rate) ; • Call-by-reference (OUT) • Variable has no meaningful value goes in and valid value comes out. • Ex: void InputChoice (double& ans); • Call-by-reference (IN/OUT) • Variable has meaningful value but it is to be altered inside function. • Ex: void SalaryCalculate(float rate, float& salary, int years);
Pre and Post conditions • Precondition: What must be true of data before a function is called (requirements). Should be validated before the function is called to avoid erroneous results. • Postcondition: What is true of data after a function is called.
Pre and Post conditions (examples) double ConvertCoins (int number, double coinValue); // Pre-Cond: Get number of coins of 1 type and their value in dollar. // Post-Cond: The total amount of money converted to dollars and returned. int ConvertCoins (int number, int coinValue); // Pre-Cond: Get number of coins of 1 type and their value in cents. // Post-Cond: The total amount of money converted to cents and returned. voidConvertCoins (int number, double coinValue, double& total); // Pre-Cond: Get number of coins of 1 type and their value in dollar. // Post-Cond: The total amount of money converted to dollars. voidConvertCoins (int number, int coinValue, int& total); // Pre-Cond: Get number of coins of 1 type and their value in cents. // Post-Cond: The total amount of money converted to cents.
Testing and Debugging Functions • Create the Structure Chart with data flow to define function interfaces • Drivers: The caller functions calling other functions. • Stubs: Dummy functions. They usually consist of a message saying the function was called. They can return a constant value (if needed).
Structure Chart • Structure Chart represents the Driver program. • Each subtask is a function • Data flow tells what the parameters for the function should be • Data flow tells whether the parameters are passed by value or reference. Main PayOut salary salary PayOut salary salary Get Initial Salary Payment Calculation PayStub Display
Structure Chart • Structure Chart represents the Driver program. • Each subtask is a function • Data flow tells what the parameters for the function should be • Data flow tells whether the parameters are passed by value or reference. Main salary salary salary salary Get Initial Salary Payment Calculation PayStub Display PayOut
Stub Examples void main () // This is real code { double salary, pay; salary = GetSalary (); PaymentCalculate(salary, pay); } double GetSalary () // This is a stub { cout << “Inside GetSalary() \n”; return 1000.0; } void PaymentCalculate (double salary, double& payout) { // This is a stub cout << “Inside PaymentCalculate() \n”; payout = 750.0; PayStubDisplay(salary, payout); } void PayStubDisplay (double salary, double payout) { // This is a stub cout << “Inside PayStubDisplay() \n”; } Output: Inside GetSalary() Inside PaymentCalculate() Inside PayStubDisplay()
Driver Examples void main () // This is a driver { double pay; PaymentCalculate(500, pay); PaymentCalculate(1000, pay); PaymentCalculate(1500, pay); } void PaymentCalculate (double salary, double& payout) // This is real code { if (salary < 1000.0) payout = salary * 0.9; else if (salary >= 1000.0 && salary < 1500.0 ) payout = salary * 0.8; else payout = salary * 0.7; PayStubDisplay (salary, payout); } void PayStubDisplay (double salary, double payout) // This is a stub { cout << “Inside PayStubDisplay() with salary=$” << salary << “ and payout=$” << payout \n”; } Output: Inside PayStubDisplay() with salary=$500 and payout=$450.00 Inside PayStubDisplay() with salary=$1000 and payout=$800.00 Inside PayStubDisplay() with salary=$1500 and payout=$1050.00
General Debugging Techniques • Keep an Open Mind: Don’t assume code is correct/incorrect. • Change only code that you believe to be incorrect. Don’t randomly change things without cause • Show your program to another person to help you debug. Fresh mind has new looks to your program. • Check Common Errors: uninitialized variables Off-by-one-errors Exceed data boundary Automatic type conversion/Integer divide rather than double divide. Using = instead of == • Localize the error: Use cout statements or debugger to trace code behavior.