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
// 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; } |
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
// 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; } |
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
// 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; } |
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
// 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; } |
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
// 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; } |
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
// 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; } |
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.
Contact Us