Tutorial Study Image

C++ Function Arguments - Call by value and Call by reference


August 31, 2022, Learn eTutorial
1291

In this C ++ tutorial, you will learn everything about the two different ways of passing arguments to function (call by value & call by reference) and how they are useful and different.

Function arguments

Function arguments in C language are the set of variables used when calling a function. Usually, the arguments take the input values and pass them to their corresponding parameters in the function definition.   There are generally two ways through which arguments can be passed into the function: 

  • Call by value 
  • Call by reference 

Before moving to the two methods let's acquaint with two other important terms used while passing arguments. They are :

  • Actual parameters  - the arguments used in the function call 
  • Formal Parameters - the parameters used in the function definition.

Formal parameters are used when we are defining a function. Whereas actual parameters come into play when the function is called for execution. So formal parameters set the rules and actual ones put the values in it to produce the result. To make it clear see the below visualization:

Function call in C

A function call in C++

Call by value

With this technique, an argument's actual value is copied into the function's formal parameter. Changes made to the parameter inside the function in this instance have no impact on the argument.

When giving arguments to a function, the call-by-value method copies the argument's real value into the formal parameter. Changes made to the parameter inside the function in this instance have no impact on the argument.

Call by value is the default method of passing parameters in C++. This generally indicates that code inside a function cannot change the arguments passed to the function when it is called. Take a look at the definition of the swap() function.


// function definition to swap the values.
void swap(int x, int y) {
   int temp;

   temp = x; /* save the value of x */
   x = y;    /* put y into x */
   y = temp; /* put x into y */
  
   return;
}
 

Let us now invoke the function swap() by passing the actual values, as seen in the following example.


#include <iostream>
using namespace std;
 
// function declaration
void swap(int x, int y);
 
int main () {
   // local variable declaration:
   int a = 1000;
   int b = 2000;
 
   cout << "Before swap, value of a :" << a << endl;
   cout << "Before swap, value of b :" << b << endl;
 
   // calling a function to swap the values.
   swap(a, b);
 
   cout << "After swap, value of a :" << a << endl;
   cout << "After swap, value of b :" << b << endl;
 
   return 0;
}

When the given code is combined in a file, compiled, and executed, the following result is obtained:

  1. and  are formal parameters whose duty is to define the formula.
  2.  On the other hand, a and b will be considered as actual parameters. Their job is to pass the value 1000 and 2000 to the  formal parameters
Before swap, value of a :1000
Before swap, value of b :2000
After swap, value of a :1000
After swap, value of b :2000

This demonstrates that the values have not changed despite the fact that they have been altered within the function.

Call by Pointer :

With this technique, an argument's address is copied into the formal parameter. The address is utilized within the function to obtain the actual argument used during the call. This implies that modifications to the parameter have an impact on the argument.

The address of an argument is copied into the formal parameter when calling a function using the pointer method of passing arguments. The address is utilized within the function to obtain the actual argument used during the call. This implies that adjustments to the parameter will have an impact on the passed argument.

 Argument pointers are supplied to functions in the same manner as other values in order to transmit values by the pointer. As a result, the function parameters must be declared as pointer types, as in the following function swap(), which swaps the values of the two integer variables pointed to by its arguments.


// function definition to swap the values.
void swap(int *x, int *y) {
   int temp;
   temp = *x; /* save the value at address x */
   *x = *y; /* put y into x */
   *y = temp; /* put x into y */
  
   return;
}
 

Let us now invoke the function swap() by passing by pointers , as seen in the following example.


#include <iostream>
using namespace std;
 
// function declaration
void swap(int *x, int *y);

int main () {
   // local variable declaration:
   int a = 1000;
   int b = 2000;
 
   cout << "Before swap, value of a :" << a << endl;
   cout << "Before swap, value of b :" << b << endl;

   /* calling a function to swap the values.
      * &a indicates pointer to a ie. address of variable a and 
      * &b indicates pointer to b ie. address of variable b.
   */
   swap(&a, &b);

   cout << "After swap, value of a :" << a << endl;
   cout << "After swap, value of b :" << b << endl;
 
   return 0;
}

Before swap, value of a :1000
Before swap, value of b :2000
After swap, value of a :1000
After swap, value of b :2000

Call by Reference :

This method replicates an argument's reference into the formal parameter. The reference is utilized inside the function to obtain the actual parameter used in the call. This implies that modifications to the parameter have an impact on the argument.

To pass the value by reference, the argument reference is passed to the functions just like any other value. As a result, the function parameters must be declared as reference types, as in the following function swap(), which swaps the values of the two integer variables pointed to by its arguments.


// function definition to swap the values.
void swap(int &x, int &y) {
   int temp;
   temp = x; /* save the value at address x */
   x = y;    /* put y into x */
   y = temp; /* put x into y */
  
   return;
}
 

Let us now invoke the function swap() by passing by reference, as seen in the following example.


#include <iostream>
using namespace std;
 
// function declaration
void swap(int &x, int &y);

int main () {
   // local variable declaration:
   int a = 1000;
   int b = 2000;
 
   cout << "Before swap, value of a :" << a << endl;
   cout << "Before swap, value of b :" << b << endl;

   /* calling a function to swap the values using variable reference.*/
   swap(a, b);

   cout << "After swap, value of a :" << a << endl;
   cout << "After swap, value of b :" << b << endl;
 
   return 0;
}


Before swap, value of a :1000
Before swap, value of b :2000
After swap, value of a :2000
After swap, value of b :1000