C++ Pointers

The C++ programming language offers various useful and exciting features and functionalities to programmers. C++ also supports object-oriented programming which makes life easier. C++ delivers many benefits to its users. Pointer is one of the most useful and important topics of any programming language. Let us learn more about pointers in C++.

What are Pointers in C++?

A pointer is used to refer to a variable that holds the address of another variable. These are symbolic representations of addresses. Always remember that an integer type pointer will only hold the address of an integer type variable. And same goes for the character.

Pointers enable programs to simulate call-by-reference. Pointers are also used to create and manipulate dynamic data structures.

Addresses in C++

Suppose, you have a variable named data in the program code then &data will give you the address in the memory.
Example:-

#include <iostream>
using namespace std;
int main()
{
  int data = 10;
  cout << "Address is: "<< &data;
}

Output:-

Address is: 0x7fff8f2f3cd4

In the above example, 0x means the address in hexadecimal format.

C++ Pointer Declaration

Syntax

datatype *name_of_the_variable;
  • datatype:- It is the base type of the pointer. And it also must be valid C++ data.
  • And at last, you have to give the name of the variable.
  • For pointer declaration, we used the asterisk.

Example of Valid pointer declarations:-

int    *a;    
double *b;   
float  *f;

Assigning addresses to pointers

You can assign addresses to pointers.
Example:-

int* ptr, data;
data = 5;

ptr = &data;

In the above code, we assigned the variable data with value 5. And the address of the data variable is assigned to the ptr pointer.

Getting the value from the address

You can also get the value from the address using pointers. You will have to use the * operator to do so.

int* ptr, data;
data = 10;
ptr = &data;

cout << *ptr;

Output:-

10

In the above example, the address of data is assigned to the pointer ptr. And we use *ptr to get the value that is stored in that address.

Example:- C++ pointers

#include <iostream>
using namespace std;
int main() {
    int data = 10;

    // declare pointer variable
    int* ptr;

    ptr = &data;
    cout << "data: " << data << endl;

    cout << "Address of data: " << &data<< endl;
    cout << "ptr: " << ptr << endl;

    cout << "Value stored in the address pointed to by pointVar: " << *ptr << endl;
    
    return 0;
}

Output:-

data: 10
Address of data: 0x7ffdb1a8a09c
ptr: 0x7ffdb1a8a09c
Value stored in the address pointed to by pointVar: 10

Change the value pointed by pointers

You can also change the value that is pointed by pointers.
Example:-

#include <iostream>
using namespace std;
int main() {
  int data = 10;
  int* ptr;
  ptr = &data;
  cout << "data: " << data << endl;
  cout << "*ptr: " << *ptr << endl;

  data = 15; //changing the value of data to 15
  cout << "Now data: " << data << endl;
  cout << "*ptr: " << *ptr << endl;
  *ptr = 17; //  changing the value of *ptr to 17
  cout << "data: " << data << endl;
  cout << "Now *ptr: " << *ptr << endl;
  return 0;
}

Output:-

data: 10
*ptr: 10
Now data: 15
*ptr: 15
data: 17
Now *ptr: 17

Reference and Dereference Operator

  • The reference operator is denoted by ‘&’. It is used to return the address of the variable.
  • The dereference operator is denoted by ‘*’. It is used to get the value that is already stored in a memory address.
  • The reference operator will return in hexadecimal format and the other will return in decimal format because representation of memory is always in hexadecimal format.

Pointers and Arrays in C++

You won’t have to use an ampersand(&) to assign the address of an array to a pointer. You can also convert an array to a pointer.

int a[20];
int *ptr;

Below is the valid operation:-

ptr=a;

In the above example, the array a and the pointer ptr will be equivalent.
Example:-

#include <iostream>
using namespace std;
int main() {
    int *ptr;
    int a[] = {5,6,9,3};
    ptr = a;
    for (int i = 0; i < 4; i++) {
   	 cout << *ptr << endl;
   	 ptr++;
    }
    return 0;
}

Output:-

5
6
9
3

Null Pointers:-

A pointer that points to nowhere then it is known as null pointers. There are two methods to assign a null pointer:-

int *point1 = 0;
int *point2 = NULL;

Invalid Pointers in C++:-

A pointer is known as an invalid pointer when it does not point to valid elements. You can also state that Uninitialized pointers are also known as invalid pointers.

int *a;
int ar[10];
int *point = ar+20;

In the above example, *a pointer is uninitialized so it is an invalid pointer. And the pointer variable point is exceeding the limit of array ar. So, it is also an invalid pointer.

Benefits of using pointers in C++:-

  • Pointers help you to reduce the length and the execution of the program.
  • Using a pointer, you can perform dynamic memory allocation easily.
  • With pointers, it is easy to handle and implement arrays and structures.

Usage of Pointers:-

There are many uses of pointers in C++ programming.

1. Dynamic Memory Allocation:- With the help of pointers, we can easily allocate memory dynamically using calloc() and malloc() functions in C++.

2. Arrays, Functions and Structures:- With pointers, it is easy to handle and implement arrays and structures. It helps in reducing code complexity and the execution time.

Complex Pointers in C++:-

You must know that there are some complex pointers available in C++. Below is a table of the precedence and associativity of the operators which are used regarding pointers.

Operator Precedence Associativity
(), [] 1 Left to Right
*, identifier  2 Right to Left
Data Type 3 _
  • ():- Used to declare and define a function.
  • []:- Used to represent an array.
  • *:- A pointer operator.
  • Identifier:- Name of the pointer.
  • Data Type:- It is the type of the variable to which the pointer points to.

Read the pointer:-

Before starting to read a pointer, you have to check that if () and [] have equal precedence and also look for the associativity.

Example:-

int (*point)[2]

In the above example, you will notice that associativity is left to right. In that case, the priority goes to (). Inside the bracket, you will notice that *(pointer operator) and point(Identifier) have the same precedence. So, the associativity will go right to left. First priority goes to the point and the second priority goes to *. At last, you can say that point is a pointer to an array of integers of size 2.

Pointers of Variables

Using C++, you can directly manipulate data from the computer’s memory. Pointer variables point to a specific address in the computer’s memory.

Declaration of Pointers of Variables

int *p;
or,
int* p;

Example:-

#include <iostream>
using namespace std;
int main() {
    int *ptr, a = 20;
    ptr = &a;
    cout << "a: " << *ptr;
    return 0;
}

Output:-

a: 20

Applications of pointers in C++

In C++, functions can only return one value. Function arguments are passed by the value. And if you do any modifications on the variables then it won’t change the value of the actual variables which are passed.

Example:-

#include <iostream>

using namespace std;
void func(int*, int*);
int main() {
    int a = 6, b = 7;
    cout << "Before:" << endl;
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;

    func(&a, &b);

    cout << "\nAfter:" << endl;
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
    return 0;
}

void func(int* x, int* y) {
    *x = 5;
    *y = 4;
}

Output:-

Before:
a: 6
b: 7After:
a: 5
b: 4

You can use pointers as the function arguments to pass the variable’s actual address in the function. The modifications which you have done on the variables will affect the outer function.
In the above example, we created a function named func and it has the address of the variables a and b.

Pointer Arithmetic:-

In a pointer, you can use four arithmetic operators such as ++, –, +, and – on pointers. With the help of this, you can perform certain arithmetic operations on pointers.

Incrementing a pointer:-

In C++, you can also increment a pointer. You can use an array that will help you increment the pointer easily.
Example:- incrementing a pointer

#include <iostream>
using namespace std;
int main () {
   int value_array[2] = {41, 1};
   int *point;
   point = value_array;
   cout<<"TechVidvan Tutorial: Incrementing a pointer!"<<endl<<endl;
   for (int a = 0; a < 2; a++) {
   	cout<<"Value of value_array: "<<*point<<endl;
   	cout<<"Address of value_array: "<<point<<endl;
   	point++;// incrementing the pointer variable!
   }
   return 0;
}

Output:-

TechVidvan Tutorial: Incrementing a pointer!

Value of value_array: 41
Address of value_array: 0x7ffea960cbf0
Value of value_array: 1
Address of value_array: 0x7ffea960cbf4

Decrementing a pointer in C++:-

The C++ programming language also has the functionality to decrement a pointer.

Example:- Decrementing a pointer

#include <iostream>
using namespace std;
int main () {
   int value_array[] = {141, 102};
   int *point;
   int max=2;
   point = &value_array[max-1];
   cout<<"TechVidvan Tutorial: Decrementing a pointer!"<<endl<<endl;
   for (int a = max; a > 0; a--) {
   	cout<<"Value of value_array: "<<*point<<endl;
   	cout<<"Address of value_array: "<<point<<endl;
  point--; // decrementing the pointer variable!
   }
   return 0;
}

Output:-

TechVidvan Tutorial: Decrementing a pointer!
Value of value_array: 102
Address of value_array: 0x7ffd201d5c24
Value of value_array: 141
Address of value_array: 0x7ffd201d5c20

Pointer Comparison:-

You can also compare pointers by using relational operators like ==, <, and >.
Example:- Pointer Comparison

#include <iostream>
using namespace std;
int main () {
   int value_array[] = {141, 1032};
   int *point;
   int max=2;
   int a=0;
   point = value_array;
   cout<<"TechVidvan Tutorial: Pointer Comparison!"<<endl;
   while(point <= &value_array[max-1]) {
  cout<<"Value of value_array: "<<*point<<endl;
  cout<<"Address of value_array: "<<point<<endl;
  point++;
  a++;
   }
   return 0;
}

Output:-

TechVidvan Tutorial: Pointer Comparison!
Value of value_array: 141
Address of value_array: 0x7ffe95588b90
Value of value_array: 1032
Address of value_array: 0x7ffe95588b94

In the above example, we are incrementing the pointer variable until the address which the pointer points to is less than or equal to the address of the last element of the array.

Pointer to Pointer:-

Pointer to pointer is known as a chain of pointers. It means that the first pointer contains the address of the second pointer and it points to the location of actual value.

Example:-

int **point;

In the above example, we declared a pointer to pointer of type integer.
Example:- Pointer to pointer

#include <iostream>
using namespace std;
int main () {
   int  val;
   int  *pt;
   int  **point;
   val = 55;
   pt = &val;
   point = &pt;
   cout<<"Value=> val: "<<val<<endl;
   cout<<"Value=> *pt: "<<*pt<<endl;
   cout<<"Value=> **pptr: "<<**point<<endl;
return 0;
}   

Output:-

Value=> val: 55
Value=> *pt: 55
Value=> **pptr: 55

In C++, there are 3 ways to pass arguments to a function:-

  • Call by value
  • Call by reference
  • Call by reference with reference argument

Example:- Call by methods in C++

#include <bits/stdc++.h>
using namespace std;
int func1(int num)
{
    cout << "func1()=> address of num1: " << &num << endl;
    num += num;
    return num;
}
void func2(int *num)
{
    cout << "func2()=> num2 address: " << num << "\n";
    *num += *num;
}
void func3(int &num)
{
    cout << "func3()=> num3 address: " << &num << "\n";
    num += num;
}
void Tech()
{
    //Call-by-Value
    int num1=8;
    cout << "main()=> num1 address: " << &num1 << "\n";
    cout << "num1: " << func1(num1) << "\n";
    cout << "No change in num1: " << num1 << "\n";
    
    //Call-by-Reference with Pointer Arguments
    int num2=8;
    cout << "main()=> num2 address: " << &num2 << "\n";
    func2(&num2);
    cout << "num2: " << num2 << "\n";
    cout << "Change in num2: " << num2 << "\n";
    
    //Call-by-Reference with Reference Arguments
    int num3=8;
    cout << "main()=> num3 address: " << &num3 << "\n";
    func3(num3);
    cout << "num3: " << num3 << "\n";
    cout << "Change in num3: " << num3 << "\n";
    
}
int main()
{
    Tech();
}

Output:-

main()=> num1 address: 0x7ffe5421b7fc
num1: func1()=> address of num1: 0x7ffe5421b7dc
16
No change in num1: 8
main()=> num2 address: 0x7ffe5421b800
func2()=> num2 address: 0x7ffe5421b800
num2: 16
Change in num2: 16
main()=> num3 address: 0x7ffe5421b804
func3()=> num3 address: 0x7ffe5421b804
num3: 16
Change in num3: 16

The arguments are passed by value in C++. You can make use of pass by reference to avoid the overhead of cloning. Changes are made into the clone that is made by the called function.

Return pointers from function:-

In C++, you have seen that you can return an array from a function. In a similar way, you can also return a pointer from a function.

NOTE:- If you try to return the address of a local variable outside the function then the local variables of the function will go out of scope. And your program will never get executed. So to avoid this type of error, you have to define the local variable as a static variable.

Example:- Return a pointer from a function

#include <iostream>
using namespace std;
int* printToscreen()
{
  static int val = 125; // defining the local variable as static to avoid execution error!
  return (&val); // function returning pointer!
}
int main()
{
  int* point;
  point = printToscreen();
  cout<<"TechVidvan Tutorial: Returning pointer from a function!"<<endl<<endl;
  cout<<"Address is: "<<point<<endl;
  cout<<"Value is: "<<*point<<endl;
  return 0;
}

Output:-

TechVidvan Tutorial: Returning pointer from a function!

Address is: 0x55d2974f6010
Value is: 125

Summary

In this tutorial, we discussed the pointers and addresses in C++. We also discussed how you can perform different operations on a pointer in C++. We discussed the benefits of using pointers in C++. Then we discussed how to return pointers from a function. We talked over how you can assign a pointer to a pointer in C++. We discussed the applications of pointers in C++.