Call by value and Call by reference explained with simple example

This is one of very basic concept of C/C++ programming language which is kind of building block of any program or software. Often unknowingly programmers make mistakes in these concept and introduce bugs in softwares 🙂

Basically in C, there are two ways to pass data to a function:

1) Call by value: In this case only value will be passed to the function and the function will store this value in its own local variable. This function will work on this copied data (not original) and set some new value based on some operations. But since this function is working on copied data and not on original data, hence it can’t update the original data in this method.

2) Call by reference: In this case address of the data is passed to the function and function will define a pointer to access this memory location. Since, this function has direct access to the original data memory location, hence it can update the value of original data. Thus, this method is called Call/Pass by reference as we are passing reference of the memory instead of direct data.

Now let’s have a look on following sample program to clear things.

// This program will provide examples of call by value and call by reference

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

// Call by value
void fun(int x)
{
    printf("Inside fun(int x) function value received %d, \n", x);
    x = 10;
}

// Call by reference
void fun1(int* x)
{
    if (x)
    {
        printf("Inside fun(int* x) function value received %d, \n", *x);
        *x = 20;
        return;
    }
    else
    {
        x = (int *) malloc(sizeof(int));
        *x = 25;
        printf("Inside func(int *x) NULL pointer received \n");
    }
}

// Call by reference for pointers
void fun2(int **x)
{
    (*x) = (int *)malloc(sizeof(int));
    *(*x) = 30;
    printf("Inside fun(int** x) function value set %d \n", *(*x));
}

int main()
{
     int a = 5;
     int * p = NULL;

     int *p1 = &amp;a;
     printf("Before calling fun(int x) value is %d \n", a);
     fun(a);
     printf("After calling fun(int x) value is %d \n", a);

     printf("Before calling fun(int* x) value is %d \n", a);
     fun1(&amp;a);
     printf("After calling fun(int* x) value is %d \n", a);
     
     fun1(p);
     if(p)
     {
         printf("This should not come \n");
     }
     else
     {
         printf("Pointer not initialized \n");
     }

     a = 50;
     fun1(p1);
     printf("value is %d \n", *p1);

     printf("Before calling fun(int** x)  \n" );
     fun2(&amp;p);
     printf("After calling fun(int** x) value is %d \n", *p);
     
}

Here the call by value procedure is being used for “fun” function as its argument is of “int” data type.

Function “fun1” is actually providing both call by value and call by reference procedure as shown in main function. Note that using pointers doesn’t always guarantee call by reference (see the pointer “p” and “p1” behavior while passing as argument in function “fun1”).

Now if we want to pass pointer as a reference to a function then that is showed in function “fun2”

Output:

Before calling fun(int x) value is 5 
Inside fun(int x) function value received 5, 
After calling fun(int x) value is 5 
Before calling fun(int* x) value is 5 
Inside fun(int* x) function value received 5, 
After calling fun(int* x) value is 20 
Inside func(int *x) NULL pointer received 
Pointer not initialized 
Inside fun(int* x) function value received 50, 
value is 20 
Before calling fun(int** x)  
Inside fun(int** x) function value set 30 
After calling fun(int** x) value is 30

Interesting Fact: Programming language C doesn’t support function overloading.

Interview questions related to this:
1) Difference between call by value and call by reference.

Leave a Reply

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