C++ being built on top of C language has readily inherited many core features, which include Pointers. Pointers were proven to be handy when it comes to working with data at memory level Statically or Dynamically. Many Programming Languages use Pointers in some or the other way.
Why Bother Learning Pointers?
Yes, it is so true that the same task could be accomplished without the use of pointers, but we must acknowledge that the proper use of pointers can make code more short, compact, and efficient at the same time.
C++ Pointers in Brief
Pointers were mainly introduced to peek and poke the data from memory effectively. Pointers were made to hold the memory addresses (i.e physical address/memory location) so that one could refer to the data at that memory location through pointers.
So What Is a Pointer?
Programmatically, a Pointer is a variable that can hold the address of other variables as its value and can indirectly refer to the contents of that memory address.
Pointer as a Variable
Yes, a pointer is a variable, which means that at some given time it can point to a variable (i.e hold the address of that variable) and next time it can point to some other variable of the same type (datatype).
Pointer as a constant
We can make a pointer constant which means it cannot point to other memory addresses with the use of const qualifier which we will see in the later parts. Before Moving into the Pointers Jargons, consider the following declaration:
int val = 100;
The above statement commands the compiler to
- Reserve memory space to hold an integer value.
- Associate name value to it.
- Assign value 100 to it.
Memory Map for the above statement are as follow:
As we can see, the compiler has chosen the memory location 65545 (Machine specific) to store the value 100. We can print this memory address as:
cout << &val; //prints the memory address of variable called val
We can store this address into a variable and refer to the value indirectly through that variable and here comes pointers into the limelight.
Had the pointers been the same as ordinary variables, there wouldn’t have been any need to grasp them separately, so for sure pointers are not ordinary variables. Let’s take a look into the syntax of a pointer.
Here data_type refers to the data type of the variable whose address is going to be stored in the pointer variable. Alternatively, we can say that pointer is gonna point to a variable whose value is of type data_type.
Some valid examples of pointer declarations are as follows:
Note that the space isn’t necessary but the *(asterisk) should be in between data_type and variable_name.
Consider the following pointer assignment statement:
Now we have successfully stored the address of val into ptr thus we can refer to val through ptr as:
Two Key Operators
Working of Pointers
Now since we have the address of val variable in ptr, we can now access and manipulate the data stored at the memory address contained in ptr.
Below is the implementation of a simple program using pointer:
Thus not only we can access val with *ptr but also can change the data (or reassign) to any value of the same data type.
Since a pointer is a variable, it does occupy a space in memory and we can even store this address into another pointer variable, which would be called pointer to pointer. This way we can create a pointer to pointer to pointer to pointer and so on. For now, we would stick to a pointer to a pointer.
The declarative syntax of pointer to a pointer is given below:
We can refer to the ptr contents as
cout << *d_ptr << ptr << &val; //eg 65545 65545 65545 i.e address of val
Since *d_ptr value is an address (address of val) thus we can access the actual data of val through the following statement.
To manipulate the content of val through d_ptr we can write as
**d_ptr = 2000;
Function Returning More Than One Value
We are aware that normally a function can return at most one value at a time. What if we need to return more than one value from a function? The Naive approach would be to make that many functions return different values. The other handy option is to use pointers making code more efficient
Types of Pointers
The types of pointers which should be known to a programmer are:
When a pointer doesn’t point to any valid memory location we should make to point it to null (i.e absence of value).
int *ptr = NULL;
When a pointer needs to point to only one memory location throughout its lifetime i.e it should be changed, then we can declare the pointer as constant.
When we are not sure what the pointer is gonna point to .i.e would it point to an int or float or char? In such a situation, we should declare the pointer as a void pointer and explicitly make it point to a variable of any data type as desirable.
When a pointer is trying to point to a memory location that is not available or inaccessible or freed (using a free function). Then the pointer is called a dangling pointer.
An awesome feature of pointers is that they can move in memory to and fro. They jump forward or backward with each step equal to the memory size they are pointing to. For eg.
Advantages of Pointers
The major advantages of pointers are:
- Makes the function return more than one variable at the same time.
- Makes code way shorter, compact resulting in increased speed of execution.
- Dynamic memory allocation and deallocation are possible only with the use of pointers.
- To implement various data structures (eg. Linked Lists, Trees, et)
Thus we can sum up by saying that a pointer is a construct that can point to a memory location and indirectly access and modify the contents inside it. From making function return multiple values to dynamic memory allocation pointers have shown their superpowers. Thus if a solution could be approached with the use of pointers, it should be solved with the use of pointers making code more efficient.