C++ Declaration and Initialization of Pointers

When discussing pointers in C++, you will learn about two important topics in this post:

C++ Pointer Declaration

Pointer variables are declared like normal variables except for the addition of the unary ∗ character.

The general form of a pointer declaration is as follows:

type ∗var_name;

where "type" can be any valid C++ data type, and "var_name" is the name of the pointer variable. The following declarations declare pointers of different types:

int ∗iptr;       // creates an integer pointer iptr
char ∗cptr;      // creates a character pointer cptr
float ∗fptr;     // creates a float pointer fptr

When we say that "iptr" is an integer pointer, it means that the memory location being pointed to by iptr can hold only integer values. In other words, it can be stated that iptr is a pointer to an integer. Similarly, in the above-given declarations, "cptr" is a pointer to a character, and "fptr" is a pointer to a floating-point value. Thus, it is the base type of the pointer that defines what types of variables the pointer can point to. Technically, any type of pointer can point anywhere in memory.

However, all pointer arithmetic is done relative to its base type, so it is important to declare the pointers correctly.

Two special operators, ∗ and &, are used with pointers. The "&" operator is a unary operator that returns the operand's memory address. For example,

int i = 100;       // declares an int variable i
int ∗iptr;         // declares an int pointer iptr
iptr = &i;         // stores the memory address of i into iptr

In the above-given three statements, the first statement is:

int i = 100;

declares an integer pointer and initializes a value of "100" to it. Then comes the second statement, which is:

int *iptr;

declares an integer pointer named "iptr." Finally, using the third and last statement, which is:

iptr = &i;

initializes the variable "i"'s memory address to an integer pointer "iptr," so that the "iptr" now points to the memory location of "i." Therefore, to get the address of the variable "i," use "iptr," and to get the value of the same variable, use "*iptr." As an example:

#include<iostream>
using namespace std;

int main()
{
   int i = 100;
   int *iptr;
   iptr = &i;

   cout<<"iptr = "<<iptr<<endl;
   cout<<"*iptr = "<<*iptr<<endl;

   return 0;
}

The following snapshot shows the output produced by the above example.

c++ pointer declaration example

I used the "red arrow" to draw your attention to the actual output. Therefore, you can say that the "*" operator is also a unary operator that returns the value stored at the operand's address. The "*" is called the "value at" operator. You can use this operator before a pointer variable to get the value.

Note: The operand of the & operator is an ordinary variable, but the operand of the ∗ operator is a pointer variable.

Dereferencing is the process of changing or accessing the value pointed to by the pointer using the "∗" operator. Dereferencing refers to changing or accessing the state of the pointer.

The pointer operator ∗ (called the "at address" sign) is the same sign as the multiply operator ∗ and the pointer operator & (called the "address of" sign) is the same as the bitwise AND operator &. But these operators have no relationship to each other. Both pointer operator & and ∗ have a higher precedence than all other arithmetic operators except the unary minus, with which they have equal precedence.

C++ Pointers Initialization

Attention: A pointer variable must not remain uninitialized since uninitialized pointers cause the system to crash. Even if you do not have any legal pointer value to initialize a pointer, you can initialize it with a NULL pointer value.

Assigning NULL to a pointer initializes it to a value that is not a legal pointer, but it saves you from the "big" problem of uninitialized pointers. A program can later test a pointer against NULL (the zero pointer) to see whether it contains a legal pointer or not. For example, consider the following code fragment:

int ∗iptr = NULL;    // iptr is initialized but does not to a legal address
.
.
.
if(iptr != NULL)
{
   // use the pointer if it points to a legal address
}

The expressions (iptr != NULL) and (iptr) are equivalent.

When you use NULL for initializing pointers, then before using the pointer anywhere in the program, first check that it is non-zero or non-NULL, as shown in the above code fragment.

Let's look at the below statements to understand the concept of pointer initializations in C++:

int num = 20;
int *iptr;
iptr = &num;
int val = *iptr;

From the above statements, first a variable "num" of type int is created and initialized with a value of 20. Now a pointer variable "iptr" of type int is declared. And the address of the variable "num" is initialized to the pointer "iptr." Now the value present at the address "num" is initialized to the variable "val" of type int, which is 20 using the operator * (also called the "at address" or "value at address" operator).

nullptr in C++

In C++, a new keyword, namely nullptr, has been introduced, which is a distinguished null-point constant. So, from now on (assuming the compiler follows the C++ standard), you can initialize your pointers with nullptr, for example,

char ∗cptr = nullptr;
int ∗iptr = nullptr;

Difference between NULL and nullptr

The differences between NULL and nullptr are:

Here are examples demonstrating the difference between NULL and nullptr.

int f1(char∗);
int f1(int);

And if you have a pointer as

char ∗cptr = NULL;

Because NULL internally maps to an int, a function call f1(cptr) would always map to f1(int) rather than f1(char∗). But with nullptr, i.e.,

char ∗cptr = nullptr;

function call f1(cptr) will map to f1(char∗) only.

C++ Pointer Arithmetic

Pointers can only perform two arithmetic operations: addition and subtraction. When you add 1 to a pointer, you are actually adding the size of the object to which the pointer is pointing. In other words, when a pointer is incremented by one, it points to the memory location of the next element of its base type. Let us use an example to better understand it. Let iptr be an integer pointer pointing to memory address 1001 at the moment. Assuming the int size is four bytes, then after the expression

iptr++;

iptr will be pointing to 1005, not to 1002. Each time you increment iptr by 1, it will point to the next integer. Similarly, when you decrement iptr by 1, it will point to the location of the previous element of its base type (int here).

C++ Quiz


« Previous Tutorial Next Tutorial »


Liked this post? Share it!