Introduction to Passing by Value, and by Reference

Passing by value is situation where the calling function sends a copy of a specific value or of the value of its variable as an argument to the called functions. Actually, all along we have been passing by value. The phrase “passing” itself referrers to parameters used and sent by the calling functions as arguments to the called function. As we indicated, the called function uses the arguments to execute its statements and then returns the value to its caller. For example in the program below function main () passes by value to function myAge().


#include<iostream> using namespace std;
 int myAge( int age)
{ int Myage=age;
 return Myage;
}//end myAge()

 int main() //start main() 
{ int Years=34; 
cout< < "I am "< <myAge(Years)< <” years old “< <endl; //Main uses the value of its variable to passed it to myAge() return 0; } //end main()
I am 34 years old

The advantage of passing by value is that a copy of the value being sent is made and passed to the called function. The original value itself is not sent and as such it remains intact as it is not subject to any modifications that the called function might make. Let us examine the concept of passing by value in the example below

#include<iostream>
 using namespace std;
 int myAge( int PrevAge)
{ return PrevAge+=1;
 }//end myAge()

 int main() //start main()
{ int Years207=34;
 cout<< "In 2007, I was "< <Years207<<" years old "<<endl; // variable Years207 is used directly to print my age
 cout<< "After one year in 2008, I became "<<myAge(Years207) <<" years old "<<endl; // myAge uses a copy of the value of Years207 passed to it by value to calculate for the age after one year.
 cout<< "My age in 2007, still remains "<<Years207<<" years old. It was not changed by myAge() "<<endl; // The value of variable Years207 is still intact
 return 0; }
 In 2007 I was 34 years old

After  one year in 2008, i became 35 years old.

My age in 2007 still remains 34 years. It was not changed by by myAge()  

The expression PrevAge+=1; in c++ performs the same function as PrevAge+1; so if PrevAge=34, return PrevAge+=1; is the same as return PrevAge+1; or 34+1. Note that because main passes by value when myAge returns, it has not changed the value of Years207.

So, passing by value prevents accidental modification to a value if in case it is to be reused at a future point in the program. However if a large data is to be passed by value, copying it can consume considerable amount of memory and execution time.

Reference Parameters and Passing by Reference

Passing by reference refers to a situation where the called function is provided the ability to access directly and modify the data or value passed to it by the caller. The technique is good for performance reasons because it minimizes execution time as there is no need to copy passed values. However because the value is accessed directly, there is a risk that the called function can inadvertently modify it leading to unwanted results if the value is to be reused at a future point in the program. There is however a way out of this problem (to be discussed later), it is possible to pass by reference but still protect the callers data from by corrupted. A reference parameter is an alias used in the parameter list of a function as code-name or place holder for the corresponding argument in the function caller. Use of a reference parameter, enables the function to directly access and modify the data of its caller. We place ampersand (&) sign before the name or identifier to indicate that it is a reference parameter. The name of the reference parameter is used in the function body without the ampersand (&) sign. In other words, once reference parameters have been correctly written, the rest of the function is written as usual. Let us pass by reference the same example above in which we passed by value.

#include<iostream>
 using namespace std;
 int myAge( int &PrevAge)
{ return PrevAge+=1;
 }//end myAge()

 int main() //start main()
 { int Years207=34; 
 cout<< "In 2007, I was "<<Years207<<" years old "<<endl; // variable Years207 is used directly to print my age 
 cout<< "After one year in 2008, I became "<<myAge(Years207) <<" years old "<<endl; // myAge uses a copy of the value of Years207 passed to it by value to calculate for the age after one year. 
cout<< "Oh,My age in 2007, has been changed it says I was "<<Years207<<" years old. "<<endl; // The value of variable Years207 is changed. This can be dangerous, for example ones age in a particular year never changes with additional years
return 0; }
In 2007, I was 34 years old

After one year in 2008, I became 35 years old

Oh,My age in 2007, has been changed it says I was 35 years old.

Apart from the ampersand (&) in the parameter list, the above example is exactly the same as the example previous one where we passed by value, but the results are not the same. This is because main() allowed myAge() to access and modify the value of variable Years207. Like we said even if, this technique enhances performance it can at times be dangerous. For example, one age in a particular will always be the same, but in our program it has been changed. If you want do not want to modify the value, place the constant key word written as const before the type specifier in the parameter declaration. This way, the function is enabled to directly access the value but not to modify it.

Alias References in a function body

Aliases can also be used in the declaration of a variable within a function. If references as aliases are used, the variable in question must be initialized at its declaration. The declaration is similar to that of parameters. Once declared the alias name can be used normally. For example

#include<iostream>
using namespace std;

int myAge(int PrevAge)
{ static int &currAge= PrevAge;
return currAge;
}//end myAge()

int main() //start main()

{ int Years=34; cout<< " My age is " <<myAge(Years) << " years old"<<endl;
return 0; }
 My age is 34 years old

We have introduced a new word called static in the above program. The static keyword specifies that the variable is allocated when the program begins and deallocated when the program ends. We used the key word static because the program returns a reference to the variable declared in the called function. If we had not declared it as such, the variable would be considered automatic meaning that it would not exist as soon as its function terminates. This leaves the referenced variable with a state of a dangling reference (undefined variable) and in such a situation, the behavior of the program in is unpredictable. A static variable keeps its value and is not destroyed even after it goes out of scope. Because an alias is just another name of for the original variable, a reference argument unless it is a reference to a constant, must always be a left value (lvalue)).
Note in declarations like;

int a;
int b=a;

a is considered a right value while b is considered a left value of the operator aquals (=). So a reference declared as an alias should never be on side of a, unless it is a reference to a constant.
PREV: Introduction to empty parameter list


NEXT: Introduction to default arguments and functions

No comments:

Post a Comment