Open In App

When do we pass arguments by pointer?

In C, the pass-by pointer method allows users to pass the address of an argument to the function instead of the actual value. This allows programmers to change the actual data from the function and also improve the performance of the program.

In C, variables are passed by pointer in the following cases:

1. To Modify Local Variables of the Function

A pointer allows the called function to modify a local variable of the caller function.

Example

In the below example program fun() can modify the local variable x of main(). 




// C program to modify local variables of the caller
// function
 
#include <stdio.h>
 
// function to modify local var x
void fun(int* x) {
  *x = 20;
}
 
int main()
{
    int x = 10;
    fun(&x);
    printf("New value of x is %d", x);
    return 0;
}

Output
New value of x is 20

2. For Passing Large-Sized Arguments

If an argument is large, the pass-by pointer is more efficient because only an address is really passed, not the entire object.

Example

The below example demonstrates the use pass-by pointer for passing large-sized arguments. consider the following Employee class and a function printEmpDetails() that prints Employee details.




// C program to print details of employee using structure
 
#include <stdio.h>
#include <string.h>
 
// Structure to represent Employee
struct Employee {
    char name[50];
    char desig[50];
};
 
// Function to print Employee details
void printEmpDetails(const struct Employee emp)
{
    printf("Name: %s\n", emp.name);
    printf("Designation: %s\n", emp.desig);
}
 
int main()
{
    // Create an instance of Employee
    struct Employee emp1;
    strcpy(emp1.name, "geek");
    strcpy(emp1.desig, "Software Engineer");
 
    // Call the printEmpDetails function
    printEmpDetails(emp1);
 
    return 0;
}

Output
Name: geek
Designation: Software Engineer

The problem with the above code is that every time printEmpDetails() is called, a new Employee object is constructed that involves creating a copy of all data members. So a better implementation would be to pass Employee as a pointer.




// C program to print details of employee using structure
 
#include <stdio.h>
#include <string.h>
 
// Structure to represent Employee
struct Employee {
    char name[50];
    char desig[50];
};
 
// Function to print Employee details
void printEmpDetails(const struct Employee* emp)
{
    printf("Name: %s\n", emp->name);
    printf("Designation: %s\n", emp->desig);
}
 
int main()
{
    // Creating an instance of Employee
    struct Employee emp1;
    strcpy(emp1.name, "geek");
    strcpy(emp1.desig, "Software Engineer");
 
    printEmpDetails(&emp1);
 
    return 0;
}

Output
Name: geek
Designation: Software Engineer

Note This point is valid only for struct as we don’t get any efficiency advantage for basic types like int, char, etc. 

3. To Achieve Run Time Polymorphism in a Function

We can make a function polymorphic by passing objects as a pointer to it.

Example

In the below program, print() receives a pointer to the base class object. Function print() calls the base class function show() if the base class object is passed, and the derived class function show() if the derived class object is passed.  




// C program to achieve run time polymorphism using function
// pointer
 
#include <stdio.h>
 
// Define the base class structure
struct Base {
    void (*show)();
};
 
// Function to show Base
void showBase() { printf("In base\n"); }
 
// Initialize Base
void initBase(struct Base* base) { base->show = showBase; }
 
// Define the derived class structure
struct Derived {
    // Inheritance by including the base class
    struct Base base;
};
 
// Function to show Derived
void showDerived() { printf("In derived\n"); }
 
// Initialize Derived
void initDerived(struct Derived* derived)
{
    // Initialize the base class
    initBase(&(derived->base));
    // Override for Derived behavior
    derived->base.show = showDerived;
}
 
// Function to print using polymorphism
void print(struct Base* base) { base->show(); }
 
// driver code
int main(void)
{
    struct Base b;
    struct Derived d;
 
    initBase(&b);
    initDerived(&d);
 
    print(&b);
   
    // Note: Using a pointer to the base class
    print((struct Base*)&d);
 
    return 0;
}

Output
In base
In derived

4. To Return Multiple Values

When you want to return multiple values from a function, passing pointers as function parameters allows us to modify the values of variables passed to the function.

Example




// C program to return multiple values from a function
 
#include <stdio.h>
 
// Function to calculate sum and product of two numbers
void calcSumAndProduct(int x, int y, int* sum, int* prod)
{
    *sum = x + y;
    *prod = x * y;
}
 
int main()
{
    int x = 5;
    int y = 7;
    int sum, prod;
    // calling the function to calculate sum and product
    calcSumAndProduct(x, y, &sum, &prod);
 
    // printing the sum and product returned from function
    printf("Sum is: %d \nProduct is: %d\n", sum, prod);
 
    return 0;
}

Output
Sum is: 12 
Product is: 35

5. To Modify the Content of Dynamically Allocated Memory.

By passing arguments by pointer to a function we can do modification in the content of dynamically allocated memory. It is mainly used when you want to allocate memory dynamically (by using functions like malloc, calloc, or realloc.

Example




// C program to modify dynamically allocated memory
 
#include <stdio.h>
#include <stdlib.h>
 
// Function to allocate memory for an integer and set its
// value
void dynamicMemoryAllocation(int** myptr)
{
    *myptr = (int*)malloc(sizeof(int));
    if (*myptr != NULL) {
        **myptr = 20;
    }
}
 
int main()
{
    int* val;
 
    // calling the function to allocate memory dynamically
    // and set the value
    dynamicMemoryAllocation(&val);
    printf("Dynamic value set is: %d\n", *val);
    // free up the allocated memory
    free(val);
    return 0;
}

Output
Dynamic value set is: 20

As a side note, it is a recommended practice to make pointer arguments const if they are being passed by pointer only due to reason no. 2 mentioned above. This is recommended to avoid unexpected modifications to the objects.

 


Article Tags :