Reference Variables The symbol has a few different

Reference Variables § The symbol “&” has a few different purposes depending on where it occurs in code. § When it appears in front of a variable name, it is the address operator, i. e. , it returns the address of the variable in memory. int x; int* ptr = &x;

Lecture No. 17 Data Structure Dr. Sohail Aslam

Reference Variables § The symbol “&’ can also appear after a type in a function signature: § For example, insert and remove from the Binary. Search. Tree class. void insert( const EType& x ); void remove( const EType& x );

Reference Variables § Or, in case we designed the Binary. Search. Tree class to hold integers only, i. e. , no templates void insert( const int& x ); void remove( const int& x );

Reference Variables § The “&” indicates a parameter that is a reference variable. § Consider the following three different functions:

Reference Variables // example 1 int. Minus 1( int old. Val) { old. Val = old. Val – 1; return old. Val; }

Reference Variables // example 2 int. Minus 2( int* old. Val) { *old. Val = *old. Val – 2; return *old. Val; }

Reference Variables // example 3 int. Minus 3( int& old. Val) { old. Val = old. Val – 3; return old. Val; }

Reference Variables The caller function: calling int. Minus 1 void caller() { int my. Int = 31; int ret. Val; ret. Val = int. Minus 1( my. Int ); cout << my. Int << ret. Val; }

Memory Organization Process 1 (browser) Code Process 3 (word) Static data Process 4 (ourtest. exe) Stack Process 2 (dev-c++) Windows OS Heap

Reference Variables § Call stack layout Parameters(caller) Local variables(caller) Return address(caller) Parameters(int. Minus 1) Local variables(int. Minus 1) sp Return address(int. Minus 1) Stack grows downwards

Reference Variables Call stack layout when int. Minus 1 is called: 1072 31 my. Int 1068 ? ret. Val calling function “caller” caller’s other stuff 1060 31 old. Val 1056 1052 sp stack grows downwards called function “int. Minus 1”

Reference Variables § How are my. Int and old. Val related? § Passing my. Int to the function int. Minus 1 results in a copy of my. Int to be placed in parameter old. Val in the call stack. § Alterations are done to the copy of “ 31” (stored in old. Val) and not the original my. Int.

Reference Variables § The original my. Int remains unchanged. § For this reason, this technique of passing parameters is called pass by value. § Alterations are done to the copy of “ 31” (stored in old. Val) and not the original my. Int.

Reference Variables Call stack layout after subtraction in int. Minus 1: 1072 31 my. Int 1068 ? ret. Val calling function “caller” caller’s other stuff 1060 31 30 old. Val 1056 1052 sp stack grows downwards called function “int. Minus 1”

Reference Variables Call stack layout after return from int. Minus 1: 1072 31 my. Int 1068 30 ret. Val caller’s other stuff sp stack grows downwards calling function “caller”

Reference Variables § We could have called int. Minus 1 as void caller() { int ret. Val; ret. Val = int. Minus 1( 31 ); // literal cout << my. Int << ret. Val; } § Because it is the value that is passed. We can always pass a literal or even an expression in call-by-value.

Reference Variables § If the programmer wanted to actually change a variable’s value from within a function, one way would be to send a pointer: void caller() { int ret. Val; int my. Int = 31; ret. Val = int. Minus 2( &my. Int ); cout << my. Int << ret. Val; } § Call this call-by-pointer.

Reference Variables Call stack layout when int. Minus 2 is called: 1072 31 my. Int 1068 ? ret. Val calling function “caller” caller’s other stuff 1060 1072 old. Val 1056 1052 sp stack grows downwards called function “int. Minus 2”

Reference Variables Call stack layout after *old. Val = *old. Val – 2; 1072 1068 31 29 my. Int ? ret. Val calling function “caller” caller’s other stuff 1060 1072 old. Val 1056 1052 sp stack grows downwards called function “int. Minus 2”

Reference Variables Call stack layout after return from int. Minus 2. 1072 31 29 my. Int 1068 29 ret. Val caller’s other stuff sp stack grows downwards calling function “caller”

Reference Variables § Suppose we want a function to change an object. § But we don’t want to send the function a copy. The object could be large and copying it costs time. § We don’t want to use pointers because of the messy syntax.

Reference Variables § The answer: call-by-reference (or passby-reference): void caller() { int ret. Val; int my. Int = 31; ret. Val = int. Minus 3( my. Int ); cout << my. Int << ret. Val; }

Reference Variables § The & after int means that old. Val is an integer reference variable. // example 3 int. Minus 3( int& old. Val) { old. Val = old. Val – 3; return old. Val; }

Reference Variables § So what is a reference variable? § The idea is: the integer object my. Int is used exactly as it exists in the caller. The function simply reaches it through a different name, old. Val. § The function int. Minus 3 cannot use the name my. Int because it is in the caller’s scope. § But both variable names refer to the same object (same memory cell).

Reference Variables Call stack layout when int. Minus 3 is called: 1072 31 my. Int 1068 ? ret. Val calling function “caller” caller’s other stuff 1060 old. Val 1056 1052 sp stack grows downwards called function “int. Minus 3”

Reference Variables Call stack layout when int. Minus 3 is called: old. Val 1072 31 my. Int 1068 ? ret. Val caller’s other stuff calling function “caller” 1060 1056 1052 sp stack grows downwards called function “int. Minus 3”

Reference Variables Call stack layout after old. Val = old. Val - 3: old. Val 1072 1068 31 28 my. Int ? ret. Val caller’s other stuff calling function “caller” 1060 1056 1052 sp stack grows downwards called function “int. Minus 3”

Reference Variables Call stack layout after return from int. Minus 3: 1072 31 28 my. Int 1068 28 ret. Val caller’s other stuff sp stack grows downwards calling function “caller”

Reference Variables § The compiler may actually implement callby-reference using pointers as we did in example 2. § The obtaining of address and dereferencing would be done behind the scene. § We should think in terms of the “renaming” abstraction.
- Slides: 30