As mentioned in other answers, arrays are not pointers. They decay into pointers in some contexts, true, but only in some contexts.
int a[] = {1, 2, 3, 4, 5};
Type of a
is int [5]
, an array with five elements of type int
. In this case a pair of empty square brackets tell the compiler to deduce the number of elements, so you definition is equivalent to int a[5] = {1, 2, 3, 4, 5};
.
If you are still not convinced, here is a piece of code that tries to make a compiler emit an error message containing the type of a
:
template <typename T> struct Type;
int main()
{
int a[] = {1, 2, 3, 4, 5};
Type<decltype(a)> dummy;
}
g++ 5.3 emits
error: aggregate ‘Type<int [5]> dummy’ has incomplete type and cannot be defined
As you can see, decltype(a) is int [5]
.
cppreference.com contains a detailed explanation of range-based for loop.
Your for loop is equivalent to:
{
auto && __range = a;
for (auto __begin = a, __end = a + 5; __begin != __end; ++__begin)
{
int i = *__begin;
std::printf("%d\n", i);
}
}
To summarize: T [N]
is a type: an array with N
elements of type T
. N
is an integral constant known at compile-time, so the compiler knows where the last element of the array is, and hence is able to generate a loop that iterates over all the elements.
If you want to know more about array decay, I suggest reading What is array decaying?.