Presentation is loading. Please wait.

Presentation is loading. Please wait.

Passing information to and from a function

Similar presentations


Presentation on theme: "Passing information to and from a function"— Presentation transcript:

1 Passing information to and from a function
Function Parameters Passing information to and from a function Copyright © Curt Hill

2 Copyright © 2006-2016 - Curt Hill
Parameter Questions What can be passed? Variables Constants Expressions Functions Can the called function change the variable? Copyright © Curt Hill

3 Parameter Passage Mechanisms
C had two parameter passage mechanisms: By value By pointer C++ has these two and one additional By reference First however some definitions Copyright © Curt Hill

4 Copyright © 2006-2016 - Curt Hill
Definitions int func(int a, double b){ … } x = func(x,y)*2 - func(w,z); Formal parameters are part of the definition Actual parameters are part of the call For any one function only one set of formals but perhaps many sets of actuals The names do not have to match Copyright © Curt Hill

5 Copyright © 2006-2016 - Curt Hill
Formal parameters The formal parameter list determines everything It defines the rules that everyone else plays by The number of parameters The type of each parameter The parameter passage mechanism Value, pointer or reference Copyright © Curt Hill

6 Copyright © 2006-2016 - Curt Hill
Communication A function that does not communicate with its caller is worthless There are three mechanisms for communication: Parameters Function result Global variables Copyright © Curt Hill

7 Copyright © 2006-2016 - Curt Hill
Direction Parameters may carry information in to or out of a function or both We sometimes refer to parameters as in, out or in-out Function results are out only Global variables can carry information in either direction They are also the least desirable communication mechanism for reasons to be seen later Copyright © Curt Hill

8 Copyright © 2006-2016 - Curt Hill
Parameter Names The formal parameter names do not have to match anything Not the actual parameter names On any others They have the same scope as the local variables of the function The prototype does not even have to specify names: double pow(double,double); is legal Copyright © Curt Hill

9 Copyright © 2006-2016 - Curt Hill
Value Parameters So far we have only seen value parameters Value parameters are noted in the formal parameter list by: type name A value parameter may only take information into a function The function receives a copy of the value of the actual parameter Copyright © Curt Hill

10 Copyright © 2006-2016 - Curt Hill
For each value parameter a new variable is created This new variable is initialized with the value from the actual parameter When the function returns the variable is destroyed Any changes to the value parameter remain in the function and are not communicated back to the caller An in parameter Copyright © Curt Hill

11 Copyright © 2006-2016 - Curt Hill
What can the Actual be? With a value parameter the actual is copied to the formal parameter anything that is assignment compatible will work Thus the actual may be a: A constant, variable or expression Of any type that may be cast into the type of the formal parameter Lots of flexibility Copyright © Curt Hill

12 Copyright © 2006-2016 - Curt Hill
Value Trace(0) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 k 5 Copyright © Curt Hill

13 Copyright © 2006-2016 - Curt Hill
Value Trace(1) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 k 5 Copyright © Curt Hill

14 Copyright © 2006-2016 - Curt Hill
Value Trace(2) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 Copyright © Curt Hill

15 Copyright © 2006-2016 - Curt Hill
Value Trace(3) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 j k 2 Copyright © Curt Hill

16 Copyright © 2006-2016 - Curt Hill
Value Trace(4) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 j 4 k 2 Copyright © Curt Hill

17 Copyright © 2006-2016 - Curt Hill
Value Trace(5) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 j 4 k 2 Test is false Copyright © Curt Hill

18 Copyright © 2006-2016 - Curt Hill
Value Trace(6) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 j 4 k 2 Changing formal parameter does not change actual Copyright © Curt Hill

19 Copyright © 2006-2016 - Curt Hill
Value Trace(7) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 k 5 i 2 j 4 k 2 Return value is = 2 Copyright © Curt Hill

20 Copyright © 2006-2016 - Curt Hill
Value Trace(8) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 2 k 5 Copyright © Curt Hill

21 Copyright © 2006-2016 - Curt Hill
Value Trace(9) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 2 k 5 Output 2 2 5 Copyright © Curt Hill

22 Copyright © 2006-2016 - Curt Hill
Value Trace(10) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 2 k 5 Copyright © Curt Hill

23 Copyright © 2006-2016 - Curt Hill
Value Trace(11) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 Copyright © Curt Hill

24 Copyright © 2006-2016 - Curt Hill
Value Trace(12) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 j k 2 Copyright © Curt Hill

25 Copyright © 2006-2016 - Curt Hill
Value Trace(13) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 j 8 k 2 Copyright © Curt Hill

26 Copyright © 2006-2016 - Curt Hill
Value Trace(14) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 j 8 k 2 Test is true Copyright © Curt Hill

27 Copyright © 2006-2016 - Curt Hill
Value Trace(15) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 j 8 k 2 10 Copyright © Curt Hill

28 Copyright © 2006-2016 - Curt Hill
Value Trace(16) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 2 j 8 k 2 10 Copyright © Curt Hill

29 Copyright © 2006-2016 - Curt Hill
Value Trace(17) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main func i 2 j 3 2 k 5 i 4 2 j 8 k 2 10 Return value is = 0 Copyright © Curt Hill

30 Copyright © 2006-2016 - Curt Hill
Value Trace(18) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 2 k 5 Copyright © Curt Hill

31 Copyright © 2006-2016 - Curt Hill
Value Trace(19) int func(int i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j <<k << “\n”; k = func(i+j); cout << i << j << k<< “\n”; main i 2 j 3 2 k 5 Output 2 2 0 Copyright © Curt Hill

32 Copyright © 2006-2016 - Curt Hill
Commentary Copy into a console program in Dev and try it Trace it results should be: Look out for PPT line endings which usually show as a rectangle Parameters are passed by value Functions may not access each others local variables Copyright © Curt Hill

33 Copyright © 2006-2016 - Curt Hill
What is missing? Value parameters may be input only That is they may only carry values into the function How are out or in-out parameters handled Two ways: Pointer parameters Available in C Not covered until later Reference parameters Copyright © Curt Hill

34 Copyright © 2006-2016 - Curt Hill
Reference parameters A value parameter receives a copy of the actual parameter Thus a constant may be passed A reference parameter receives the actual variable Thus it may change the value of the variable It restricts what may be passed in the actual parameter Copyright © Curt Hill

35 Copyright © 2006-2016 - Curt Hill
Form of the Formal The mark of a reference parameter is the ampersand (&) The form of the reference parameter is: type & name For example: int fn(int & a, float b, double & c) Two reference parameters One value parameter No space needed before or after & Copyright © Curt Hill

36 Copyright © 2006-2016 - Curt Hill
Actual Parameters This also changes the form of actual parameters The actual must be a variable No constants and no expressions It must be of exactly the same type The purpose of a reference parameter is to change the variable How do you change a constant or expression? Copyright © Curt Hill

37 Copyright © 2006-2016 - Curt Hill
Reconsider the trace Now lets consider the previous program It will now have two ways to return values: The reference parameter The function result The second call of the first program is now illegal and thus must be changed Copyright © Curt Hill

38 Copyright © 2006-2016 - Curt Hill
Reference Trace(0) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 k 5 Copyright © Curt Hill

39 Copyright © 2006-2016 - Curt Hill
Reference Trace(1) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 k 5 Copyright © Curt Hill

40 Copyright © 2006-2016 - Curt Hill
Reference Trace(2) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i func’s i is now an alias for main’s i Copyright © Curt Hill

41 Copyright © 2006-2016 - Curt Hill
Reference Trace(3) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i j k 2 Copyright © Curt Hill

42 Copyright © 2006-2016 - Curt Hill
Reference Trace(4) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i j 4 k 2 Copyright © Curt Hill

43 Copyright © 2006-2016 - Curt Hill
Reference Trace(5) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i j 4 k 2 test is false Copyright © Curt Hill

44 Copyright © 2006-2016 - Curt Hill
Reference Trace(6) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i j 4 k 2 The two i variables are changed Copyright © Curt Hill

45 Copyright © 2006-2016 - Curt Hill
Reference Trace(7) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 k 5 i j 4 k 2 = 2 Copyright © Curt Hill

46 Copyright © 2006-2016 - Curt Hill
Reference Trace(8) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 2 k 5 Returned 2 is set into j Copyright © Curt Hill

47 Copyright © 2006-2016 - Curt Hill
Reference Trace(9) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 2 k 5 Output Last time it was 2 2 5 Copyright © Curt Hill

48 Copyright © 2006-2016 - Curt Hill
Reference Trace(10) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 2 k 5 Copyright © Curt Hill

49 Copyright © 2006-2016 - Curt Hill
Reference Trace(11) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i func’s i is now an alias for main’s j Copyright © Curt Hill

50 Copyright © 2006-2016 - Curt Hill
Reference Trace(12) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i j k 2 Copyright © Curt Hill

51 Copyright © 2006-2016 - Curt Hill
Reference Trace(13) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i j 4 k 2 Copyright © Curt Hill

52 Copyright © 2006-2016 - Curt Hill
Reference Trace(14) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i j 4 k 2 test is false Copyright © Curt Hill

53 Copyright © 2006-2016 - Curt Hill
Reference Trace(15) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i j 4 k 2 main’s j is changed Copyright © Curt Hill

54 Copyright © 2006-2016 - Curt Hill
Reference Trace(16) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main func i 2 j 3 2 k 5 i j 4 k 2 0+0-2 = -2 Copyright © Curt Hill

55 Copyright © 2006-2016 - Curt Hill
Reference Trace(17) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 2 k 5 -2 Copyright © Curt Hill

56 Copyright © 2006-2016 - Curt Hill
Reference Trace(18) int func(int & i) { int j,k=2; j = k * i; if (j>k*2) k+=j; i = i - 2; return(i+j-k); } int main (void) { int i=2,j=3,k=5; j = func(i); cout<< i << j << k << “\n”; k = func(j); cout << i << j << k << “\n”; main i 2 j 3 2 k 5 -2 Output is 0 0 -2 Last time it was 2 2 0 Copyright © Curt Hill

57 Copyright © 2006-2016 - Curt Hill
Contrast A value parameter always provides a copy A reference parameter is an alias A new name on an old thing Value parameters have flexible actual parameters Reference parameters have rigid actuals Copyright © Curt Hill

58 Copyright © 2006-2016 - Curt Hill
Copy Overhead The only in parameter is a value parameter The copying of the value may be a problem On simple variables this is no problem since the copy is small What if the item is a class or other structure and the size is large Say greater than 10,000 bytes Copyright © Curt Hill

59 Copyright © 2006-2016 - Curt Hill
Solution We could copy it by reference However it is in-out We could change it by mistake and introduce a bug C++ introduces a new mechanism to solve this problem: Constant reference parameters Copyright © Curt Hill

60 Constant Reference Parameters
Prefix a reference parameter with the reserved word const: const type & name This is used to get in only parameters, but to avoid the copy overhead The compiler will issue a syntax error on code that attempts to change a constant parameter Copyright © Curt Hill

61 Copyright © 2006-2016 - Curt Hill
Reference parameters are new to C++ Constant reference also C had only value and pointer C also went through several revisions The form of parameter declarations changed Started with FORTRAN style parameters Moved towards Pascal style parameters These are what we have seen Copyright © Curt Hill

62 FORTRAN style parameters
Since there is still quite a bit of old style code around it is best if you see both at least once Thus we will look at the same function using both styles of parameter declaration Copyright © Curt Hill

63 Copyright © 2006-2016 - Curt Hill
New Style Suppose that we have the following: double partial_factorial (int n, int k) { double fact=1.0; int i; for (i=k+1;i<=n;i=i+1) fact *= fact; return(fact); } Copyright © Curt Hill

64 Copyright © 2006-2016 - Curt Hill
Old Style Suppose that we have the following: double partial_factorial(n, k) int n,k; { double fact=1.0; int i; for (i=k+1;i<=n;i=i+1) fact *= fact; return(fact); } Copyright © Curt Hill

65 Copyright © 2006-2016 - Curt Hill
Notes The parameter list contains only the names of the parameters Between the end of the parameter list and the opening brace is the declarations of the parameters Inside the braces are local variables You may still see this kind of notation in various places: Windows programming documentation Code found on internet Copyright © Curt Hill

66 Copyright © 2006-2016 - Curt Hill
Another Thought C++ still accepts FORTRAN style parameters With very rare exceptions every valid C program should compile in C++ This is one of the disadvantages of upward compatibility Java started fresh Used most of good parts of C++ Ignored rest Copyright © Curt Hill

67 Copyright © 2006-2016 - Curt Hill
Scope Each pair of braces forms its own scope block Function braces are no exception The formal parameter list is sort of the odd ball The names of the formal parameters are only known within the function The prototype may leave the names out Somewhat similar to the declaration of a variable in a for header Copyright © Curt Hill

68 Consider the following
double partial_factorial(int n, int k) { double fact=1.0; for (int i=k+1;i<=n;i=i+1) fact *= i; return(fact); } What is known where? Copyright © Curt Hill

69 Copyright © 2006-2016 - Curt Hill
Answers Any code that follows partial_factorial knows: partial factorial exists as a function It returns a value of type double It takes two parameters, both integers However, the names of the parameters and all local variables are not accessible to this code Copyright © Curt Hill

70 Copyright © 2006-2016 - Curt Hill
Formal parameters Unusual scope Outside the function the code knows the number and type of the parameters, but not the names The scope of the names of the parameters is confined to the compound statement that is the body of the function Copyright © Curt Hill

71 Copyright © 2006-2016 - Curt Hill
Globals Identifiers that have global scope will be known to both the function and its caller These may be used to communicate between the two This is not the best form of communication but it works See the following example Copyright © Curt Hill

72 Copyright © 2006-2016 - Curt Hill
Global Trace(0) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global v Copyright © Curt Hill

73 Copyright © 2006-2016 - Curt Hill
Global Trace(1) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global v 2 Copyright © Curt Hill

74 Copyright © 2006-2016 - Curt Hill
Global Trace(2) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global v 2 Copyright © Curt Hill

75 Copyright © 2006-2016 - Curt Hill
Global Trace(3) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global v 2 Copyright © Curt Hill

76 Copyright © 2006-2016 - Curt Hill
Global Trace(4) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j 4 k 2 global v 2 Copyright © Curt Hill

77 Copyright © 2006-2016 - Curt Hill
Global Trace(5) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j 2 k 2 global Test is false v 2 Copyright © Curt Hill

78 Copyright © 2006-2016 - Curt Hill
Global Trace(6) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j 2 k 2 global v Copyright © Curt Hill

79 Copyright © 2006-2016 - Curt Hill
Global Trace(7) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j 2 k 2 global = 0 v Copyright © Curt Hill

80 Copyright © 2006-2016 - Curt Hill
Global Trace(8) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global To use the global like a parameter, assign v back to i. v Copyright © Curt Hill

81 Copyright © 2006-2016 - Curt Hill
Global Trace(9) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global Output: v Copyright © Curt Hill

82 Copyright © 2006-2016 - Curt Hill
Global Trace(10) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global v Copyright © Curt Hill

83 Copyright © 2006-2016 - Curt Hill
Global Trace(11) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 global v Copyright © Curt Hill

84 Copyright © 2006-2016 - Curt Hill
Global Trace(12) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global v Copyright © Curt Hill

85 Copyright © 2006-2016 - Curt Hill
Global Trace(13) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global v Copyright © Curt Hill

86 Copyright © 2006-2016 - Curt Hill
Global Trace(14) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global Test is false v Copyright © Curt Hill

87 Copyright © 2006-2016 - Curt Hill
Global Trace(15) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global v -2 Copyright © Curt Hill

88 Copyright © 2006-2016 - Curt Hill
Global Trace(16) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main func i 2 j 3 k 5 j k 2 global = -4 v -2 Copyright © Curt Hill

89 Copyright © 2006-2016 - Curt Hill
Global Trace(17) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 -4 global v -2 Copyright © Curt Hill

90 Copyright © 2006-2016 - Curt Hill
Global Trace(18) int v; int func() { int j,k=2; j = k * v; if (j>k*2) k+=j; v = v - 2; return(v+j-k); } int main (void) { int i=2,j=3,k=5; v = i; j = func(); cout<< i << j << k << << v; v = j; k = func(); cout << i << j << k << v; main i 2 j 3 k 5 -4 global Output: v -2 Copyright © Curt Hill

91 What is wrong with this code?
Additional assignment statement needed func would be difficult to use in other programs Each call needs two statements The definition of the global variable v Both global variables and reference parameters demonstrate side effects Reference parameter side effects are expected Copyright © Curt Hill

92 Communication with functions
Function results Out only Value parameters In only Reference parameters In-out Global variables These are ordered in preference Copyright © Curt Hill

93 Copyright © 2006-2016 - Curt Hill
Commentary If at all possible use only value parameters and function results These are the most obvious and cause the least problem for the one who reads the code Use reference parameters less frequently At least the name appears in the call Use global variables even less frequently Copyright © Curt Hill

94 When to use reference parameters
These are best used when more than one output from the function to the caller is needed Also use when a variable may not be copied Often used with void functions Since there is no return value the programmer expects that one or more of the parameters is a reference parameter Copyright © Curt Hill

95 What kind of variable cannot be copied?
fstreams cannot be copied ifstreams, ofstreams including cin and cout Why? A file is a peculiar data structure It has pointers to and from the operating system Copyright © Curt Hill

96 Copyright © 2006-2016 - Curt Hill
File Picture ifstream inf(“data.dat”); Program side Operating System side inf data.dat OS data Copyright © Curt Hill

97 Copyright © 2006-2016 - Curt Hill
A Copy results in: ifstream inf(“data.dat”); Program side Operating System side inf data.dat OS data inf2 data.dat Incorrect structure Copyright © Curt Hill

98 Copyright © 2006-2016 - Curt Hill
Streams Again Thus a file may not be assigned Nor may it be a value parameter To attempt to do so results in a syntax error What this really means is that the copy constructor is private Thus not accessible An explanation of that statement must await the description of classes Copyright © Curt Hill

99 When to use global variables
Seldom To do so ruins reusability, one of the goals of using functions Typically only used when a program has a central data structure This data structure is used by most if not all functions Thus is would end up being a parameter in every call Copyright © Curt Hill

100 Copyright © 2006-2016 - Curt Hill
Function invocation Better understanding of what going on will occur if we understand how functions are invoked Most modern computers have a built in stack This stack operates at the machine level Items may be pushed on and popped off Lots of things happen on the stack for a call Copyright © Curt Hill

101 In the calling function
Each parameter is evaluated and pushed onto the stack Value parameters push on a value Reference parameters push on an address Next the call occurs This pushes on the return address One slot is reserved for the function result if there is one Copyright © Curt Hill

102 Copyright © 2006-2016 - Curt Hill
In the called function Value parameters are created and initialized Reference parameters are connected with actual Local variables are created and initialized as needed First statement of function is executed Copyright © Curt Hill

103 Copyright © 2006-2016 - Curt Hill
Upon return Value is copied upon the stack where the calling function may find it The function returns to the caller This destroys all of the parameters and local variables The caller finds the return value and proceeds Copyright © Curt Hill

104 Copyright © 2006-2016 - Curt Hill
Some observations: The stack is the location for both parameters and local variables They are truly created and destroyed when the function starts and ends The local variables might or might not be in the same location the next time a function is called You cannot rely on uninitialized variables Copyright © Curt Hill

105 Dynamic vs static storage allocation
By default C/C++ uses dynamic (aka automatic) By contrast FORTRAN uses static C++ will allow this by prefixing the variable with static static int a = 5; A static variable retains its value between calls Only initialized once Copyright © Curt Hill

106 Copyright © 2006-2016 - Curt Hill
Static A static variable is like a global variable in that it retains its value from one call to another It is like a local variable in that its scope is local to the function The reserved word static also is used for class variables and functions with different meaning Consider the following traces Copyright © Curt Hill

107 Copyright © 2006-2016 - Curt Hill
Non-static Trace(0) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 Copyright © Curt Hill

108 Copyright © 2006-2016 - Curt Hill
Non-static Trace(1) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 Copyright © Curt Hill

109 Copyright © 2006-2016 - Curt Hill
Non-static Trace(2) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 i 5 Copyright © Curt Hill

110 Copyright © 2006-2016 - Curt Hill
Non-static Trace(3) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 i 5 j 2 Copyright © Curt Hill

111 Copyright © 2006-2016 - Curt Hill
Non-static Trace(4) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 i 5 7 j 2 Copyright © Curt Hill

112 Copyright © 2006-2016 - Curt Hill
Non-static Trace(5) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 i 5 7 j 2 5 Copyright © Curt Hill

113 Copyright © 2006-2016 - Curt Hill
Non-static Trace(6) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 i 5 7 j 2 5 returns = 12 Copyright © Curt Hill

114 Copyright © 2006-2016 - Curt Hill
Non-static Trace(7) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 n 12 Copyright © Curt Hill

115 Copyright © 2006-2016 - Curt Hill
Non-static Trace(8) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 n 12 Output 12 Copyright © Curt Hill

116 Copyright © 2006-2016 - Curt Hill
Non-static Trace(9) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 n 12 Copyright © Curt Hill

117 Copyright © 2006-2016 - Curt Hill
Non-static Trace(10) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 i 5 Copyright © Curt Hill

118 Copyright © 2006-2016 - Curt Hill
Non-static Trace(11) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 i 5 j 2 Copyright © Curt Hill

119 Copyright © 2006-2016 - Curt Hill
Non-static Trace(12) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 i 5 7 j 2 Copyright © Curt Hill

120 Copyright © 2006-2016 - Curt Hill
Non-static Trace(13) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 i 5 7 j 2 5 Copyright © Curt Hill

121 Copyright © 2006-2016 - Curt Hill
Non-static Trace(14) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 i 5 7 j 2 5 returns = 12 Copyright © Curt Hill

122 Copyright © 2006-2016 - Curt Hill
Non-static Trace(15) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 n 12 Copyright © Curt Hill

123 Copyright © 2006-2016 - Curt Hill
Non-static Trace(16) int func(int i){ int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main m 5 n 12 Output 12 again Copyright © Curt Hill

124 Copyright © 2006-2016 - Curt Hill
Notes The second function call was exactly like the first Every variable had the same value at the beginning so that is what we expect Now we try it again Except make the local static Copyright © Curt Hill

125 Copyright © 2006-2016 - Curt Hill
Static Trace(0) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); func j 2 Copyright © Curt Hill

126 Copyright © 2006-2016 - Curt Hill
Static Trace(1) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 Copyright © Curt Hill

127 Copyright © 2006-2016 - Curt Hill
Static Trace(2) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 Copyright © Curt Hill

128 Copyright © 2006-2016 - Curt Hill
Static Trace(3) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 i 5 Copyright © Curt Hill

129 Copyright © 2006-2016 - Curt Hill
Static Trace(4) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 i 5 7 Copyright © Curt Hill

130 Copyright © 2006-2016 - Curt Hill
Static Trace(5) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 5 i 5 7 Copyright © Curt Hill

131 Copyright © 2006-2016 - Curt Hill
Static Trace(6) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 j 2 5 i 5 7 returns = 12 Copyright © Curt Hill

132 Copyright © 2006-2016 - Curt Hill
Static Trace(7) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 Copyright © Curt Hill

133 Copyright © 2006-2016 - Curt Hill
Static Trace(8) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 Output 12 Copyright © Curt Hill

134 Copyright © 2006-2016 - Curt Hill
Static Trace(9) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 Copyright © Curt Hill

135 Copyright © 2006-2016 - Curt Hill
Static Trace(10) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 Copyright © Curt Hill

136 Copyright © 2006-2016 - Curt Hill
Static Trace(11) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 i 5 Copyright © Curt Hill

137 Copyright © 2006-2016 - Curt Hill
Static Trace(12) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 i 5 10 Copyright © Curt Hill

138 Copyright © 2006-2016 - Curt Hill
Static Trace(13) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 10 i 5 10 Copyright © Curt Hill

139 Copyright © 2006-2016 - Curt Hill
Static Trace(14) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 j 2 5 10 i 5 10 returns = 20 Copyright © Curt Hill

140 Copyright © 2006-2016 - Curt Hill
Static Trace(15) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 20 j 2 5 10 Copyright © Curt Hill

141 Copyright © 2006-2016 - Curt Hill
Static Trace(16) int func(int i){ static int j = 2; i += j; j += i/2; return i+j; } int main(){ int m = 5; int n = func(m); cout << n << "\n"; n = func(m); main func m 5 n 12 20 j 2 5 10 Output 20 Copyright © Curt Hill

142 Copyright © 2006-2016 - Curt Hill
Last Thought Seldom need static variables in functions We often need static variables and methods in classes Copyright © Curt Hill

143 Copyright © 2006-2016 - Curt Hill
Some more questions Can a function call another function? Sure Can a function call itself? Can a function access any variable in the main function, its caller, functions it calls? Only those passed as arguments. Can a function be passed as a parameter to another function? Yes Copyright © Curt Hill

144 Copyright © 2006-2016 - Curt Hill
Recursion A function calling itself is called a recursive function Recursion is the generalization of looping Recursion is mainly considered in the subsequent course However, here is an example Copyright © Curt Hill

145 Copyright © 2006-2016 - Curt Hill
Factorial Again int facti(int n) { int fact = 1; for(int i = 2; i<=n; i++) fact *= i; return fact; } int factr(int n) { if(n < 2) return 1; return n*factr(n-1); Copyright © Curt Hill

146 Copyright © 2006-2016 - Curt Hill
Finally Lots of material in this presentation Not all of it is needed for last programs Understanding the difference between the two parameter passage mechanisms, value and reference, is very important Copyright © Curt Hill


Download ppt "Passing information to and from a function"

Similar presentations


Ads by Google