C++ Call by Reference Using Pointers
In C++, there are two primary ways to pass arguments to a function: call by value and call by reference. In call by reference, the function works directly with the original variables, rather than copies, which allows modifications to be reflected outside the function. While references are commonly used for call by reference, pointers can also be used for this purpose.
Using pointers for call by reference is particularly useful when you need to:
In this guide, we'll explain how pointers can be used to pass arguments by reference in C++.
In call by reference, rather than passing the value of the argument to the function, we pass the memory address of the variable. This allows the function to modify the actual variable, not just a copy.
When you use pointers for call by reference, you pass the pointer to the function, which contains the memory address of the variable you want to modify.
void function_name(data_type* pointer) {
// Function code that uses the pointer to modify the original variable
}
data_type* pointer
), which points to the original variable passed by the caller.Let's take a look at a simple example to demonstrate how to pass arguments by reference using pointers.
#include <iostream>
using namespace std;
// Function to swap two numbers using pointers
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
cout << "Before swap: x = " << x << ", y = " << y << endl;
// Pass the memory address of x and y to the function
swap(&x, &y); // Pass pointers to x and y
cout << "After swap: x = " << x << ", y = " << y << endl;
return 0;
}
Output:
Before swap: x = 5, y = 10
After swap: x = 10, y = 5
Explanation:
swap
function accepts pointers as arguments (int* a
, int* b
).main
function, we pass the addresses of x
and y
to swap
using the &
operator.swap
function, we dereference the pointers (*a
, *b
) to access the values at those memory addresses, allowing us to modify the original variables x
and y
.Pointers can also be used to modify arrays in a similar way. Arrays are inherently passed by reference in C++, but using pointers explicitly can help you understand how data is passed and modified.
#include <iostream>
using namespace std;
// Function to modify array elements using pointers
void modifyArray(int* arr, int size) {
for (int i = 0; i < size; i++) {
*(arr + i) = *(arr + i) * 2; // Double each element
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Before modification: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
// Pass the array (actually a pointer to the first element)
modifyArray(arr, size);
cout << "After modification: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
Output:
Before modification: 1 2 3 4 5
After modification: 2 4 6 8 10
Explanation:
modifyArray
function accepts a pointer int* arr
that points to the first element of the array.*(arr + i)
) to modify each element of the array.You can also pass structures to functions by reference using pointers, allowing you to modify the structure’s members.
#include <iostream>
using namespace std;
// Define a structure
struct Person {
string name;
int age;
};
// Function to modify structure members using pointers
void modifyPerson(Person* p) {
p->name = "John Doe"; // Modify name using pointer
p->age = 30; // Modify age using pointer
}
int main() {
Person p1 = {"Alice", 25};
cout << "Before modification: " << p1.name << ", " << p1.age << endl;
// Pass the pointer to the structure
modifyPerson(&p1);
cout << "After modification: " << p1.name << ", " << p1.age << endl;
return 0;
}
Output:
Before modification: Alice, 25
After modification: John Doe, 30
Explanation:
modifyPerson
function accepts a pointer to a Person
structure (Person* p
).->
operator is used to modify the members of the structure.p1
is modified because we passed its address to the function.Pointers are especially useful when working with dynamic memory allocation (using new
and delete
). You can modify dynamically allocated memory in the same way as with stack-allocated variables.
#include <iostream>
using namespace std;
void allocateAndModify(int* ptr) {
*ptr = 100; // Modify the value using pointer
}
int main() {
int* p = new int; // Dynamically allocate memory for one integer
cout << "Before modification: " << *p << endl; // Uninitialized value
// Modify the dynamically allocated memory
allocateAndModify(p);
cout << "After modification: " << *p << endl; // Value should be 100
delete p; // Free the allocated memory
return 0;
}
Output:
Before modification: 0
After modification: 100
Explanation:
new int
.allocateAndModify
function modifies the dynamically allocated value using the pointer.delete
.