Using Pointers
Explanation and application of Pointer Arithmetics and the NULL pointer.
Overview:
You’ve read the basic introduction to C++ pointers and now have a strong foundation on their basic operators and usefulness. Now, take a step further into learning why pointers are useful and where and how to use them. Follow along this tutorial to learn how to perform arithmetic operations on pointers and also make use of NULL pointers.
What are pointers?
A pointer is a variable that can store a physical address of another variable. A pointer has access to the value pointed to by the variable and also the ability to reassign it’s value. Furthermore, the pointer itself can be reassigned to a new variable. Let’s keep this much in mind as we learn about how pointers behave arithmetically and how we can take advantage of them and NULL pointers practically.
What is Pointer Arithmetics?
The address stored in pointers are numerical values. Therefore, we can perform arithmetic operations on these values.
What do you mean by arithmetic operations?
Primary arithmetic operations include addition, subtraction, multiplication and division. However, we can only perform addition and subtraction on pointers. These operations help pointers conveniently traverse through memory addresses and do what they do, like read and write values pointed to by it. Let’s look at an example to see it in action:
char * mychar;
short * myshort;
long * mylong;
Here, we have declared three different pointers with three different data types. The size in bytes of each of the data types are 1 byte, 2 bytes and 4 bytes respectively. For simplicity, let’s assume the values of the addresses in the declarations above to be 1000, 2000 and 3000 respectively. Next, we are going to increment each pointer.
++mychar;
++myshort;
++mylong;
After incrementing, mychar will contain the value 1001. However, not so obviously, myshort will contain 2002 and mylong will contain 3004.
Wait, why?
The answer to your question can be found at the pointer declaration. The reason we specify a data type for a pointer is because the behavior of the pointer differs depending on its type. Specifically, while incrementing or decrementing, the pointer adds or subtracts the size of the type to or from it. In this particular example, the size in bytes of the type it points to is added to the pointer. This behavior exists because when incrementing a pointer, the pointer is made to point to the following element of the same type, therefore, adding the size in bytes of the type of the pointer.
What are Null Pointers?
Pointers by design can point to any address, even if the address does not point to any value.
int * p;
In the above example, the pointer p holds an address to a nonexistent value. Such cases will cause an error when trying to dereference the pointer.
A common convention to avoid these errors is to assign NULL to a pointer variable in case it does not have exact address to be assigned. Let’s look at some examples of various ways to declare null pointers.
int * p = 0;
int * q = nullptr;
int * r = NULL;
Null pointers create convenience for programmers because it now points to 0 instead of an address with no value to dereference. The following is an example of a null pointers in real programs.
if(ptr) // succeeds if p is not null
if(!ptr) // succeeds if p is null
In a nutshell:
Pointers can be incremented or decremented according to the data type it was declared as. This behavior is especially useful for pointers to traverse through physical addresses in memory and do what they do, like accessing or reassigning the value it points to. Pointers can cause errors if it holds an address to a nonexistent value. Common convention to avoid these values is to use NULL pointers.