Download presentation
Presentation is loading. Please wait.
Published byLawrence Griffin Modified over 9 years ago
1
Functions Illustration of: Pass by value, reference Scope Allocation Reference: See your CS115/215 textbook
2
float CircleArea (float r) { const float Pi = 3.1415; return Pi * r * r; } Function Definition Function body Return statement Local object definition Formal parameter Return type Function name
3
Function Prototype float CircleArea (float r); Function prototype (or actual function) must appear in file before the function is called
4
Function Invocation cout << CircleArea(MyRadius) << endl; To process the invocation, the function that contains the insertion statement is suspended and CircleArea() does its job. The insertion statement is then completed using the value supplied by CircleArea(). Actual parameter
5
// Include statements first #include using namespace std; // Using statement float CircleArea(float r); // function prototypes // main(): manage circle computation int main() { // Always a main function cout << "Enter radius: "; float MyRadius; cin >> MyRadius; float Area = CircleArea(MyRadius); cout << "Circle has area " << Area; return 0; } // CircleArea(): compute area of radius r circle float CircleArea(float r) { const float Pi = 3.1415; return Pi * r * r; }
6
Two Characteristics of Variables Scope – where can you reference the variable name Allocation – where is the variable kept in storage
7
Variable Scope Global – can be referenced within any function in any source file of the program Static – can be referenced within any function in the source file where it is declared Function – can be referenced within a function Block – can be referenced within a block - set of curly braces {}
8
Global Scope Variables defined outside of functions are global A global variable can be used by any function in the file that is defined after the global variable It is best to avoid programmer-defined global variables Exceptions tend to be important constants Globals with appropriate declarations can even be used in other program files Local variables can reuse a global variable's name scope resolution operator :: can provide access to global even if name reuse has occurred
9
Global Example float pi = 3.14159; // usual use of global int i = 1; // example to illustrate scope resolution int main() { cout << i << endl; // print 1 { char i = 'a'; cout << i << endl; // print a ::i = 2; cout << i << endl; // print a cout << ::i << endl; // print 2 } cout << i << endl; // print 2 return 0; }
10
Use of Global in Other Source Files File 1: float pi = 3.14159; // pi can be used (and modified) in file1 File 2: extern float pi; // pi can be used (and modified) in file 2 // pi cannot be initialized (except in file 1) There is only one global variable pi. Code in either file can access or change it. A global variable can be initialized in only one file. All other files that need to access it use the extern keyword.
11
Static Scope Similar to global scope (declared outside of any function) but: Use static keyword Can only be referenced in this file (never any other file) For example: static float pi = 3.14159;
12
Function Scope Parameters passed to a function and any variables declared at the start of the function have function scope Function scope means that they can be referenced anywhere in the function (including all blocks in the function)
13
Blocks can be put anywhere a statement can be put Blocks within blocks are nested blocks Typical use of blocks are for while, for, if clauses A variable is known only within the block in which it is defined and in nested blocks of that block Block Scope A block is a list of statements within curly braces
14
Block Scope Example void f(int a) { // a has function scope int i = 1; // this i has function scope cout << i << endl; // print 1 { int j = 10; // j has block scope cout << i << j << endl; // print 1 10 int i = 2; // this i has block scope cout << i << endl; // print 2 } cout << i << endl; // print 1 cout << j << endl; // illegal }
15
For, While, If Blocks For variables only used within a while, for, or if, clause, use block scope for (int i = 0; i < MAX; i++) { …… } A for block iterator is a typical example
16
Name Reuse If a nested block defines an object with the same name as enclosing block, the new definition is in effect in the nested block Each scope area can have a variable of the same name: Global, static (one variable only) Function (each function) Block (each block)
17
However, Don’t Do This At Home void f() { float i = 3.14159; // function scope i { int i = 1; // block 1 scope i cout << i << endl; // print 1 { cout << i << endl; // print 1 char i = 'a'; // block 2 scope i cout << i << endl; // print a } cout << i << endl; // print 1 } cout << i << endl; // print 3.14159 }
18
Calling a function to swap variables // Will Swap swap Number1, Number 2?????? int main() { int Number1 = PromptAndRead(); int Number2 = PromptAndRead(); if (Number1 > Number2) { Swap(Number1, Number2); // Swap? } cout << "The numbers in sorted order:" << Number1 << ", " << Number2 << endl; return 0; }
19
Will Swap swap? IF parameters passed by value: NO If parameters passes by reference: YES
20
Using Pass by Value void Swap(int a, int b) { int Temp = a; a = b; b = Temp; return; }
21
Doesn’t change the caller’s variables!
22
Pass by Value Rules Formal parameter is created on function invocation and it is initialized with the value of the actual parameter Changes to formal parameter do not affect actual parameter Reference to a formal parameter produces the value for it in the current activation record New activation record for every function invocation Formal parameter name is only known within its function Formal parameter ceases to exist when the function completes Activation record memory is automatically released at function completion
23
Pass by Reference If the formal argument declaration is a reference parameter then Formal parameter becomes an alias for the actual parameter Changes to the formal parameter change the actual parameter Function definition determines whether a parameter’s passing style is by value or by reference Reference parameter form ptype i &pname i void Swap(int &a, int &b)
24
Same Call to Swap But… void Swap(int &a, int &b); int main() { int Number1 = PromptAndRead(); int Number2 = PromptAndRead(); if (Number1 > Number2) { Swap(Number1, Number2); } cout << "The numbers in sorted order: " << Number1 << ", " << Number2 << endl; return 0; }
25
Swap defined as Pass by Reference void Swap(int &a, int &b) { int Temp = a; a = b; b = Temp; return; } Return statement not necessary for void functions Passed by reference -- in an invocation the actual parameter is given rather than a copy
26
Correct Pass By Reference int i = 5; int j = 6; Swap(i, j); int a = 7; int b = 8; Swap(b, a); void Swap(int &a, int &b) { int Temp = a; a = b; b = Temp; return; }
27
C Style Reference Parameters void IndirectSwap(char *Ptr1,char *Ptr2){ char c = *Ptr1; *Ptr1 = *Ptr2; *Ptr2 = c; } int main() { char a = 'y'; char b = 'n'; IndirectSwap(&a, &b); cout << a << b << endl; return 0; }
28
Pass Address By Reference int i = 0; int* ptrj = &i; FuncA(ptrj); // i is now 5 // ptrj is now NULL void FuncA(int* &a) { // Caller’s variables // can be changed *a = 5; a = NULL; return; }
29
Pass Address By Value int i = 0; int* ptrj = &i; FuncA(ptrj); // i is now 5 // ptrj is still &i void FuncA(int* a) { // Cannot change ptrj // Can change i *a = 5; a = NULL; return; }
30
Passing Data/Addresses Variables can be data or the addresses of data Both can be passed by value or reference Passing a variable by value: the called function cannot change the caller’s variable Passing a variable by reference: the called function can change the callers variable If an address is passed by value, the called function can change the caller’s data that the address is pointing to, but not the caller’s passed address If an address is passed by reference, the called function can change the caller’s data that the address is pointing to, and the caller’s passed address
31
Arrays are passed by reference The name of the array is its address int myarray1[10], myarray2[10]; ….. copyArray(myarray1, myarray2,arraysize); ….. void copyArray (int array1[], int array2[], int size) { // int* array1, int* array2 works also for (int i = 0; i < size; i++) array1[i] = array2[i]; // Copies caller’s array2 into array1 }
32
Passing Array Elements You can pass individual array elements if needed: printArrayIndex(array1[4]); …. void printArrayIndex (int element) { cout << element; element++; // Does not change caller’s array }
33
Passing a File Stream Function to extract a value from a given stream (opened in the caller) void GetNumber(int &MyNumber, istream &sin) { sin >> MyNumber; return; } Why is the stream a reference parameter? Why is MyNumber a reference parameter?
34
Language Parameter Passing These are the rules for C++ Pass by value, pass by reference are general terms, but… Each language has its own rules You must not assume the language follows C++ rules
35
Allocation: Global and Static Global and static scope variables: Included with program instructions Only one copy referenced by all
36
Allocation: Function and Block Allocated on the stack (activation record) when the function is called Deallocated (stack storage is freed for reuse) when function returns
37
37 Stack Activation Frames the activation record contains the return address for this function call, and also the parameters, and local variables, and space for the function’s return value, if non-void the activation record for a particular function call is popped off the run-time stack when the final closing brace in the function code is reached, or when a return statement is reached in the function code at this time the function’s return value, if non-void, is brought back to the calling block return address for use there
38
38 // A recursive function int Func ( /* in */ int a, /* in */ int b ) // Pre: Assigned(a) && Assigned(b) // Post: Function value == ?? { int result; if ( b == 0 ) // base case result = 0; else if ( b > 0 ) // first general case result = a + Func ( a, b - 1 ) ; // instruction 50 else // second general case result = Func ( - a, - b ) ; // instruction 70 return result; } 38
39
39 FCTVAL ? result ? b 2 a 5 Return Address 100 Run-Time Stack Activation Records x = Func(5, 2); // original call at instruction 100 original call at instruction 100 pushes on this record for Func(5,2)
40
40 FCTVAL ? result ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 record for Func(5,2) call in Func(5,2) code at instruction 50 pushes on this record for Func(5,1) Run-Time Stack Activation Records x = Func(5, 2); // original call at instruction 100
41
41 FCTVAL ? result ? b 0 a 5 Return Address 50 FCTVAL ? result 5+Func(5,0) = ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 record for Func(5,2) record for Func(5,1) call in Func(5,1) code at instruction 50 pushes on this record for Func(5,0) Run-Time Stack Activation Records x = Func(5, 2); // original call at instruction 100
42
42 FCTVAL 0 result 0 b 0 a 5 Return Address 50 FCTVAL ? result 5+Func(5,0) = ? b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100 record for Func(5,0) is popped first with its FCTVAL Run-Time Stack Activation Records x = Func(5, 2); // original call at instruction 100 record for Func(5,2) record for Func(5,1)
43
43 record for Func(5,2) record for Func(5,1) is popped next with its FCTVAL Run-Time Stack Activation Records x = Func(5, 2); // original call at instruction 100 FCTVAL 5 result 5+Func(5,0) = 5+ 0 b 1 a 5 Return Address 50 FCTVAL ? result 5+Func(5,1) = ? b 2 a 5 Return Address 100
44
Static Declaration in a Function To have a variable in a function keep its value, you can declare the variable static Its scope is function (or block) But it is put in the global/static storage with the program Its value is initialized only once (first call) After that it retains its value between calls
45
Function Scope Example To count how many times a function was called: void readFile( …… ) { static int numberOfCalls = 0; numberOfCalls++; …….. cout << “This function has been called “ << numberOfCalls << “ times” << endl; }
46
Dynamic Allocation Use of new operator allocates variable in dynamic storage (or heap) Stays allocated until delete operator is used Can only be accessed via a pointer If you lose access to the pointer, you lose access to the variable
47
Memory Leak Variable allocated in dynamic storage within a function Function returns without deallocation via delete void funca() { float *pi = new float; *pi = 3.14159; ….. return; }
48
Allocation Summary Global, static variables get loaded into storage with program, initialized once (on start of program) Function, block variables get allocated on stack when function accessed, deallocated when function exits Dynamic storage variables allocated with new operator, freed with delete operator, referenced indirectly via pointer
49
Scope Summary Global variables known anywhere in any source file Static variables (declared outside of function) known in any function in their file Function variables known anywhere in the function Block variables known in its block (and nested blocks)
50
Language Rules These are the rules for C++ Each language (for example, Java, Perl) has the concepts of scope and allocation, but… Each language has its own rules You must not assume the language has the same rules as C++
51
Passing an Object Objects can be passed by value or reference If you don’t want the object modified, you can pass by value. This is safer, but execution is slower and the destructor will be called You can pass by reference but use the const keyword for faster execution (and to not call the destructor): void funca(const rational & rationalObject)
52
Pass an Object by Reference If you pass by value, the class destructor is called when the function returns to destroy the passed copy of the object This can lead to unwanted side effects. Your destructor may be doing cleanup operations that you only wanted done when the object is no longer used (for example, a linked list object). Always pass an object by reference. Use the const keyword if you do not want the object modified.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.