Arrays and pointers are NOT the same. In your case, the variable is a pointer, not an array. Even if they are not the same, the confusion is quite common and you will find in many places (including C/C++ books) that they are the same thing. This means that you should get acquainted to people calling pointers arrays.
When the C language was developed they decided that instead of passing arrays by value (possibly requiring a huge amount of copying and stack memory) they would convert silently the array into a pointer to the first element and then pass that pointer to the function.
void f( int a[3] ); // valid and misleading
// what it means:
// void f( int *a);
void test() {
int array[3];
f( array );
// what it means:
// f( & array[0] )
}
For backwards compatibility C++ keeps that feature around and you cannot pass arrays by value, nor define a function that takes an array by value (in both cases it will be converted to a pointer to the first element silently). At the same time, you can use the array access syntax on pointers to simplify pointer arithmetic, making it more confusing:
int array[3];
int *pointer = array; // simplified:
// int * pointer = & array[0]
pointer[2]; // equivalent to *(pointer+2) or array[2]
This means that with regular functions both in C and C++ arrays silently decay into pointers and most people will have the idea that they are the same thing: an array is a pointer to the first element. Well, they are not.
Both in C and C++ they are different entities, even if some usage patterns are equivalent due to that design decision. But they are in fact different:
int array[3]; sizeof(array); // 3*sizeof(int)
int *p1=array; // sizeof(int*), usually 4/8 bytes for 32/64 bit
int *p2=new int[3]; // sizeof(int*)
After passing through a function/method call, they are all pointers:
void f( int array[3] ) { sizeof(array); } // sizeof(int*) it is really a pointer! size is ignored
void g( int *p ) { sizeof(array); } // sizeof(int*)
In C++ things become even more interesting, as pass-by-value is not the only available paradigm and you can pass by reference:
void f( int (&array)[3] ); // funny syntax to pass an array of 3 integers by reference
void testf() {
int array1[3]; f(array1); // correct
int array2[2]; // f(array2); compilation error, it is not an array of 3 ints!
int *p = array1; // f(p); compilation error, it is not an array of 3 ints!
}
void g( int array[3] ); // means: void g( int *array );
void testg() {
int array1[3]; g(array1); // correct, the array decays into & array[0]
int array2[2]; g(array2); // correct, the array decays again
int *p = array1; g( p ); // correct it is a pointer
}
Note that when you define a function that takes an array by value you are actually defining a function that takes a pointer by value and that the compiler will not check that the argument to the function call actually has that size. This is a known source of errors and the reason why most functions that take arrays also take a size parameter.
Lastly, you cannot create arrays dynamically, you can only acquire memory dynamically into pointers, so when you need a heap allocated array you are actually in need of a pointer into a heap allocated contiguous block o memory:
void test() {
int *p = new int[3];
// int array[3] = new int[3]; // error!! an array is not a pointer
delete p;
}
At the end this all means that they are not the same thing, but that you can always use an array in the place of a pointer and it will be automatically converted by the compiler into a pointer to the first element of the array. More often than not, people will refer to pointers into a block of contiguously memory (whether stack or heap allocated) as array.