750 likes | 771 Views
Functions. Purpose. D ivide the code into smaller segments that: - Perform one task, isolating the operation - A re Reusable - Internally: within one program - Externally: in other programs - Provide Abstraction : use of a complex object without knowledge of its details. Syntax.
E N D
Purpose Divide the code into smaller segments that: - Perform one task, isolating the operation - AreReusable - Internally: within one program - Externally: in other programs - Provide Abstraction: use of a complex object without knowledge of itsdetails.
Syntax Syntax is divided into 2 (optionally 3) parts: 1. Declaration: where the function is defined 2. Invocation: where the function is “called into action” (used). 3. Prototype: where a function is “listed” in a program to allow “invoke before define” when needed (optional).
Declaration Syntax returnType name(formalArguments) { } returnType: is the data type of the value returned, or void when no value is returned. name: is an identifier chosen by the programmer.
Declaration Syntax returnType name(formalArguments) { } formalArguments: is a comma-separated list of 0 or more arguments, where each argument is: type identifier or type & identifier
Declaration Syntax Examples: void hello() { } void print(int x) { } void print(int x, int y, int z){ } float divide(int x, int y) { } string askName() { } void askV(long & a, double & b){ }
Declaration Syntax If a return type is specified, the function must return a value of the specified type. Example: int fun() { inti; ... return i; // required }
Declaration Syntax If the return type is void, the function must NOT return a value. It may use return; if needed. Example: voidfun() { ... if (something) return; // optional, but allowed ... }
Invocation Syntax As an individual statement: name ( actualArguments ); Or, if it returns a value, as part of an expression: int x = name ( actualArguments ) * 2;
Invocation Syntax name ( actualArguments ); actualArguments: a comma-separated list of expressions. Actual Arguments must match Formal Arguments in: - Number - Type - Order
Invocation Syntax Example: void fun(int a, float b, string c){ } fun(2, 3.0, ”Hi”);//valid int a=3; fun(2*a-1, 4, ”?”); //valid fun(2, 3.0); //must have 3 acts fun(2,”Hi”,3.0); //order: int,flt,str int x=fun(2, 3.0, ”Hi”); //reType void
Invocation Syntax When the Formal Argument has a &, the corresponding actual must be a single variable of the exact same type. void fun(int &a) { } int b=2; float c=3; fun(b); //valid fun(b+2); // not just a variable fun(2); // not a variable fun(c); // must be an int variable
Formal Argument Classifications Actual Argument : arg. in the Invocation Formal Argument: arg. in the Declaration - Pass-By-Value (PBV):has no & - Pass-By-Reference (PBR): has a&
Invocation Semantics When a function is invoked: 1.For each PBV (no &) argument: a. Formals are allocated. b.Actuals are evaluated. c.Value of actuals are copiedto formals. 2.For each PBR (with &) argument: Formals simply rename corresponding Actuals
Invocation Semantics When a function is invoked (continued): 3.Execution control jumps to the beginning of the function. When the function returns: 1.PBV Formals are deallocated 2.PBR Formals no longer rename Actuals 3.Execution jumps back to the invocation 4.If a value is returned, the invocation represents the value returned.
Semantics Example: execution always begins at main() void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: vars c and d are allocated and initialized void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: function fun() is invoked; follow the Semantics void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 1.a. PBV formal arguments are allocated void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 1.b. PBV actual arguments are evaluated: c+2 evaluates to 7 void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 1.c. PBV actual arg. value copied to Formal: void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 2. PBR Formals rename Actual: void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 3. Execution jumps to begin of function void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: ais incremented void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: b is decremented void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: a and b are printed void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: exit/return: follow semantics void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 1. PBV Formals are deallocated void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 2. PBR Formals no longer rename void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: 3. Execution jumps back to Invocation void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: c and d are printed and program ends void fun(int a, int & b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example: IMPORTANT NOTE: - at the beginning of main: c=5, d=10 - at the end of main: c=5, d=9 - The function changed d, not c, because of & void fun(int a, int& b) { a++; b--; cout << a << ” ” << b << endl; } void main() { int c=5, d=10; fun(c+2,d); cout << c << ” ” << d; }
Semantics Example 2: Execution starts at main() intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3) - 1; cout << d; }
Semantics Example 2: d is allocated (not initialized) intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3) - 1; cout << d; }
Semantics Example 2: evaluate the Right Side of the = which includes an invocation. intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 1.a. Allocate PBV Formal a intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 1.b. Evaluate PBV actual (to 3) intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 1.c. copy Actual to Formal (essentially: a = 3;) intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 2. There are no PBR Formals intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 3. Execution jumps to { intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: Execute the assignment intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: return the value of a(6) intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 1. PBV Formals are deallocated intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 2. There are no PBR Formals intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 3. Execution returns to the invocation intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3)– 1; cout << d; }
Semantics Example 2: 4. The Invocation now represents the value returned (6) intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3) – 1; // 6 - 1 cout << d; }
Semantics Example 2: Finish the evaluation and assignment intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d = doubleIt(3) – 1; // d=5 cout << d; }
Semantics Example 2: print d and end program intdoubleIt(int a) { a = a * 2; return a; } void main() { int d; d= doubleIt(3) – 1; cout << d; }
Semantics Example 3: multiple invocations void roja() { cout << ”red” << endl; } void azul() { cout << ”blue” << endl;} void pupura() { roja(); cout << ”Purple” << endl; azul(); } void main() { azul(); pupura(); }
Semantics Example 3: Execution always starts at main() void roja() { cout << ”red” << endl; } void azul() { cout << ”blue” << endl;} void pupura() { roja(); cout << ”Purple” << endl; azul(); } void main() { azul(); pupura(); }