Download presentation
Presentation is loading. Please wait.
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.