# 2.3: References and Pointers

$$\newcommand{\vecs}{\overset { \rightharpoonup} {\mathbf{#1}} }$$ $$\newcommand{\vecd}{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}{\| #1 \|}$$ $$\newcommand{\inner}{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}{\| #1 \|}$$ $$\newcommand{\inner}{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$$$\newcommand{\AA}{\unicode[.8,0]{x212B}}$$

References and Pointers

There are 3 ways to pass C++ arguments to a function:

• call-by-value
• call-by-reference with pointer argument
• call-by-reference with reference argument

// C++ program to illustrate call-by-methods in C++

#include <iostream>
using namespace std;

//Pass-by-Value
int square1(int n)
{
//Address of n in square1() is not the same as n1 in main()
cout << "address of n1 in square1(): " << &n << "\n";

// clone modified inside the function
n *= n;
return n;
}

//Pass-by-Reference with Pointer Arguments
void square2(int *n)
{
//Address of n in square2() is the same as n2 in main()
cout << "address of n2 in square2(): " << n << "\n";

// Explicit de-referencing to get the value pointed-to
*n *= *n;
}

//Pass-by-Reference with Reference Arguments
void square3(int &n)
{
//Address of n in square3() is the same as n3 in main()
cout << "address of n3 in square3(): " << &n << "\n";

// Implicit de-referencing (without '*')
n *= n;
}

int main()
{
//Call-by-Value
int n1=8;
cout << "address of n1 in main(): " << &n1 << "\n";
cout << "Square of n1: " << square1(n1) << "\n";
cout << "No change in n1: " << n1 << "\n";

//Call-by-Reference with Pointer Arguments
int n2=8;
cout << "address of n2 in main(): " << &n2 << "\n";
square2(&n2);
cout << "Square of n2: " << n2 << "\n";
cout << "Change reflected in n2: " << n2 << "\n";

//Call-by-Reference with Reference Arguments
int n3=8;
cout << "address of n3 in main(): " << &n3 << "\n";
square3(n3);
cout << "Square of n3: " << n3 << "\n";
cout << "Change reflected in n3: " << n3 << "\n";

return 0;

} 

Output
address of n1 in main(): 0x7ffcdb2b4a44
address of n1 in square1(): 0x7ffcdb2b4a2c
Square of n1: 64
No change in n1: 8
address of n2 in main(): 0x7ffcdb2b4a48
address of n2 in square2(): 0x7ffcdb2b4a48
Square of n2: 64
Change reflected in n2: 64
address of n3 in main(): 0x7ffcdb2b4a4c
address of n3 in square3(): 0x7ffcdb2b4a4c
Square of n3: 64
Change reflected in n3: 64

In C++, by default arguments are passed by value and the changes made in the called function will not reflect in the passed variable. The changes are made into a clone made by the called function.
If wish to modify the original copy directly (especially in passing huge object or array) and/or avoid the overhead of cloning, we use pass-by-reference. Pass-by-Reference with Reference Arguments does not require any clumsy syntax for referencing and dereferencing.