Consider the following code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 |
int main() { int x { 5 }; int *ptr { &value }; // ptr is a normal (non-const) pointer int y { 6 }; ptr = &y; // we can point at another value *ptr = 7; // we can change the value at the address being held return 0; } |
With normal (non-const) pointers, we can change both what the pointer is pointing at (by assigning it a new address to hold) or change the value at the address being held (by assigning a new value to the dereferenced pointer).
However, what happens if the value we want to point at is const?
1 2 3 4 5 6 7 |
int main() { const int x { 5 }; // x is now const int *ptr { &x }; // compile error: cannot convert const int* to int* return 0; } |
The above snippet won’t compile -- we can’t set a normal pointer to point at a const variable. This makes sense: a const variable is one whose value cannot be changed. Allowing the programmer to set a non-const pointer to a const value would allow the programmer to dereference the pointer and change the value. That would violate the const-ness of the variable.
Pointer to const value
A pointer to a const value (sometimes called a pointer to const
for short) is a (non-const) pointer that points to a constant value.
To declare a pointer to a const value
, use the const keyword before the pointer’s data type:
1 2 3 4 5 6 7 8 |
int main() { const int x{ 5 }; const int* ptr { &x }; // this is okay, ptr is pointing to a "const int" *ptr = 6; // not allowed, we can't change a const value return 0; } |
In the above example, ptr
points to a const int. Because ptr
points to a const int, the value being pointed to can’t be changed.
Just like a reference to const
, a pointer to const
can point to non-const variables too. A pointer to const
treats its value as constant, regardless of whether the variable at the address being held was defined as const or not.
Thus, the following is okay:
1 2 3 4 5 6 7 8 9 10 11 |
int main() { int x{ 5 }; // non-const const int* ptr { &x }; // ptr points to a "const int" *ptr = 6; // not allowed: ptr points to a "const int" so we can't change the value through ptr value = 6; // allowed: the value is still non-const when accessed through a non-const identifier return 0; } |
Because a pointer to const
is not const itself (it just points to a const value), the pointer can be redirected to point at other values:
1 2 3 4 5 6 7 8 9 10 |
int main() { int x{ 5 }; const int *ptr { &value1 }; // ptr points to a const int int y{ 6 }; ptr = &value2; // okay, ptr now points at some other const int return 0; } |
Const pointers
We can also make a pointer itself constant. A const pointer is a pointer whose value can not be changed after initialization.
To declare a const pointer
, use the const keyword between the asterisk and the pointer’s name:
1 2 3 4 5 6 7 |
int main() { int x{ 5 }; int* const ptr { &x }; // const after the pointer type means this is a const pointer return 0; } |
In the above case, ptr
is a const pointer to a non-const int value.
Just like a normal const variable, a const pointer must be initialized upon definition. This means a const pointer will always point to the same address. In the above case, ptr
will always point to the address of x
(until ptr
goes out of scope and is destroyed) and this cannot be changed.
1 2 3 4 5 6 7 8 9 10 |
int main() { int x{ 5 }; int y{ 6 }; int* const ptr { &x }; // okay, the const pointer is initialized to the address of value1 ptr = &y; // Error: once initialized, a const pointer can not be changed. return 0; } |
However, because the value being pointed to is still non-const, it is possible to change the value being pointed to via dereferencing the const pointer:
1 2 3 4 5 6 7 8 |
int main() { int x{ 5 }; int *const ptr { &x }; // ptr will always point to x *ptr = 6; // allowed, since the value being pointed to is non-const return 0; } |
Const pointer to a const value
Finally, it is possible to declare a const pointer to a const value by using the const keyword both before the type and before the variable name:
1 2 3 4 5 6 7 |
int main() { int value { 5 }; const int* const ptr { &value }; // a const pointer to a const value return 0; } |
A const pointer to a const value
can not be set to point to another address, nor can the value it is pointing to be changed through the pointer. It can only be dereferenced to get the value it is pointing at.
Pointer and const recap
To summarize, you only need to remember 4 rules, and they are pretty logical:
- A non-const pointer can be redirected to point to other addresses.
- A const pointer always points to the same address, and this address can not be changed.
- A pointer to a non-const value can change the value it is pointing to. These can not point to a const value.
- A pointer to a const value treats the value as const when accessed through the pointer, and thus can not change the value it is pointing to. These can be pointed to const or non-const l-values (but not r-values, which don’t have an address)
Keeping straight the declaration syntax can be challenging. Just remember that the type of value the pointer points to is always on the far left:
1 2 3 4 5 6 7 8 9 10 |
int main() { int value { 5 }; const int* ptr1 { &value }; // ptr1 points to a "const int", but is not const itself, so this is a pointer to a const value. int* const ptr2 { &value }; // ptr2 points to an "int", but is const itself, so this is a const pointer to a non-const value. const int* const ptr3 { &value }; // ptr3 points to an "const int", and it is const itself, so this is a const pointer to a const value. return 0; } |
![]() |
![]() |
![]() |
If (int *const pnPtr = &nValue;) and
(const int *pnPtr = &nValue;) are possible
Can we use (int const * pnPtr = &nValue;)as well?
Thanks
This seems to be a very silly naming system. Shouldn't 'a pointer to a constant variable' be called a 'read only pointer' or something?
hai
this site very use full and can i know
1.difference between free() and exit().
2.on exit() dynamic memory will be freed with out using free()
int main()
{
char *ptr=(char*)malloc(100);
ptr +=50;
free(ptr);
printf("hai\n ");
exit(0);
}
#include
int main()
{
using namespace std;
int nvalue=10;
int nvalue2=5;
const int *ptr=&nvalue;
nvalue=20;
cout << *ptr << endl;
cout << nvalue << endl;
return 0;
}
output:
20
20
why so..?? the value of nvalue should be constant to 10 if we access it through *ptr but here its changing to 20 even if we are accessing it through *ptr...may b m lacking in understanding the concept...still can some1 plz clarify me dis...
Please correct me if I am wrong. I think that the relation between pointers and constant can be best understood when seen from pointers' point of view.
CONSTANT POINTER : is a pointer which is constant; meaning it holds a constant value (address which it points to). that is, it constantly points to the address of a variable (assigned during declaration). the variable may not be a constant. thus the constant pointer points to one unique address and can manipulate the variable that has that address. hence,
int nValue = 5;
int *const pnPtr = &nValue;
*pnPtr = 6; // it is possible !!
nValue = 7; // this is also possible !! inadvertently skipped in this tutorial i guess
POINTER TO A CONSTANT VARIABLE :
the variable may not be a constant but still, when declared this way, the pointer treats the variable as a constant.
int nValue = 5;
const int *pnPtrt = &nValue; // POINTER TO A CONSTANT VARIABLE
nValue = 6; // this can be done as the variable need not be constant
however, *pnPtr = 7; will cause program to crash because the pointer pnPtr treats nValue as a constant.
CONSTANT POINTER TO A CONSTANT VARIABLE :
here, both the pointer as well as the variable, are constant.
const int nValue = 5;
const int *const pnPtr = &nValue;
nValue = 6; // not possible because nValue is a constant
*pnPtr = 6; // not possible because pnPtr is pointer to a constant ( and not because pnPtr is a constant pointer !)
So far i uderstand the pointers but i need to practice,any help ?
Hi there,
I don't understand what the benefit is when we declare a pointer as constant.
Any help?
Dear Alex,
This tutorial is awesome! As I am going through it, I am building a program that will play Minesweeper by itself. It works right now, but I am modifying it daily to apply the good programming practices I am learning here.
Anyway, I see you typed: "a const pointer will always point to the same value".
Did you mean: "a const pointer will always point to the same location"?
Maybe I'm just not understanding it.
In this case, both the value and locations would be the same, no?