An Intensive Study Of Pointers And Their Uses In C++.
A Pointer is one of the most powerful features of C++ language. A pointer helps to manipulate the variables through its address.
In this tutorial, we will explore all about pointers and its uses in C++ in detail.
=> Watch Out The Simple C++ Training Series Here.
What You Will Learn:
What Is A Pointer?
A pointer is a variable that holds the address of a memory location. We know that all the variables we declare, have a specific address in memory. We declare a pointer variable to point to these addresses in memory.
The general syntax for declaring a pointer variable is:
datatype * variable_name;
For Example, the declaration int* ptr;
This means ptr is a pointer that points to a variable of type int. Hence a pointer variable always contains a memory location or address. Let us see the working of pointer variables below.
Consider we have the following declarations:
Int p, *ptr; //declare variable p and pointer variable ptr p = 4; //assign value 4 to variable p ptr = &p; //assign address of p to pointer variable ptr
In memory, these declarations will be represented as follows:
This is the internal representation of pointer in memory. When we assign the address variable to the pointer variable, it points to the variable as shown in the representation above.
As ptr has an address of variable p, *ptr will give the value of variable p (variable the pointer variable ptr is pointing to).
Note: The operator * that we use with the pointer is used to denote that it is a pointer variable.
Let us see some of the pointer concepts that are used in C++.
Pointer Arithmetic
We know that a pointer variable always points to the address in memory. Among the operations that we can perform, we have the following arithmetic operations that are carried out on pointers.
- Increment operator (++)
- Decrement operator (–)
- Addition (+)
- Subtraction (-)
Let us see the usage of these operations in an Example program.
#include <iostream> #include <string> using namespace std; int main() { int myarray[5] = {2, 4,6, 8,10}; int* myptr; myptr = myarray; cout<<"First element in the array :"<<*myptr<<endl; myptr ++; cout<<"next element in the array :"<<*myptr<<endl; myptr +=1; cout<<"next element in the array :"<<*myptr<<endl; myptr--; cout<<"next element in the array :"<<*myptr<<endl; myptr -= 1; cout<<"next element in the array :"<<*myptr<<endl; return 0; }
Output:
First element in the array :2
next element in the array :4
next element in the array :6
next element in the array :4
next element in the array :2
We have seen the arithmetic operations carried out on pointers. Note that the increment operator ++ increments the pointer and points to the next element in the array. Similarly, the decrement operator decrements the pointer variable by 1 so that it points to the previous element in the array.
We also use + and – operators. First, we have added 1 to the pointer variable. The result shows that it points to the next element in the array. Similarly, – operator makes the pointer variable to point to the previous element in the array.
Apart from these arithmetic operators, we can also use comparison operators like ==, < and >.
Null And Void pointers
If in case, a pointer variable is not assigned an address of a variable, then it is a good practice to assign a NULL value to the pointer variable. Pointer variable with a NULL value is called the NULL pointer.
A null pointer is a constant pointer with value zero defined in the iostream header. The memory at address 0 is reserved by the operating system and we cannot access this location.
Using the null pointer, we can avoid the misuse of unused pointers and prevent pointer variables from having some garbage values assigned to them.
Void pointers are the special pointers that point to the values with no type. The void pointers are more flexible as they can point to any type. But they cannot be directly dereferenced. For dereferencing, the void pointer needs to be converted to a pointer that points to a value with the concrete data type.
We have shown the working of the NULL pointer & void pointer in the following code Example.
#include <iostream> #include <string> using namespace std; int main() { int intvar = 10; char c = 'A'; void* vptr; int* myptr = NULL; cout<<"NULL pointer value :"<<myptr<<endl; vptr = &c; char* charptr; charptr = (char*)vptr; cout<<"Void pointer vptr points to:"<<*charptr<<endl; int* intptr; vptr = &intvar; intptr = (int*)vptr; cout<<"Void pointer vptr points to:"<<*intptr; return 0; }
Output:
NULL pointer value :0
Void pointer vptr points to:A
Void pointer vptr points to:10
In the above program, first, we declare an integer pointer that is assigned a value NULL. When we print this pointer, we see that the value is 0 as we have discussed earlier.
Next, we declare a void pointer. First, we assign an address of character variable to this void pointer. Then we assign void pointer to a character pointer and typecast it with char*. Next, we print charptr value that points to char A which was a character variable that we declared earlier and is pointed by the void pointer.
Next, we have assigned an integer variable to the void pointer and then we carry out the same steps of dereferencing this void pointer by using an integer pointer.
Arrays And Pointers
Arrays and pointers are strongly associated with one another. We know that the name of the array points to the first element in the array and this is a constant pointer.
We can assign this pointer to a pointer variable and then access the array either by decrementing the pointer or by using the subscript operator.
We will see this association between the pointer variable and array in the following code Example.
#include <iostream> #include <string> using namespace std; int main() { int myarray[5] = {1, 1, 2, 3, 5}; int* ptrvar; ptrvar = myarray; for(int i=0;i<5;i++) { cout<<*ptrvar<<"\t"; ptrvar++; } return 0; }
Output:
1 1 2 3 5
In the above program, we assign the array name to a pointer variable. As the array name points to the first element in the array, we can print the contents of the entire array by using a pointer variable and increment it using the ++ operator. This is shown in the output.
Array Of Pointers
Sometimes, we need more than one pointer variables in a program. Instead of declaring each individual pointer variable, we can declare an array of pointers.
Let us straightaway take an Example to demonstrate an array of pointers.
#include <iostream> #include <string> using namespace std; int main() { int myarray[5] = {2,4,6,8,10}; int *ptr[5]; //array of pointers for(int i=0;i<5;i++){ ptr[i] = &myarray[i]; } for (int i = 0; i < 5; i++) { cout << "Value of myarray[" << i << "] = "; cout << *ptr[i] << endl; } return 0; }
Output:
Value of myarray[0] = 2
Value of myarray[1] = 4
Value of myarray[2] = 6
Value of myarray[3] = 8
Value of myarray[4] = 10
In the declaration in the above,
int *ptr[5];
We can interpret as; ptr is an array of 5 integer pointers. Hence each element of ptr will point to a variable of type integer.
We make use of an integer array and assign the address of each element of the array to each of the ptr elements. Then we display the contents of ptr array by outputting “*ptr[i]”.
Pointer Of Pointers
The pointer of pointers is nothing but multiple indirections. It is a kind of chain of pointers. When we define a pointer of pointers, the first pointer has an address of the second pointer, which in turn has the address of the variable which it points to.
In memory, this will be represented as:
A pointer of pointers is declared as follows:
int** intptr;
We directly take a code Example to better understand the pointer of pointers.
#include <iostream> #include <string> using namespace std; int main() { int *vptr; int ** intptr; int var = 10; vptr = &var; intptr = &vptr; cout<<"Variable var: "<<var<<endl; cout<<"Pointer to Variable: "<<*vptr<<endl; cout<<"Pointer to Pointer to a variable: "<<**intptr; return 0; }
Output:
Variable var: 10
Pointer to Variable: 10
Pointer to Pointer to a variable: 10
In the above program, we declare an integer variable, an integer pointer and a pointer of a pointer to an integer. As shown in the program, the pointer variable is assigned the value of a variable. The pointer of the pointer variable is assigned the address of the pointer variable.
In the end, we print the three variables that display the same value 10 equal to an integer variable.
Passing Pointers To Functions
Passing pointers to function is the same as other parameter passing techniques wherein we pass pointer variables to the function.
We revisit our swapping two values and modify it to pass pointer variables as parameters.
#include <iostream> #include <string> using namespace std; void swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; } int main() { int a, b; cout<<"Enter the values to be swapped: "; cin>>a>>b; cout<<"a = "<<a<<"\t"<<"b = "<<b; swap(&a,&b); cout<<endl; cout<<"Swapped values"<<endl; cout<<"a = "<<a<<"\t"<<"b = "<<b; return 0; }
Output:
Enter the values to be swapped: 3 2
a = 3 b = 2
Swapped values
a = 2 b = 3
As shown in the program, we pass the values to be swapped as integer variables. The formal parameters are defined as pointer variables. As a result of this, the changes made to the variables inside the functions are reflected outside in the calling function as well.
Function Pointers
in the same way, as we have pointers to variables, arrays, etc., we can also have pointers to functions. But the difference is that the function pointer points to the executable code and not to data like variables or arrays.
We take an Example to demonstrate function pointers.
#include <iostream> #include <string> using namespace std; void displayVal(int a) { printf("Value of a is %d\n", a); } int main() { void (*func_ptr)(int) = &displayVal; (*func_ptr)(100); return 0; }
Output:
Value of a is 100
In the above program, we have a function ‘displayVal’ which just prints an integer value passed to it. In the main function, we have defined a function pointer ‘func_ptr’ which takes an int as an argument and returns a void type.
void (*func_ptr)(int)
Note: We need to enclose function pointer inside (). If we omit it, it will become a function prototype.
We have assigned the address of the function ‘displayVal’ to this function pointer. Then using this function pointer ‘func_ptr’ we pass the argument value 100 which is equivalent to calling displayVal with argument 100.
Now if we have another function with the same prototype, then we can use the same function pointer by assigning the address of the function to it. This is the major use of function pointers.
Conclusion
This is all about the pointers, its definitions and uses in C++.
In our next tutorial, we will learn more about references in C++. References also have special use in C++ and are often used as aliases for variables.