Arrays are not pointers!
Arrays do decay to a pointer to their first element in all sorts of circumstances. For example std::cout << arr;
actually prints the memory address of the first element of the array. std::cout << &arr;
prints the memory address of the array. As the address of the first element is the same as the address of the array you see the same value.
However, just because they have the same value, does not mean they are the same. arr
can decay to a int*
, while &arr
is a pointer to an array, a int(*)[3]
.
I hope the following will help to clear things up a little:
#include <iostream>
#include <type_traits>
void make_it_decay(int x[]) {
std::cout << std::is_same_v< decltype(x), int*> << "\n";
}
int main() {
int arr[3] = {1,2,3};
//std::cout << (arr == &arr) << "\n"; // does not compile !
std::cout << (arr == &(arr[0])) << "\n";
std::cout << std::is_same_v< decltype(arr), int[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr),int(*)[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr[0]), int* > << "\n";
make_it_decay(arr);
}
output:
1
1
1
1
1
I use decltype
to infer the type of certain expressions and std::is_same_v
to see if the expressions are of same type.
arr
is of type int[3]
. It is an array. It is not a pointer.
&arr
is the address of the array. It is a pointer to an array with three elements, a int(*)[3]
.
&arr[0]
even though it has the same value as &arr
is of different type. It is a pointer to int
, an int*
.
When we pass arr
to a function then it decays to a pointer to the first element of the array. And we can see that inside the function x
is int*
.
Now to your quesiton...
Above I tried to lay out what happens when you write std::cout << arr
. Pointers are different, because ... well arrays are not pointers.
std::cout << ptr; // prints the value ptr
std::cout << &ptr; // prints the address of ptr
Perhaps some visualization helps. The difference in types gets most apparent when incrementing the pointers
-------------------
| arr |
-------------------
| 1 | 2 | 3 |
-------------------
^ ^ ^
&arr | &arr + 1
&arr[0] |
&arr[0] + 1