I am a beginner to data structures and algorithms, started studying the pointers now and before asking the question here I read this recommended post but I couldn't understand it so I am asking the query here.
I have been told by a friend that array's name is a pointer to the first value in the array, as arr returns the address of arr[0], arr+1 returns address of arr[1], so when I write this
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i = 10;
int arr[3] = {1, 2, 3};
int *ptr = &i;
cout << arr << " " << &arr << endl;
cout << ptr << " " << &ptr;
return 0;
}
Both arr and &arr give same result
0x61ff00 0x61ff00
While ptr and &ptr give different results
0x61ff0c 0x61fefc
Can someone tell me why is this happening ?
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);
}
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