400 likes | 640 Views
4. Functions, Procedures, Methods – Encapsulating Behavior. SW Engineering Goal: Create modules of code that can be reused, easily understood readability easily modified maintainability, easily extended/reduced scalability.
E N D
4. Functions, Procedures, Methods – Encapsulating Behavior SW Engineering Goal: Create modules of code that can be reused, easily understood readability easily modified maintainability, easily extended/reduced scalability. 1st step: the function idea from math. Functions are also known as procedures - usually when more than one value computed; and methods when in the context of object oriented programming Terminology: In general functions express a rule/law of computation; in programming it is an algorithm, that sets forth the steps to be executed by the machine, i.e. the function is a unit/module for a certain behavior, or the function encapsulates behavior. MET CS 563 - Fall 2008 4. Functions
Math Functions Mathematics f ( x ) = y Example: sin ( x ) = y sin ( 90°) = 1 f Domain X Y Range x = 90° 1 = y x y input output function value function name argument f MET CS 563 - Fall 2008 4. Functions
x max(x,y) max2( ) y What do we need to know for defining and using a function? type of returned value name of function type of argument(s) argument name(s) Definition: <type > <identifier>(<type> <identifier>, <type> <identifier>, …) <function-body> function header: contains all info for use Example: int max2( int x, int y ) { if (x >= y) return x; else return y; } function body MET CS 563 - Fall 2008 4. Functions
i max2( ) j max(i,j) messages between client and server Calling Environment / Client int max2(int x, int y) { if (x >= y) return x; else return y; } main() { . . largest = max2 ( i , j ); . . } Using/Calling/Invoking Functions formal parameters/arguments (x,y) in definition actual parameters/arguments (i,j) in invocation Invocation / Server x y MET CS 563 - Fall 2008 4. Functions
formal parameter: parameter that appears in function definition only as PLACEHOLDER. NO computation is done. Formal and Actual Parameters; Parameter Passing actual parameter: parameter that appears in function invocation gives the input value computation is performed parameter passing: when the function is called its arguments receive specific values (through the actual parameters) that are used to perform the computation in this particular invocation. This process is called parameter passing. The semantics of argument passing is the same as initialization - argument types are checked and conversion made if needed. Depending on how it is performed the results on the calling environment aredifferent. C++ has three different mechanisms for parameter passing – by value, by reference, and by pointer. MET CS 563 - Fall 2008 4. Functions
Header of the standard math library (available functions specified in Visual C++ Programmer's Guide) //Example 4.1: Built-in functions of the Standard Math Library //Stroustrup, p.660) //file: mathLib.cpp #include <iostream> #include <iomanip> #include <cmath> //must be included to provide access to math library //<math.h> in older versions and C using namespace std; int main() { double x; //Square root cout << "double sqrt(double number) computes the " << "square root of number, e.g. " << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 3 ) << "\n\tsqrt(" << 9.0 << ") = " << sqrt( 9.0 )//note: error if 9 instead of 9.0 in some compilers << "\n\tEnter number you want to know the square root of: "; cin >> x; cout << "\tsqrt( " << x <<") = "<< sqrt(x)<<endl; double sqrt(double number) computes the square root of number, e.g. sqrt(9.000) = 3.000 Enter number you want to know the square root of: 121 sqrt( 121.000) = 11.000 MET CS 563 - Fall 2008 4. Functions
Example 4.1 : pow() //Power cout << "\ndouble pow(double x, double y) computes " << "x raised to power y, e.g. " << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 3 ) << "\n\tpow(" << 2 <<','<< 4 <<") = " << pow(2, 4 ) << "\n\tEnter two numbers x and y to compute x raised to power y is: "; double y; cin >> x >> y; cout << "\tpow( " << x <<','<< y <<") = "<< pow(x, y)<<endl; double pow(double x, double y) computes x raised to power y, e.g. pow(2,4) = 16.000 Enter two numbers x and y to compute x raised to power y is: 2 10 pow( 2.000,10.000) = 1024.000 MET CS 563 - Fall 2008 4. Functions
Example 4.1 : sin() //sin const double PI=3.14159; cout << "\ndouble sin(double x) with x in radians computes " << "sin(x), e.g. " << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 3 ) << "\n\tsin(" << 0 <<") = " << sin(0.0) //note: error if 0 instead of 0.0 in some compilers << "\n\tsin(PI/6)=sin(" << PI/6 <<") = " << sin(PI/6) << "\n\tEnter angle in radians to compute sin(x): "; cin >> x ; cout << "\tsin( " << x <<") = "<< sin(x)<<endl; double sin(double x) with x in radians computes sin(x), e.g. sin(0) = 0.000 sin(PI/6)=sin(0.524) = 0.500 Enter angle in radians to compute sin(x): 1.57 sin( 1.570) = 1.000 MET CS 563 - Fall 2008 4. Functions
Example 4.1 : tan() //tan cout << "\ndouble tan(double x) with x in radians computes "<< "tan(x), e.g. " << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 3 ) << "\n\ttan(" << 0 <<") = " << tan(0.0) //note: error if 0 instead of 0.0 in some compilers << "\n\ttan(PI/2)=tan(" << PI/2 <<") = " << tan(PI/2) << "\n\tEnter angle in radians to compute tan(x): "; cin >> x ; cout << "\ttan( " << x <<") = "<< tan(x)<<endl; return 0; } double tan(double x) with x in radians computes tan(x), e.g. tan(0) = 0.000 tan(PI/2)=tan(1.571) = 753695.995 Enter angle in radians to compute tan(x): .7855 tan( 0.785) = 1.000 should be , but no warning! MET CS 563 - Fall 2008 4. Functions
double tan(double x) - tan(x) tan(PI/2)=tan(1.57079) = 753696 tan(PI/4)=tan(0.785397) = 0.999999 tan(-PI/4)=tan(-0.785397) = -0.999999 tan(-PI/2)=tan(-1.57079) = 753696 //Example 4.2: Range and Domain Errors //file: outBound.cpp ….. const double PI=3.14159; //tan cout << "\ndouble tan(double x) - tan(x)\n"; cout << "\ttan(PI/2)=tan(" << PI/2 <<") = " << tan(PI/2)<<endl; cout << "\ttan(PI/4)=tan(" << PI/4 <<") = " << tan(PI/4)<<endl; cout << "\ttan(-PI/4)=tan(" << -PI/4 <<") = " << tan(-PI/4)<<endl; cout << "\ttan(-PI/2)=tan(" << -PI/2 <<") = " << tan(PI/2)<<endl; //Square root cout << "\ndouble sqrt(double x) - square root\n"; cout << "\tsqrt(-1.0) = "<< sqrt(-1.0)<<endl; cout << "\tsqrt(-1.0) = "<< sqrt(-1.0)<<endl; //log cout << "\ndouble log(double x) - natural logarithm\n"; cout << "\tlog(0.0) = "<< log(0.0)<<endl; cout << "\tlog(-1.0) = "<< log(-1.0)<<endl; error and no warning! correctly warns on infinite or not defined values double sqrt(double x) - square root sqrt(-1) = -1.#IND double log(double x) - natural logarithm log(0) = -1.#INF log(-1) = -1.#IND Moral: Check Documentation and Boundary Cases!!! MET CS 563 - Fall 2008 4. Functions
// Example 4.3: User defined functions//Functions returning numerical values - perimeter definition of perimeter( ) double perimeter(double length, double width) //Computes perimeter of rectangle //Receives:sides of rectangle length, width - two doubles //Returns: perimeter - double { double p; //functions can have their own declarations // in this case and overkill, however, see area function below p = 2*(length + width); return p; } MET CS 563 - Fall 2008 4. Functions
definition of area( ) double area(double length, double width) //Computes area of rectangle //Receives:sides of rectangle length, width - two doubles //Returns: area - double { return length * width; } // Example 4.3 : area, isSquare definition of isSquare( ) bool isSquare(double length, double width) //Tests whether a rectangle is a square //Receives:sides of rectangle length, width - two doubles //Returns: true(1) if rectangle is a square and false(0) otherwise { if (length==width) return TRUE; //return 1; else return FALSE; // return 0; } MET CS 563 - Fall 2008 4. Functions
int main() { double side1, side2; //sides of a rectangle cout << "Computing the perimeter and area of a rectangle"<<endl; cout << "Enter the two sides of the rectangle: \n"; cin >> side1 >> side2; cout << "The perimeter is " << perimeter(side1, side2) << endl; cout << "The area is " << area(side1, side2) << endl; if (isSquare(side1, side2)) cout << "The rectangle is a square"; else cout << "The rectangle is not a square" << endl; return 0; } // Example 4.3 : main Computing the perimeter and area of a rectangle Enter the two sides of the rectangle: 3 5 The perimeter is 16 The area is 15 The rectangle is not a square MET CS 563 - Fall 2008 4. Functions
Unconditional Jumps return and exit return <argument>; terminates function that executes the return statement. Examples: in main return 0 terminates program indicating successful execution; in a function return identifier terminates function and returns value of identifier. exit <argument>; terminates programno matter what function executes the exit statement. Examples: A popular convention for arguments are the values 0 for successful execution and 1 for abnormal ending. The arguments are returned to the operating system. To protect the programs from changes in convention, the standard library (stdlib.h, or cstdlib) provides two symbolic constants EXIT_SUCCESS and EXIT_FAILURE. Using the symbolic constants is safer and enhances readability too. (Do not forget to include the standard library when working with the literals!) MET CS 563 - Fall 2008 4. Functions
Functions with No Return Value Function Definition: <return-type > <identifier>(<type> <identifier>, <type> <identifier>, …) <function-body> Special Cases: a) No Return Value void <identifier>(<type> <identifier>, <type> <identifier>, …) <function-body> Example: Function with argument and no return value void errorMessage(int flag){ if(flag) cout<<"Flag is true\n"; else cout<<"Flag is false\n"; } MET CS 563 - Fall 2008 4. Functions
Functions with Empty Parameter Lists b)Empty Parameter Listsor <return-type > <identifier>(void) <function-body> <return-type > <identifier>( ) <function-body> Example: return value, but no arguments int absValue(void){ int x; cin>>x; if(x>) return x; else return -x; } Note that void can be omitted if function has no arguments, but must be present if no value is returned Example: no return value, no arguments void message(){ cout<<"Function with no arguments and no return value\n"; } MET CS 563 - Fall 2008 4. Functions
Problem: Allowing function calls "BEFORE" the function is defined without causing confusion? Function Prototypes • "BEFORE" means the function definition is • in same file after invocation • in another file • in a library Solution in ANSI C and C++: Provide the information needed for the formulating the function call and nothing more. This is <returned-type> <function-name>(<argument-type>,…,<argument-type>); e.g. int min2 ( int , int ); double sqrt ( double); function prototype MET CS 563 - Fall 2008 4. Functions
Header Files • The prototypes of all functions in a library, e.g. the standard libraries, are collected in files, called header files. The programmer can also create his/her own header files. • "Old style" header files have the .h extension, e.g. iostream.h, string.h, iomanip.h • "New style" header files omit the .h extension, e.g. <algorithm>, <memory> • Header files must be included in order to make the function prototype available, e.g. • #include <memory> • #include < iostream.h > • #include " myHeader.h" < > for standard libraries " " for programmer defined headers MET CS 563 - Fall 2008 4. Functions
Goal: Provide values for arguments if none are specified. The argument values specified by the user override the default values Specification: Defaults are specified with the first occurrence of the function name, typically with the prototype Default Argument Values //Figure 3.5: Default argument values int max ( int = 0, int = 0); int main() { cout << "The largest number is " << max() << endl; cout << "The largest number is " << max(1,2) << endl; cout << "The largest number is " << max(3) << endl; return 0; } int max(int x, int y){ cout<<" x="<<x <<" y="<<y<<endl; if (x >= y) return x; else return y; } No argument values supplied; default values for arguments Two argument values supplied; default values are overridden One argument values supplied; overrides first default; it is not possible to override the second default without overriding the first x=0 y=0 The largest number is 0 x=1 y=2 The largest number is 2 x=3 y=0 The largest number is 3 MET CS 563 - Fall 2008 4. Functions
The function uses the values of the actual parameters but cannot change them OUTSIDE the function. Call by Value int main() { int n = 8, p; int product ( int ); cout << "This program computes the\n" << "product of the numbers from 1 to n" << endl; cout << "Enter number n: "; cin >> n ; p = product ( n ) ; cout << "The product of the numbers from 1 to " << n << " is "<< p << endl; return 0; } int product ( int n ) { int product = 1 ; for ( ; n > 0 ; --n ) product *= n ; return product ; } function prototype as declaration in main( ) n remains unchanged in main() n is decremented in product() This program computes the product of the numbers from 1 to n Enter number n: 3 The product of the numbers from 1 to 3 is 6 MET CS 563 - Fall 2008 4. Functions
Goal:Allow the function to change the actual arguments in the calling environment A reference object is a synonym or alias of another object. They are declared by the type of which they are an alias, followed by & Reference objects must be initialized as they are only aliases, i.e. they do not define/declare a new object: Call by Reference with References Call by Reference with References - Example int i; int& iRef = i; // iRef is an alias of i Definition: void swapWithRef(int& a, int& b) { int s; s=a; a=b; b=s; } Call: swapWithRef(x, y); MET CS 563 - Fall 2008 4. Functions
Nested Function Calls Example: Finding the largest of four numbers Functions: max2 ( ) returns largest of two numbers x max(x , y) y max2 ( ) max4 ( ) returns largest of four numbers x y max2 ( ) max (x, y) max (x,y,z,w) max2 ( ) z w max2 ( ) max4 ( ) max (z, w) MET CS 563 - Fall 2008 4. Functions
// Example 4.4 : Nested function calls - largest of four numbers//main int max2(int, int); int max4(int, int, int, int); int main() { int a, b, c, d; cout << "Computing the largest of four numbers"<<endl; cout << "Enter four integers: \n"; cin >> a >> b >> c >> d; cout << "The largest number is " << max4(a, b, c, d) << endl; return 0; } MET CS 563 - Fall 2008 4. Functions
// Example 4.4 : Nested function calls - largest of four numbers//function definitions int max2(int x, int y) //Computes largest of two int //Receives:two int //Returns: largest { if (x >= y) return x; else return y; } int max4(int w, int x,int y, int z) //Computes largest of four int //Receives:four int //Returns: largest { return max2(max2(w,x), max2(y,z)); } Computing the largest of four numbers Enter four integers: 3 1 78 333 The largest number is 333 MET CS 563 - Fall 2008 4. Functions
Random Number Generation rand ( ) and strand ( ) • Example: Rolling a six sided die - See D&D, Ch. 3.8, p.170 • Problems: a) How to generate random numbers? b) How to limit the random values to the ones needed by the application, e.g. 1 to 6 for the six sided die? • The function rand ( ) from the standard library <stdlib.h> produces an integer in • [ 0 , RAND_MAX] at random, i.e. every integer between 0 and RAND_MAX has • an equal chance to be chosen when rand ( ) is called. • RAND_MAX is a symbolic constant defined in stdlib.h and • RAND_MAX > = 32767 = maximum value for 2 bytes int • The function rand( ) is a pseudo random generator, in that although it picks values at • random, it repeats the random sequence every time the program is executed: • Use rand() for developing and debugging your program. • After debugging, one can produce random sequences by randomizing with the • function srand( <unsigned> ). Every time the programruns an unsigned (positive) • integer, called the seed, is given to srand( ) which "seeds" the rand() function to • produce every time a different sequence. MET CS 563 - Fall 2008 4. Functions
Scaling: transforming the range of rand ( ) • “heads and trails” i = rand % 2 • 6 sided die 1 2 3 4 5 6 • i = rand ( ) % 6 0 1 2 3 4 5 • j = rand ( ) % 6 + 1 1 2 3 4 5 6 MET CS 563 - Fall 2008 4. Functions
Where can an object be used, accessed, referenced? When and how long does object exist in memory? block function file automatic static Scope and Storage Classes Given by scope rules that follow the basic principle: a) object scope is within program unit (and any other unit nested within it) in which object has been declared b) in case of identical identifiers, the object in the inner block supercedes the object in the outer block Given by storage class specifiers: auto: exists while its scope unit is active. register: auto + advises the compiler to use a register; may be ignored, e.g. not enough registers available. static: exists while the program is running extern: static + indicates object declared outside current unit local global MET CS 563 - Fall 2008 4. Functions
Static Variables (staticVariable.cpp) void f(int a){ while(a--){ static int n = 0; //initialize once int x = 0; //initialized a times in each call of f() cout << "n is " << n++ << " , x is " << x++ << endl; } } int main() { f(3); } n is 0 , x is 0 n is 1 , x is 0 n is 2 , x is 0 Static variables provide a function with its very own memory without introducing global variables that can be accessed/modified/corrupted by other functions MET CS 563 - Fall 2008 4. Functions
b local static: remains in memory after f() exits; and is available for the next f() invocation; b is not recreated/reinitialized with each f() call a keeps its value in main, although it changes in f() int f(int a) //adds counter b to argument a,then increments b { cout << "\tEntering f() \n"; static int b = 1; cout << "\tf: a="<<a<<" b="<<b<<endl; a += b++; cout << "\tf: a="<<a<<" b="<<b<<endl; cout << "\tLeaving f() \n"; return a; } int main() { cout << "Entering main()\n"; int x=0, a=10; cout.setf(ios::fixed|ios::right); //DD,Ch.11 cout<<"main: x="<<x<<" a="<<a<<endl; x = f(a); cout<<"main: x="<<x<<" a="<<a<<endl; x = f(a); cout<<"main: x="<<x<<" a="<<a<<endl; // Example 4.5: Scope and Storage: What does the following program print? Entering main() main: x=0 a=10 Entering f() f: a=10 b=1 f: a=11 b=2 Leaving f() main: x=11 a=10 Entering f() f: a=10 b=2 f: a=12 b=3 Leaving f() main: x=12 a=10 MET CS 563 - Fall 2008 4. Functions
Entering block block: a = 100 Leaving block() main: a = 10 Leaving main() a keeps its value in main, although it changes in block // Example 4.5: Scope and Storage: What does the following program print? local variable a in block declared, supercedes local variable a from the outer block { cout << "\tEntering block\n"; int a=100; cout<<"\tblock: a= "<<a<<endl; cout<<"\tLeaving block\n"; } cout<<"main: x="<<x<<" a="<<a<<endl; cout<<"Leaving main()\n"; return 0; } • Note: • Local variables default to auto, therefore the auto specifier is routinely omitted • Global variables default to extern; need to be included when program resides in multiple files MET CS 563 - Fall 2008 4. Functions
Recursion vs. Iteration Recursive: Function that calls itself Example: factorial(1)=1 factorial(n) = n*factorial(n-1) Recursive implementation: unsigned long factorial(int n) { if(n<=1) return 1; else return n*factorial(n-1); } Iterative implementation: unsigned long factorial(int n) { unsigned long f=1; for(n; n >1;n--) f=n*f; return f; } • More elegant and readable • More overhead as multiple function calls • Substantially more efficient • Always preferred when readability not sacrificed too badly MET CS 563 - Fall 2008 4. Functions
Inline Functions Goal: Advise the compiler to incorporate the function code within the program, thus avoiding the overhead of a function call. This is especially handy for small functions. However the compiler may disregard the advice Definition: inline <return-type > <identifier>(<type> <identifier>, …) <function-body> Example: inline double area(double length, double width) {return legth*width }; Note: recursive inline functions are possible; a clever compiler can generate the constant 720 for factorial(6), while another generates 6*factorial(5), and yet another an un-inlined call factorial(6). MET CS 563 - Fall 2008 4. Functions
Overloading Functions Main Idea: Use the same function name (function overload) or operator symbol (operator overload) to perform different computations, initializations or other actions. Why would this be useful? Example 1: Overloading functions A function area() computes the area of a rectangle, given its two sides. For the special case of a square, we want to compute the area using the "same" function and input just one side. Solution: define two functions having the same name, but different argument lists, so that area(7, 3) returns 21 while area(7) returns 49 MET CS 563 - Fall 2008 4. Functions
Function Overload Example In general when the same identifier (function name) is used for several different function definitions the set of resulting functions is referred to as an overloaded function. For the area definition in Example 1 (fnctOverload.cpp) float area(float a, float b){ return a*b; } float area(float a){ return a*a; } Computes area of rectangle Input: two sides of type float Returns area of type float Computes area of square Input: side of type float Returns area of type float MET CS 563 - Fall 2008 4. Functions
Function Overload Example (continued) int main() { float side1, side2; cout << "This program computes areas of rectangles and squares" << endl; cout << "\nEnter the first side of the rectangle:"; cin >> side1; cout << "\nEnter the second side of the rectangle:"; cin >> side2; cout << "\nThe area of the rectangle is " << area(side1, side2)<<endl; cout << "\nEnter the side of the square:"; cin >> side1; cout << "\nThe area of the square is " << area(side1) << endl; return 0; } This program computes areas of rectangles and squares Enter the first side of the rectangle: 7 Enter the second side of the rectangle: 3 The area of the rectangle is 21 Enter the side of the square: 7 The area of the square is 49 MET CS 563 - Fall 2008 4. Functions
How does overload work? • · The compiler decides which function definition to choose through argument matching - the process of comparing type and number of the actual and formal arguments according to the function signature that includes the function name and the list of the argument types, not including const and ‘&’ . • · Note: The different definitions of the overloaded function cannot differ only in the type of the returned value; they must differ in the type or/and number of arguments sent to them. (see functOverload_DONOT.cpp) MET CS 563 - Fall 2008 4. Functions
Rules for Resolving Overloading • Exact Match • Match with Type Conversion • (see fnctOverload_Promotion.cpp • fnctOverload_Defaults.cpp ) MET CS 563 - Fall 2008 4. Functions
Functions - Summary • Functions encapsulate behavior. • Functions interact with the (calling) environment by messages: they receive the parameter values and reply by the returned value. • The parameters in the definition of a functionsdo not perform any computation and are therefore called formal parameters; The parameters in the invocation of a functionsdo perform the computation and are therefore called actual parameters; • Function prototypes contain only the information needed to interact/use a function and allow the compilation of a call before the function definition. • Parameters are passed by value, i.e. copies of the parameter values are given to the function and any changes to these parameters within the functions remain local, with no effect whatsoever to the values of the parameters in the calling environment. • Functions can be called from within other functions, a process referred to as nested function calls. MET CS 563 - Fall 2008 4. Functions
Summary (continued) • function parameters can be supplied with default values in the first occurrence – either prototype or definition - of the function. This allows calling the function without arguments (the defaults provide values), or with fewer arguments than specified in the parameter list (values are assigned from left to right without skipping and argument). • static variable local to the function provide are initialized only once with the 1st function call and are alive till the end of the program. • inline advises compiler to incorporated function code in program thus bypassing the function calling mechanism, and speeding up execution. However, the compiler may disregard the advice. • function overload allows to use the same function name for different calculations • an overloaded function is a set of functions with the same name each of them defined separately; the definitions of the functions cannot differ only in the type of the returned value, they must differ in the type and or number of the arguments. MET CS 563 - Fall 2008 4. Functions