Home C Tutorial: Function Call by Reference in C Programming

Tutorial: Function Call by Reference in C Programming

In C programming, call by reference allows a function to modify the actual arguments passed to it.

Instead of passing a copy of the variable’s value, a function is provided with the memory address (or pointer) of the variable, enabling direct modification of the original data.

This tutorial covers:

1. What is Call by Reference?

Call by reference is a mechanism in C where:

  • A function receives the address of a variable instead of a copy of its value.
  • Using pointers, the function can directly modify the original variable in memory.

Key Concepts

  • Call by reference requires pointers.
  • The & operator is used to pass the address of a variable.
  • The * operator is used inside the function to dereference the pointer and access the actual data.

2. How Call by Reference Works

Example Overview

#include <stdio.h>

void modifyValue(int *num) {
    *num = 20;  // Dereference pointer and modify the original value
}

int main() {
    int value = 10;
    printf("Before function call: value = %d\n", value);
    
    modifyValue(&value);  // Pass the address of 'value'
    
    printf("After function call: value = %d\n", value);
    return 0;
}

Output:

Before function call: value = 10
After function call: value = 20

Explanation

  1. The &value in modifyValue(&value) passes the address of value to the function.
  2. Inside the modifyValue function, the pointer *num refers to the original variable.
  3. Modifications to *num affect the original value.

3. Examples of Call by Reference

3.1 Swapping Two Numbers

Using call by reference, you can swap two numbers directly without returning values.

#include <stdio.h>

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

int main() {
    int x = 5, y = 10;
    printf("Before swap: x = %d, y = %d\n", x, y);
    
    swap(&x, &y);  // Pass the addresses of x and y
    
    printf("After swap: x = %d, y = %d\n", x, y);
    return 0;
}

Output:

Before swap: x = 5, y = 10
After swap: x = 10, y = 5

3.2 Incrementing a Value

Increment the original value of a variable.

#include <stdio.h>

void increment(int *num) {
    (*num)++;  // Increment the value pointed to by num
}

int main() {
    int value = 42;
    printf("Before increment: value = %d\n", value);
    
    increment(&value);  // Pass the address of value
    
    printf("After increment: value = %d\n", value);
    return 0;
}

Output:

Before increment: value = 42
After increment: value = 43

3.3 Modifying Multiple Values

A function can modify multiple variables by passing their addresses.

#include <stdio.h>

void modifyValues(int *a, int *b, int *c) {
    *a += 10;
    *b *= 2;
    *c -= 5;
}

int main() {
    int x = 3, y = 6, z = 9;
    printf("Before: x = %d, y = %d, z = %d\n", x, y, z);
    
    modifyValues(&x, &y, &z);  // Pass addresses of x, y, and z
    
    printf("After: x = %d, y = %d, z = %d\n", x, y, z);
    return 0;
}

Output:

Before: x = 3, y = 6, z = 9
After: x = 13, y = 12, z = 4

4. Advantages and Disadvantages

Advantages

  1. Direct Modification: Enables functions to modify multiple variables without returning values.
  2. Efficiency: Reduces memory overhead for large structures since addresses are passed instead of copying data.
  3. Flexibility: Allows functions to return multiple results by modifying variables directly.

Disadvantages

  1. Complexity: Requires understanding pointers, which can be error-prone for beginners.
  2. Risk of Side Effects: Unintentional modifications to variables may lead to bugs.

5. Comparison with Call by Value

Aspect Call by Value Call by Reference
Data Passed A copy of the variable’s value. The address of the variable.
Original Data Cannot be modified. Can be modified.
Memory Usage More memory used for copies. Less memory used for pointers.
Return Values Can return only one value. Can modify multiple variables directly.
Ease of Use Easier to implement and understand. Requires understanding of pointers.

6. Practical Use Cases

6.1 Updating an Array

You can modify an array by passing its pointer.

#include <stdio.h>

void updateArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;  // Double each element
    }
}

int main() {
    int nums[] = {1, 2, 3, 4, 5};
    int size = sizeof(nums) / sizeof(nums[0]);
    
    printf("Before update: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", nums[i]);
    }
    printf("\n");
    
    updateArray(nums, size);  // Pass array pointer
    
    printf("After update: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", nums[i]);
    }
    printf("\n");
    return 0;
}

Output:

Before update: 1 2 3 4 5
After update: 2 4 6 8 10

6.2 Dynamic Memory Allocation

Call by reference is crucial for dynamically allocating memory.

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

void allocateMemory(int **ptr, int size) {
    *ptr = (int *)malloc(size * sizeof(int));  // Allocate memory
    if (*ptr == NULL) {
        printf("Memory allocation failed!\n");
        return;
    }
    for (int i = 0; i < size; i++) {
        (*ptr)[i] = i + 1;  // Initialize values
    }
}

int main() {
    int *array = NULL;
    int size = 5;
    
    allocateMemory(&array, size);  // Pass pointer to the pointer
    
    printf("Array elements: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    free(array);  // Free allocated memory
    return 0;
}

Output:

Array elements: 1 2 3 4 5

7. Conclusion

Call by reference in C is a powerful feature that allows functions to modify original variables directly. It is especially useful when working with large data structures, dynamic memory, or situations requiring multiple outputs.

Key Takeaways

  • Use pointers (* and &) to implement call by reference.
  • Ensure proper memory management when dealing with dynamically allocated memory.
  • Choose call by reference over call by value when efficiency and direct modification are needed.

Mastering call by reference will significantly enhance your ability to write efficient and flexible programs in C.

You may also like