top

Search

C Tutorial

.

UpGrad

C Tutorial

Call by Value and Call by Reference in C

The strategy of argument passing in functions plays a critical role in C programming. These strategies primarily encompass two methods: Call by Value and Call by Reference. Proficiency in these concepts ensures optimal code performance, efficiency, and comprehensibility.

Before explicating the distinction between call by value and call by reference in C, let's comprehend their definitions. In the call by value method, the actual parameters' values (variables defined in the calling function) are replicated into the formal parameters (variables declared in the invoked function). Contrastingly, call by reference transmits the address of the variable instead of passing the variable's value.

Difference Between Call by Value and Call by Reference in C

A thorough understanding of the difference between call by value and call by reference in C necessitates a hands-on example of call by value and call by reference in C.

Consider the following piece of code:

#include <stdio.h>

void call_by_value(int x) {
   printf("Inside call_by_value x = %d before adding 20.\n", x);
   x += 20;
   printf("Inside call_by_value x = %d after adding 20.\n", x);
}

void call_by_reference(int *y) {
   printf("Inside call_by_reference y = %d before adding 20.\n", *y);
   *y += 20;
   printf("Inside call_by_reference y = %d after adding 20.\n", *y);
}

int main() {
   int a=30;
   
   call_by_value(a);
   printf("In main a = %d after call_by_value.\n", a);
   
   call_by_reference(&a);
   printf("In main a = %d after call_by_reference.\n", a);

   return 0;
}

In this call by value and call by reference example, we first declare integer a and set it to 30. We then pass a to the call_by_value function. The function adds 20 to x, but this doesn't impact a because x is a copy of a. When we print the value of an after the call to call_by_value, it remains 30.

Next, we pass the address of a to the call_by_reference function. The function adds 20 to the value at address y, which does affect a because y points to a. When we print the value of a after the call to call_by_reference, it is now 50.

When to Use Call by Value and Call by Reference in C?

Choosing between call by value and call by reference in C is guided by your coding needs. Each method has distinct uses and implications for your code.

Call by Value in C

If you want a function to operate on the variables' values but don't want these variables to be modified within the function, you should use call by value. This method is useful when you need to keep the original values of variables intact. This is also the preferred way when you're working with small data structures, as copying their values won't consume much memory.

Consider the following example:

#include <stdio.h>

void update(int num) {
   num = num * 2;
   printf("Value inside function update = %d\n", num);
}

int main() {
   int a = 10;
   
   printf("Value of a before function call = %d\n", a);
   update(a);
   printf("Value of a after function call = %d\n", a);
   
   return 0;
}

In this code, we declare a function update which multiplies the given number by 2. We then declare an integer a in the main function and call the update function with a as an argument. However, you'll notice that the value of a remains unchanged even after the function call. This is because we used call by value, so the update function only operated on a copy of a.

Call by Reference in C

If you want a function to modify the variables directly, you should use call by reference. This method passes the memory address of the variable rather than copying the value. It is beneficial when dealing with large data structures, as it will avoid the inefficiency of copying the entire data structure.

Let's illustrate this with a similar function as before, but now using call by reference:

#include <stdio.h>

void update(int *num) {
   *num = *num * 2;
   printf("Value inside function update = %d\n", *num);
}

int main() {
   int a = 10;
   
   printf("Value of a before function call = %d\n", a);
   update(&a);
   printf("Value of a after function call = %d\n", a);
   
   return 0;
}

In this code, we modify the update function to take a pointer to an integer. We then pass the address of a to the update function. This time, the value of a is changed after the function call because we used call by reference.

Advantages of Using Call by Value Method

Call by Value, one of the two main methods for argument passing in C, brings several notable benefits.

Safeguards the Actual Parameters

One of the primary advantages of call by value in C is its ability to protect actual parameters from unintentional alterations. As the function operates on a copy of the original data, the actual parameters remain unchanged regardless of the operations performed within the function.

For instance, consider a function designed to find the factorial of a number:

#include <stdio.h>

int factorial(int n) {
   if(n == 0)
      return 1;
   else
      return n * factorial(n-1);
}

int main() {
   int num = 5;
   
   printf("Factorial of %d is %d\n", num, factorial(num));
   printf("Value of num is still %d\n", num);
   
   return 0;
}

In the above example, the function factorial uses recursion to compute the factorial of a number. If we had used call by reference here, the original number num would have been modified during the computation, which is not desirable. However, with call by value, the value of num remains untouched.

Simplicity

Call by Value is often easier to understand because it follows a straightforward linear execution pattern. This simplicity makes the code easier to debug and comprehend, especially for novice programmers.

Consider this example:

#include <stdio.h>

void square(int num) {
   num = num * num;
   printf("Square inside function = %d\n", num);
}

int main() {
   int a = 5;
   
   square(a);
   printf("Value of a after function call = %d\n", a);
   
   return 0;
}

In this example, the function square calculates the square of a number. The function operates on a copy of a, leaving the original value of a unchanged after the function call. This direct, linear flow of data manipulation makes it easier to follow the logic of the program.

In summary, the primary advantages of using call by value in C are its ability to safeguard the original data and its simplicity in program comprehension and debugging. Despite potentially increased memory usage for larger data structures, these benefits make call by value a valuable tool in many programming scenarios.

Advantages of Using Call by Reference Method

Call by Reference in C offers several benefits, especially when dealing with specific coding scenarios.

Efficiency with Large Data Structures

Call by Reference is particularly advantageous when handling large data structures. Since only the address is passed to the function, there's no need to create a copy of the entire data structure. This saves both memory and time, making your program more efficient.

#include <stdio.h>
void updateArray(int* arr, int n) {
    for(int i = 0; i < n; i++) {
        arr[i] += 1;
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    updateArray(arr, 5);
    for(int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

In this example, we're modifying an array using the updateArray function. If we used Call by Value here, it would have created a copy of the array, which is inefficient, especially for large arrays.

Modification of Original Variables

Call by Reference allows functions to modify original variables. This feature is helpful when you need the function to update the value of certain variables.

#include <stdio.h>

void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 5, y = 10;
    swap(&x, &y);
    printf("x = %d, y = %d", x, y);
    return 0;
}

Here, we're swapping the values of two variables using the swap function. The function directly modifies x and y because we passed their addresses.

Disadvantages of Using Call by Value Method

While Call by Value offers numerous benefits, it also has some downsides.

Inefficient for Large Data Structures

Call by Value can be inefficient for large data structures, as it requires creating a copy of the entire data structure. This results in increased memory usage and runtime, which can be particularly problematic in memory-constrained or time-critical applications.

No Modification of Original Variables

Call by Value doesn't allow functions to modify original variables. This lack of flexibility can limit what functions can do and require more complex workarounds to achieve certain outcomes.

Disadvantages of Using Call by Reference Method

Call by Reference, while beneficial in many cases, has its downsides as well.

Potential for Unintended Changes

One risk of using Call by Reference is the potential for unintended changes to original variables. If not handled carefully, a function might modify variables when it's not supposed to, leading to potential bugs.

Complexity of Understanding and Debugging

Call by Reference can lead to code that's harder to understand and debug. Since it's less linear than Call by Value, it can be harder to trace how data is modified throughout the program. This complexity can make the development process more time-consuming, particularly for less experienced programmers.

Conclusion

In conclusion, understanding the nuances of call by value and call by reference in C is paramount for any C programmer. These distinct methods of passing arguments in functions have their own unique advantages and potential pitfalls. Mastering these concepts can significantly enhance your programming skills, streamline your code, and ultimately improve your programs' performance.

Whether you're preserving data integrity with call by value, or optimising memory usage with call by reference, each technique offers a powerful tool in your programming repertoire. However, as with any tool, it's essential to recognise when to use each one and to understand the potential consequences.

Finally, keep in mind that continued learning is the key to mastering any programming language. Check out upGrad’s Executive PG Programme in Data Science for an in-depth, hands-on exploration of these concepts and much more. Remember, the journey of becoming an expert tech expert involves constant practice, learning, and adaptation to new paradigms. 

Your next big leap in C programming is just a click away - give upGrad's programs a try today!

FAQs

1. What is Call by Value in C?

Call by Value in C involves passing the actual value of a variable to the function. Any changes made within the function do not affect the variable's original value in the calling function.

2. What is Call by Reference in C?

Call by Reference in C involves passing the address of the variable to the function. This means that the function works directly on the original variable, and any changes made within the function reflect in the calling function.

3. When should I use Call by Value and Call by Reference in C?

Use Call by Value when you don't want the function to alter the original variables. Use Call by Reference when you need the function to modify the original variables or when passing large data structures to avoid the inefficiency of copying data.

4. What are the risks of using Call by Reference?

Using Call by Reference can lead to unintended modifications to the original variables. It can also make the code harder to understand and debug due to the non-linear execution pattern.

Leave a Reply

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