A pointer is a type of variable which is used to store an object's memory address.
Both C and C++ make significant use of pointers for three key reasons:
For all of these situations, raw pointers are used in C-style programming. Raw pointers, however, are the cause of numerous critical programming errors. Therefore, unless they significantly improve efficiency and there is no doubt as to whose pointer owns the object and is in charge of destroying it, their use is strongly banned. Modern C++ offers lambda expressions for passing functions, smart pointers for allocating objects, and iterators mainly for traversing data structures. Instead of utilizing raw pointers, use these language and library features to make your program safer, simpler to understand, as well as easier to maintain.
Learning C++ pointers is simple and exciting. Pointers are useful for performing some C++ actions more quickly, and they are also very essential for performing others C++ tasks including dynamic memory allocation.
As you are aware, every variable is a memory location with a defined address that can be accessed using the ampersand (&) operator, which stands for a memory address.
A pointer variable's content is not initialized when it is declared. In other words, it has a location of "anywhere," which is obviously an invalid address. It's risky! A pointer needs to be initialized by having an actual address assigned to it. Typically, the address-of-operator (&) is used for this.
We know that everything in programming is stored in a memory and each and every memory cell comprises two entities-- one is the address location and the other is the value stored in it.
The address of the variable is returned by the address-of operator (&), which acts on a variable. For instance, if the variable number is an int, the address of the variable number is returned by &number.
The address of a variable can be obtained using the address-of operator, and the address can then be assigned to a pointer variable.
Suppose that we declare a variable,v, of type int and initialize it with value 1.
int v = 1;
The value 1 will be stored in the address location, say here 2000, and ‘v’ will point to or contain the value 1. The next integer type value will be allocated in the successive memory location as given above on declaration. This indicates that each variable will have a unique address location irrespective of its values. To get the address of a variable we use the ampersand( &) prior to the variable.
&v;
Look at the example of a C++ program that is given below, which prints the address of the defined variables
#include <iostream>
using namespace std;
int main () {
int var1;
char var2[20];
cout << "Address of var1 variable will be: ";
cout << &var1 << endl;
cout << "Address of var2 variable will be: ";
cout << &var2 << endl;
return 0;
}
Output:
Address of var1 variable will be: 0x7fff0fb6d57c Address of var2 variable will be: 0x7fff0fb6d560
A variable that contains the address of another variable is known as a pointer. Before using a pointer, just like any variable or constant, you should declare it.
type *var_name;
Here, var_name is the pointer variable's name, and type is the base type of the pointer; that must be a valid C++ type. The same asterisk that you used to declare a pointer is also used for multiplication. However, the asterisk in this sentence indicates that a variable is a pointer.
int *ip; // pointer mainly to an integer
double *dp; // pointer mainly to a double
float *fp; // pointer mainly to a float
char *ch // pointer mainly to a character
All pointers, regardless of whether they are integer, float, character, or another type, actually have the same value, which is a lengthy hexadecimal number that corresponds to a memory address. The variable or constant that a pointer points to is the only main thing that differentiates pointers of various data types.
A few key operations will be performed with pointers quite frequently such as:
This is accomplished by using the unary operator *, which returns the value of the variable at the address indicated by its operand.
These operations are used in the example which is given below.
#include <iostream>
using namespace std;
int main () {
int var = 40; // the actual variable declaration.
int *ip; // the pointer variable
ip = &var; // store address of var in pointer variable
cout << "The Value of var variable will be: ";
cout << var << endl;
// now print the address which is stored in ip pointer variable
cout << "The Address stored in ip variable will be: ";
cout << ip << endl;
// now access the value at the address available in pointer
cout << " The Value of *ip variable will be: ";
cout << *ip << endl;
return 0;
}
Output:
The value of var variable will be: 40 The address stored in ip variable will be: 0x7ffe608a7fa4 The value of *ip variable will be: 40
Let us write another C++ program in order to demonstrate the use of * for pointers in C++.
#include <iostream>
using namespace std;
int main()
{
// its a normal kind integer variable
int Var = 20;
// A pointer variable which holds address of var.
int *ptr = &Var;
// This line will mainly prints value at address which is stored in ptr.
// Value stored isthe value of variable "var"
cout << "Value of Var = "<< *ptr << endl;
cout << "Address of Var = " << ptr << endl;
// We can also use ptr as lvalue (Left hand
// side of assignment)
*ptr = 40; // Value at address is now 20
// This prints 40
cout << "After doing *ptr = 40, *ptr is "<< *ptr << endl;
return 0;
}
Output:
Value of Var = 20 Address of Var = 0x7ffe7cb29f8c After doing *ptr = 40, *ptr is 40
The C++ language makes extensive use of pointers.
With the help of the pointer-based malloc() and calloc() methods in the C programming language, we may dynamically allocate memory.
In arrays, functions, and structures in the C language, pointers are frequently employed. Performance is enhanced while the code is reduced.
Null pointers, pointer arithmetic, pointers vs arrays, an array of pointers, pointer to pointer, and passing pointers to functions, and these are some of the very important concepts within pointers. Pointers have a wide variety of simple concepts, and they are very important for C++ programming.
The following are a few essential pointer principles that every C++ programmer should understand: that will be discussed in the next tutorials.
Sr.No | Concept & Description |
---|---|
1 | Null Pointers
C++ supports null pointers. Null pointers are those to which NULL has been assigned. |
2 | Pointer Arithmetic
You can execute arithmetic operations on a pointer just like you can on a numeric value : ++, --, +, - |
3 | Pointers vs Arrays
There is a deep connection between the pointers and arrays. |
4 | Array of Pointers
You can define arrays to hold a number of pointers. |
5 | Pointer to Pointer
C++ allows you to have a pointer on a pointer and so on. |
6 | Passing Pointers to Functions
Passing an argument by reference or by address enables the passed argument to be changed in the calling function by the called function. |
7 | Return Pointer from Functions
C++ allows a function to return a pointer to a local variable, static variable, and dynamically allocated memory as well. |
A pointer to a pointer is considered as a type of multiple indirections or just as a chain of pointers. A pointer typically contains a variable's address. In the definition of a pointer to a pointer, the first pointer includes the address of the second pointer and this identifies the place where the real value is located, as illustrated below.
A pointer to a pointer variable must be described as such. An additional asterisk is added in front of its name to indicate this. For example, the declaration in order to declare a pointer to a pointer of type int is as follows
int **var;
The asterisk operator must be used twice to access a target value when it is indirectly pointed to by a pointer to a pointer, as demonstrated in the example below.
#include <iostream>
using namespace std;
int main () {
int var;
int *ptr;
int **pptr;
var = 5000;
// take the address of var
ptr = &var;
// using address of operator & take the address of ptr
pptr = &ptr;
// using pptr take the value
cout << "The value of var :" << var << endl;
cout << "The value is available at *ptr :" << *ptr << endl;
cout << "The Value is available at **pptr :" << **pptr << endl;
return 0;
}
Output:
The value of var :5000 The value is available at *ptr :5000 The Value is available at **pptr :5000
A pointer can be passed to a function in C++. For that simply declare the function parameter mainly as a pointer type.
Let us use a very straightforward C++ program as an example of passing an unsigned long pointer to a function and changing the value inside it to cause a reflection in the caller function.
#include <iostream>
#include <ctime>
using namespace std;
void getSeconds(unsigned long *par);
int main () {
unsigned long sec;
getSeconds( &sec );
// print the actual value
cout << "Number of seconds will be:" << sec << endl;
return 0;
}
void getSeconds(unsigned long *par) {
// get the current number of seconds
*par = time( NULL );
return;
}
Output:
Number of seconds will be:1660158812
Now let us see an example of a function that can accept a pointer as well as it can also accept an array
#include <iostream>
using namespace std;
// function declaration:
double getAverage(int *arr, int size);
int main () {
// an int array with 6 elements.
int balance[5] = {1000, 20000, 3000, 1700, 5200};
double avg;
// now pass the pointer to the array as an argument.
avg = getAverage( balance, 6 ) ;
// output the returned value
cout << "Average value is will be: " << avg << endl;
return 0;
}
double getAverage(int *arr, int size) {
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
Output:
Average value is will be: 10610.7
Similar to how C++ allows you to return an array from a function as we saw in a previous topic, C++ also permits you to return a pointer from a function. You would have to declare a function returning a pointer, as in the example below,
int * myFunction() {
.
.
.
}
The second thing to keep in mind is that returning the address of a local variable outside of the function is not a smart idea, thus you should define the local variable as a static variable.
Now have a look at the code below, which will produce 10 random integers and return them using an array name that mainly represents a pointer, that is the address of the very first array element.
#include <iostream>
#include <ctime>
using namespace std;
// function mainly to generate as well as to retrun random numbers.
int * getRandom( ) {
static int r[12];
// set the seed
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 12; ++i) {
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// main function to call above defined function.
int main () {
// a pointer to an int.
int *p;
p = getRandom();
for ( int i = 0; i < 12; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
Output:
1238517784 1706475627 84960591 958048303 73893020 158631104 477142828 2116082795 832547651 1809736359 615981633 938663983 *(p + 0) : 1238517784 *(p + 1) : 1706475627 *(p + 2) : 84960591 *(p + 3) : 958048303 *(p + 4) : 73893020 *(p + 5) : 158631104 *(p + 6) : 477142828 *(p + 7) : 2116082795 *(p + 8) : 832547651 *(p + 9) : 1809736359 *(p + 10) : 615981633 *(p + 11) : 938663983