Chapter Functions for All Subtasks CISC 1600 Spring
Chapter Functions for All Subtasks CISC 1600 Spring 2013 X. Zhang
Slide 1 - 2 Review Function: a packaged segment of code (i. e. , has a name) that implement well-defined functionality To calculate square root of a double value, named sqrt To read from keyboard the number of items to order, named Get. Item. Num Blackbox analogy: a function takes some input and produces some output Input: the value to calculate square root of, the item’s name Output: the result of calculation, or user’s input (as in Get. Item. Num) Input provided as parameters, output as return value …
Slide 1 - 3 Review Function declaration, function definition, function call Syntax, formal parameters, actual arguments Function must be declared before being called int Get. Item. Number (string item. Name); function declaration int main( ) actual arguments { Get. Item. Number (“ 14 -inch pizza”); function call } int Get. Item. Number (string item. Name) { formal parameters int value; cout <<“Enter the number of item “ << item. Name <<“: ”; cin >> value; return value; } function definition
Slide 1 - 4 Review: variable scopes Variable scope: each variable has a scope, i. e. , part of the program where it can be accessed Block scope rule: each variable’s scope is from the point where it is declared to the end of block where it is declared Local variable: declared within a block statement (function body, or block statement in if-statement, loop statement) Formal parameters are local variables When a function returns, its local variables go out of scope (no more accessible, we cross out its variable tables when tracing) Global variable: declared outside of functions
Slide 1 - 5 Variable scopes Variables with same name, but different scopes are allowed Different functions can have their own variables named value, i, j, Nested block => Shadow (eclipse): A global variable and a local variable with same name: inside the function, the global variable is shadowed (eclipsed), i. e. , not accessible Two nested block statements: what is scope of two value variables? int func 1 (int a) { int value=0; for (int i=0; i< a; i++) { int value = value+a; }
Slide 1 - 6 Review: function call You can call a function from main, from any function (including the function itself, i. e. , recursive function) value = sqrt (9. 0)+12. 0; pizza_12 = Get. Item. Number (“ 12 -inch pizza”); Get. Item. Number (“ 14 -inch pizza”); // legal, but without effects Note: if you declare and define a function, but do not call the function from main(), the function will not be executed Parameter passing (pass-by-value): the values of arguments are assigned to parameters based on order Normally, arguments can be expressions, variables, or constants Type of arguments should match with corresponding parameters (recall they will be assigned to the parameters) Return from function: When reach return statement, or end of function body Go back to caller function, to the statement where function is called
Slide 5 - 7 Overview void Functions Call-By-Reference Parameters Using Procedural Abstraction Testing and Debugging General Debugging Techniques
Slide 5 - 8 void-Functions Recall blackbox analogy Function input as parameters Function output as return value A subtask/function might produce No value, e. g. , a function that clears screen, or prints receipt One value More than one value: e. g. , a function that reads/checks date We have seen how to implement functions that return one value A void-function implements a subtask that returns no value Pass-by-reference allow a function to “produces” more than
Slide 5 - 9 void-Function Definition void-function definitions Keyword void replaces the type of the value returned void means that no value is returned return statement does not include an expression Optional return statement ends the function Return statement is implicit if it is not included Example: void show_results (double f_degrees, double c_degrees) { using namespace std; cout << f_degrees << “ degrees Fahrenheit is euivalent to “ << endl << c_degrees << “ degrees Celsius. ” << endl; return; }
Slide 5 - 10
Slide 5 - 11 Using a void-Function void-function calls are executable statements They do not need to be (and cannot be) part of another statement They end with a semi-colon Example: show_results(32. 5, 0. 3); NOT: cout << show_results(32. 5, 0. 3);
Slide 5 - 12 void-Function Calls Mechanism is nearly the same as the function calls we have seen Argument values are assigned to formal parameters, based on order It is fairly common to have no parameters in void-functions Statements in function body are executed Function ends when reaching return statement, or end of function block ( ending })
Slide 1 - 13 Void function example: breakpoint() Last Friday: adding cout statements at critical place in codes If you want to pause program’s execution, and continue after you have examined outputs generated so far int main() { … cout <<“Before calling function func 1, a=“ << a << endl; break_point(); func 1 (a); cout <<“After calling function func 1, a=“ << a << endl; } void break_point() { char c; cout <<"Press c to continue: "; cin >> c;
Slide 5 - 14 Example: Converting Temperatures main function is defined to return a value of type int Where, or to whom is the value returned to ? Exit status of program/command: indicate success or failure
Slide 5 - 15
Slide 5 - 16 Can you modify the code so that it does not use return ?
Slide 5 - 17 Overview void Functions Call-By-Reference Parameters Using Procedural Abstraction Testing and Debugging General Debugging Techniques
Slide 5 - 18 Call-by-Reference Parameters Try write function declaration for a function that reads a date from keyboard Need to “return” three integer values Call-by-value parameters cannot be used to “return” results formal parameters receive values of arguments at function call When we change values of formal parameters in a function body, arguments variables used in the function call is not changed Call-by-reference parameters allow us to change variable used in the function call Add a & between parameter type and name
Slide 5 - 19 Call-By-Reference Details Call-by-reference works almost as if the argument variable is substituted for the formal parameter, not the argument’s value In reality, memory location of argument variable is assigned to formal parameter Whatever is done to a formal parameter in function body, is actually done to argument variable Textbook: assign memory location for argument variable Handout on tracing function call Draw an arc from formal parameter to argument variable to reflect pass-by-reference
Slide 5 - 20 Call-by-Reference Example void get_input(double& f_variable) { using namespace std; cout << “ Convert a Fahrenheit temperature” << “ to Celsius. n” << “ Enter a temperature in Fahrenheit: “; cin >> f_variable; } At function call: get_input (a); // call get_input, using variable a as f_variable // user input will be saved to a get_input (b); // call get_input, using variable b as f_variable // user input will be saved to b
Slide 5 - 21 Pass-by-value parameter double convert(double f_variable) { f_variable = … //modify local variable f_variable } At function call: convert (a); // call convert, passing a’s value to f_variable convert(10. 0+b); // call convert, passing 10. 0+b’s value to f_variable
Slide 5 - 22 Choosing Parameter Types Call-by-value and call-by-reference parameters can be mixed in same function Use reference parameter only when necessary Does the function need to change the value of the variable used as an argument? Yes? Use a call-by-reference formal parameter No? Use a call-by-value formal parameter
Slide 1 - 23 Example int Days. Passed. Calc (int &day, int &month, int &year, int &total_days) { total_days = day; for ( ; month>0; month--) total_days += Days. In. Month (year, month); return total_days; }
Slide 5 - 24 Overview void Functions Call-By-Reference Parameters Function Design Rules of thumb Using Procedural Abstraction Testing and Debugging
Slide 1 - 25 Function Design: to function or not? Introduce functions, When your main() function becomes too long => introduce function to increase readability, ease to maintain E. g. , lab 7, cashier program When you are repeating codes => introduce function to reuse code When your code is likely to be useful for others E. g. , Leap. Year( ), Days. Since. Jan 1( ) When you feel overwhelmed by a task => devide and conquer, solve the task by solving smaller, more manageable subtasks
Slide 1 - 26 Function Design How to decide what should be in a function? Well-defined, self-contained functionalities Try to be as general as possible Instead of cout the result of calculation, return the results => allow the calculation results to be used to many different ways int Days. Since. Jan 1 (int m, int) is more useful than void Print. Days. Since. Jan 1 (int m, int d, int y); Typically, leave it to main() to display/report results
Slide 5 - 27 Function Design: black box Functions should be designed so they can be used as black boxes Knowing declaration and comment should be sufficient, should not need to know details of function definition C/C++ standard library functions online resource, e. g. , C++ reference at http: //en. cppreference. com/w/ use command man to look up, e. g. , man sqrt #include <math. h> double sqrt(double x); float sqrtf(float x); long double sqrtl(long double x);
Slide 5 - 28 Function Comment: Pre and Postconditions Precondition: states function is called what is assumed to be true when Function should not be used unless the precondition holds E. g. , sqrt ( ) should not be called with negative value Postcondition: describes effect of function call, what will be true after function is executed (when precondition holds) If function returns a value, that value is described Changes to call-by-reference parameters are described E. g. , sqrt () returns the square root of the parameter’s value
Slide 5 - 29 Why use preconditions and postconditions? Preconditions and postconditions should be first step in designing a function specify what a function should do Always specify what a function should do before designing how the function will do it Minimize design errors Minimize time wasted writing code that doesn’t match task at hand
Slide 5 - 30 swap_values revisited void swap_values(int& n 1, int& n 2); //Precondition: variable 1 and variable 2 have // been given values // Postcondition: The values of variable 1 and // variable 2 have been // interchanged
Slide 5 - 31 Exercises Can you write preconditions and postconditions for a function that calculate factorial ?
Slide 5 - 32 Overview void Functions Call-By-Reference Parameters Function Design Rules of thumb Using Procedural Abstraction Problem Solving, Testing and Debugging
Problem Solving (1) How to go about solve the problem? Programming or software development involves much more than writing code Multiple iterative steps 1. Understand the problem What is the required behavior of the program/software ? What input does it take? What output it generates? Clarify with the user/customer/teacher … 33
Problem Solving: find a solution 1. Understand the problem 2. Find a solution: algorithmic part It helps to use sample inputs and reflect how you (a human being) solve the problem ? Don’t take it for granted, try to be as specific as you can --- what’s the thinking process in your mind? e. g. , test prime number e. g. , test valid date e. g. , print a number, say 234. 56, as “two hundred thirty four and 56/100” What’s going on ? 34
Problem Solving: Design 1. Understand the problem 2. Find a solution 3. Design a solution: how to structure your program, what are the key variables (data structures) to use, in order to implement your solution Outcome: pseudocode or code skeleton that captures important structure/control flow, and function headers and comments Approach: Divide and Conquer, i. e. , break down into manageable pieces Refine/Modify solutions by walking through pseudocode 35 4. Implementation and Testing
Implementation, i. e. , coding Top-down approach: implement main( ) or upper- level function first, Bottom-up approach: implement lower-level functions, i. e. , those being called by others, first To identify possible design problems, we should test complicated or critical modules (functions) first Code a little, test a little You always have a code that runs! 36 main Read. Date Days. Passed Is. Valid. Date Days. Passed. Since Year. Start
Test while code A function might call other functions that haven’t been implemented yet Solutions: temporarily replace the body of those function a stub, i. e. , returns a simple value that is sufficient for testing another function bool Is. Leap. Year (int year) { //todo: refer to … return false; } display info to help you see order of execution, parameters passed E. g. , cout <<“ Function Days. In. Month called with parameters …” ; 37
Slide 5 - 38 Test while code: 2 Each function should be tested as a separate unit Testing individual functions facilitates finding mistakes Test cases: input used to test the program or function Test boundary conditions, where program is expected to change behavior or make a choice e. g. , for testing valid date, we need to consider various cases to make sure our code is complete… Driver programs allow testing of individual functions
Slide 5 - 39 Drive program example … int main( ) { if (Is. Leap. Year (2000)) cout <<“ 2000 is leap year”; else cout <<“ 2000 is not leap year”; //should test more cases 1100 (non-leap year), 1945 (non-leap year)… cout <<“Days. Since. Jan 1 (1, 13, 2000)=“ << Days. Since. Jan 1 (1, 13, 2000) << endl; //should also test Feb, March (leap year and non-leap year)… }
Problem Solving: test 1. 2. 3. 4. 5. Understand the problem Design a solution Refine/Modify design Implement designed solution Test and debug: make sure program satisfy requirement Run program with various inputs and see if it always work 40
Problem Solving approach Multiple Iterative Steps Understand the problem Design a solution Refine/Modify design Implement designed solution Test and debug Reality: One might interleave these steps Code while design, test while code Start with main, write comments as design Test a key function first, or a critical part first One might need to go back to modify design: During/after coding, while testing It’s expensive to make big changes in design at later stage… 41
Guideline For small and individual project, no need to document design But have a design in your mind is important Use comments to document your design At least for non-trivial function A reminder for yourself Top-down approach combined with bottom-up approach During coding: know what you are doing Do not copy code that you don’t understand Delete (comment out) code and variables no more used. Remove mental clutter ! Code a little, test a little 42
Slide 5 - 43 General Debugging Techniques Keep an open mind Don’t assume bugs are in a particular location Don’t randomly change code until program works, without understanding what you are doing This strategy may work for small programs you write but is doomed to failure for any programs of moderate complexity Show the program to someone else Check for common errors, e. g. Local vs. Reference Parameter = instead of == Localize the error using cout statements
Slide 5 - 44 General Debugging Techniques Use a debugger Tool typically integrated with a development environment that allows you to stop and step through a program line-by-line while inspecting variables assert macro Can be used to test pre or post conditions #include <cassert> assert(boolean expression) If the expression is false then the program will abort
Slide 5 - 45 Assert Example Denominator should not be zero in Newton’s Method
- Slides: 45