C++ Pointers with Examples

What are Pointers?

In C++, a pointer refers to a variable that holds the address of another variable. Like regular variables, pointers have a data type. For example, a pointer of type integer can hold the address of a variable of type integer. A pointer of character type can hold the address of a variable of character type.

You should see a pointer as a symbolic representation of a memory address. With pointers, programs can simulate call-by-reference. They can also create and manipulate dynamic data structures. In C++, a pointer variable refers to a variable pointing to a specific address in a memory pointed by another variable.

Addresses in C++

To understand C++ pointers, you must understand how computers store data.

When you create a variable in your C++ program, it is assigned some space the computer memory. The value of this variable is stored in the assigned location.

To know the location in the computer memory where the data is stored, C++ provides the & (reference) operator. The operator returns the address that a variable occupies.

For example, if x is a variable, &x returns the address of the variable.

Pointer Declaration Syntax

The declaration of C++ takes the following syntax:

datatype *variable_name; 
  • The datatype is the base type of the pointer which must be a valid C++ data type.
  • The variable_name is should be the name of the pointer variable.
  • Asterisk used above for pointer declaration is similar to asterisk used to perform multiplication operation. It is the asterisk that marks the variable as a pointer.

Here is an example of valid pointer declarations in C++:

int    *x;    // a pointer to integer
double *x;    // a pointer to double
float  *x;    // a pointer to float
char   *ch     // a pointer to a character

Reference operator (&) and Deference operator (*)

The reference operator (&) returns the variable’s address.

The dereference operator (*) helps us get the value that has been stored in a memory address.

For example:

If we have a variable given the name num, stored in the address 0x234 and storing the value 28.

The reference operator (&) will return 0x234.

The dereference operator (*) will return 5.

Example 1:

#include <iostream>
using namespace std;
int main() {
	int  x = 27;  
	int  *ip;        
	ip = &x;       
	cout << "Value of x is : ";
	cout << x << endl;
	cout << "Value of ip is : ";
	cout << ip<< endl;
	cout << "Value of *ip is : ";
	cout << *ip << endl;
	return 0;
}

Output:

Reference operator (&) and Deference operator (*)

How this works:

Reference operator (&) and Deference operator (*)

Here is a screenshot of the code:

Reference operator (&) and Deference operator (*)

Code Explanation:

  1. Import the iostream header file. This will allow us to use the functions defined in the header file without getting errors.
  2. Include the std namespace to use its classes without calling it.
  3. Call the main() function. The program logic should be added within the body of this function. The { marks the beginning of the function’s body.
  4. Declare an integer variable x and assigning it a value of 27.
  5. Declare a pointer variable *ip.
  6. Store the address of variable x in the pointer variable.
  7. Print some text on the console.
  8. Print the value of variable x on the screen.
  9. Print some text on the console.
  10. Print the address of variable x. The value of the address was stored in the variable ip.
  11. Print some text on the console.
  12. Print value of stored at the address of the pointer.
  13. The program should return value upon successful execution.
  14. End of the body of the main() function.

Pointers and Arrays

Arrays and pointers work based on a related concept. There are different things to note when working with arrays having pointers. The array name itself denotes the base address of the array. This means that to assign the address of an array to a pointer, you should not use an ampersand (&).

For example:

p = arr;

The above is correct since arr represents the arrays’ address. Here is another example:

p = &arr;

The above is incorrect.

We can implicitly convert an array into a pointer. For example:

int arr [20];
int * ip;

Below is a valid operation:

ip = arr;

After the above declaration, ip and arr will be equivalent, and they will share properties. However, a different address can be assigned to ip, but we cannot assign anything to arr.

Example 2:

This example shows how to traverse an array using pointers:

#include <iostream>
using namespace std;
int main() {
	int *ip;
	int arr[] = { 10, 34, 13, 76, 5, 46 };
	ip = arr;
	for (int x = 0; x < 6; x++) {
		cout << *ip << endl;
		ip++;
	}
	return 0;
}

Output:

Pointers and Arrays

Here is a screenshot of the code:

Pointers and Arrays

Code Explanation:

  1. Declare an integer pointer variable ip.
  2. Declare an array named arr and store 6 integers into it.
  3. Assign arr to ip. The ip and arr will become equivalent.
  4. Create a for a loop. The loop variable x was created to iterate over the array elements from index 0 to 5.
  5. Print the values stored at the address of the pointer IP. One value will be returned per iteration, and a total of 6 repetitions will be done. The endl is a C++ keyword that means the end line. This action allows you to moves the cursor to the next line after each value is printed. Each value will be printed in an individual line.
  6. To move the pointer to the next int position after every iteration.
  7. End of the for a loop.
  8. The program must return something upon successful execution.
  9. End of the main() function body.

NULL Pointer

If there is no exact address that is to be assigned, then the pointer variable can be assigned a NULL. It should be done during the declaration. Such a pointer is known as a null pointer. Its value is zero and is defined in many standard libraries like iostream.

Example 3:

#include <iostream>
using namespace std;
int main() {
	int  *ip = NULL;
	cout << "Value of ip is: " << ip;
	return 0;
}

Output:

NULL Pointer

Here is a screenshot of the code:

NULL Pointer

Code Explanation:

  1. Declare a pointer variable ip and assigning it a value of NULL.
  2. Print value of pointer variable ip alongside some text on the console.
  3. The program must return value upon successful completion.
  4. End of the body of the main() function.

Pointers of Variables

With C++, you can manipulate data directly from the computer’s memory.

The memory space can be assigned or re-assigned as one wishes. This is made possible by Pointer variables.

Pointer variables point to a specific address in the computer’s memory pointed to by another variable.

It can be declared as follows:

int *p;

Or,

int* p;

In the you example, we have declared the pointer variable p.

It will hold a memory address.

The asterisk is the dereference operator that means a pointer to.

The pointer p is pointing to an integer value in the memory address.

Example 4:

#include <iostream>

using namespace std;
int main() {
	int *p, x = 30;
	p = &x;
	cout << "Value of x is: " << *p;
	return 0;
}

Output:

Pointers of Variables

Here is a screenshot of the code:

Pointers of Variables

Code Explanation:

  1. Declare a pointer variable p and a variable x with a value of 30.
  2. Assign the address of variable x to p.
  3. Print the value of pointer variable p alongside some text on the console.
  4. The program must return value upon successful completion.
  5. End of the body of the main() function.

Application of Pointers

Functions in C++ can return only one value. Further, all the variables declared in a function are allocated on the function call stack. As soon as the function returns, all the stack variables are destroyed.

Arguments to function are passed by value, and any modification done on the variables doesn’t change the value of the actual variables that are passed. Following example helps illustrate this concept:-

Example 5:

#include <iostream>

using namespace std;
void test(int*, int*);
int main() {
	int a = 5, b = 5;
	cout << "Before changing:" << endl;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	test(&a, &b);

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

void test(int* n1, int* n2) {
	*n1 = 10;
	*n2 = 11;
}

Output:

Application of Pointers

Here is a screenshot of the code:

Application of Pointers

Code Explanation:

  1. Create a prototype of a function named test that will take two integer parameters.
  2. Call the main() function. We will add the program logic inside its body.
  3. Declare two integer variables a and b, each with a value of 5.
  4. Print some text on the console. The endl (end line) will move the cursor to begin printing in the next line.
  5. Print the value of variable a on the console alongside other text. The endl (end line) will move the cursor to begin printing in the next line.
  6. Print the value of variable b on the console alongside other text. The endl (end line) will move the cursor to begin printing in the next line.
  7. Create a function named test() that takes in the addresses of variable a and b as the parameters.
  8. Print some text on the console. The \n will create a new blank line before the text is printed. The endl (end line) will move the cursor to begin printing in the next line after the text is printed.
  9. Print the value of variable a on the console alongside other text. The endl (end line) will move the cursor to begin printing in the next line.
  10. Print the value of variable b on the console alongside other text. The endl (end line) will move the cursor to begin printing in the next line.
  11. The program must return value upon successful completion.
  12. End of the body of the main() function.
  13. Defining the function test(). The function should take two integer pointer variables *n1 and *n2.
  14. Assigning the pointer variable *n1 a value of 10.
  15. Assigning the pointer variable *n2 a value of 11.
  16. End of the body of the function test().

Even Though, new values are assigned to variable a and b inside the function test, once the function call completes, the same is not reflected the outer function main.

Using pointers as function arguments helps to pass the variable’s actual address in the function, and all the changes performed on the variable will be reflected in the outer function.

In the above case, the function ‘test’ has the address of variables ‘a’ and ‘b.’ These two variables are directly accessible from the function ‘test’, and hence any change done to these variables are reflected in the caller function ‘main.’

Advantages of using Pointers

Here, are pros/benefits of using Pointers

  • Pointers are variables which store the address of other variables in C++.
  • More than one variable can be modified and returned by function using pointers.
  • Memory can be dynamically allocated and de-allocated using pointers.
  • Pointers help in simplifying the complexity of the program.
  • The execution speed of a program improves by using pointers.

Summary

  • A pointer refers to a variable holding address of another variable.
  • Each pointer has a valid data type.
  • A pointer is a symbolic representation of a memory address.
  • Pointers allow programs to simulate call-by-reference and create and manipulate dynamic data structures.
  • Arrays and pointers use a related concept.
  • The array name denotes the array’s base.
  • If you want to assign the address of an array to a pointer, don’t use an ampersand (&).
  • If there is no specific address to assign a pointer variable, assign it a NULL.