In every high-level programming language, there is support for user-defined functions, and functions are used to perform a specific task. The function provides modularity to the program and increases the concept of reusability of code, instead of witting similar code, again and again, we can define a function that can perform that task and just invoke that function whenever we need.

Call by Value vs Call by Reference

In a programming language, we can invoke the function in two ways:

  • Call by Value.
  • Call by Reference.

When we call a function, we can pass arguments along with it if the function accepts any argument. The arguments we pass along the function during the function calling those arguments known as actual arguments and the user-defined function accept that actual argument as a formal argument.

The Call by value method and call by reference method more likely show how the formal parameter going to accept the values from the actual parameter.

Here in this article, we will compare the two ways of invoking or calling a function, call by value method and call by the reference method.

Example in C++:

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
int func(for_arg_1, for_arg_2)   // here func arguments are formal arguments
                { return for_arg_1+for_arg_2;
                }
void main()
{
int act_arg_1=1, act_arg_2=2;
clrscr();
cout<<func(act_arg_1,act_arg_2);  //here func arguments are actual arguments
 getch();
}

Output:

3 

Call by Value Method

In Call by value method the formal arguments accept the copies of the actual arguments and the function perform operations on the formal argument or copies of the actual arguments. That’s why all the changes make on the formal argument does not have any effect on the actual argument.

In this method when we call the function the function first creates the copies of the actual arguments in the different memory location and then send that copied arguments to the formal arguments. Here if the function makes any changes in the formal arguments the changes do not show any adverse effect on the actual arguments.

Example in C++:

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
int func(for_arg_1, for_arg_2)
                { 
                for_arg_1=45;
                for_arg_2=70;
                cout<<"\nThe formal argument 1 has been changed to: "<< for_arg_1;
                cout<<"\nThe formal argument 2 has been changed to: "<<for_arg_2<<endl;
                 }
void main()
{
int act_arg_1=1, act_arg_2=2;
clrscr();
cout<<"Before we call the function the value of both actual arguments is:";
cout<<"\nThe value of actual argument 1 is: " <<act_arg_1;
cout<<"\nThe value of actual argument 2 is: " <<act_arg_2;
cout<<"\n\n\n---------------------Using Call by Value method-------------------" ;
func(act_arg_1,act_arg_2);
cout<<"-------------------------------------------------------------------" ;

cout<<"\n\n\nAfter calling the function the values of actual arguments is:\n ";
cout<<"\nThe value of actual argument 1 is: "<<act_arg_1;
cout<<"\nThe value of actual argument 2 is: "<<act_arg_2;
 getch();
}

Output:

Before we call the function the value of both actual arguments is:

The value of actual argument 1 is: 1
The value of actual argument 2 is: 2

---------------------Using Call by Value method-------------------

The formal argument 1 has been changed to: 45
The formal argument 2 has been changed to: 70

-------------------------------------------------------------------

After calling the function the values of actual arguments is:

The value of actual argument 1 is: 1
The value of actual argument 2 is: 2

Call by Reference Method

In Call by Reference method, the formal parameter accepts the address of the actual parameter and here we use pointers to grab the value associated with those addresses. Hence here we are using the same address for the formal and actual arguments so if there is any value change occur in the formal parameter that will also affect the actual argument values.

Hence in this method addresses are the same for both formal and actual arguments the conflict of value changing can be clearly seen.

Example in C++:

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
int func(int *for_arg_1, int *for_arg_2)
                { *for_arg_1=45;
                *for_arg_2=70;
                cout<<"\nThe formal argument 1 has been changeed to: "<< *for_arg_1;
                cout<<"\nThe formal argument 2 value has been changed to: "<<*for_arg_2<<endl;
                 }
void main()
{
int act_arg_1=1, act_arg_2=2;
clrscr();

cout<<"Before we call the function the value of both actual arguments is:";
cout<<"\nThe value of actual argument 1 is: " <<act_arg_1;
cout<<"\nThe value of actual argument 2 is: " <<act_arg_2;

cout<<"\n\n\n---------------------Using Call by Reference method-------------------" ;
func(&act_arg_1,&act_arg_2);
cout<<"-------------------------------------------------------------------" ;


cout<<"\n\n\nAfter calling the function the values of actual argumetns is:\n ";
cout<<"\nThe value of actual argument 1 is: "<<act_arg_1;
cout<<"\nThe value of actual argument 2 is: "<<act_arg_2;
 getch();
}

Output:

Before we call the function the value of both actual arguments is:

The value of actual argument 1 is: 1
The value of actual argument 2 is: 2

---------------------Using Call by Reference method-------------------

The formal argument 1 has been changed to: 45
The formal argument 2 has been changed to: 70

-------------------------------------------------------------------

After calling the function the values of actual arguments is:

The value of actual argument 1 is: 40
The value of actual argument 2 is: 70

Call by value vs Call by reference: Head to Head Comparison

Call by Value Call by Reference
It sends a copy of the actual parameter to the formal parameter It sends the address of actual parameters to the formal parameters
All the change occur in copy does not have any adverse effect on actual parameters All the changes have a direct effect on the actual parameters
When we call the function we just pass the value of actual parameter e.g. function(actualparameter1 , actualparameter2 ) When we call the function we send the address of the actual parameters e.g.

function(&actualparameter1 , &actualparameter2)

The function receives the calling as copies

e.g.

function(formalparametes1, formalparameters2)

The function receives the calling as addresses

e.g.

function(*formalparametes1, *formalparameters2)

We pass primitive type in Call by value method We pass objects implicitly in Call by reference method

Advantages:

Call by Value Call by Reference
  • It does not change the value of the actual parameter which keeps code simple
  • Does not matter how many times the function gets called there would be no effect on actual arguments
  • Sometimes when we want to change the value of the actual parameter along with formal arguments, we can consider this method
  • Unlike call by value method, it does not create any copies which make it more memory efficient

Disadvantages

Call by Value Call by Reference
  • For every actual parameter, it creates copy which occupies more memory space.
  • We have to pass the argument as a variable
  • The use of the address in function could make program complex
  • It can manipulate the actual parameters too, which could create a problem.

Leave a Reply

Your email address will not be published. Required fields are marked *