The main difference between arrays and pointers is that they are completely different things.
As array is a collection of objects, which is laid out contiguously in memory. For example, int x[5]
defines an array named x
, which is a collection of 5
integers, laid out side by side in memory. Individual elements in the array may be accessed using "array syntax" of the form x[i]
where i
is an integral value with values between 0
and 4
. (Other values of i
will result in undefined behaviour).
A pointer is a variable which holds a value that is an address in memory. For example, int *p
defines p
as a pointer to an int
, and it can be initialised with the address of a variable of type int
. For example, p = &some_int
causes p
to contain the address of some_int
. When that is done, the notation *p
(called dereferencing) provides access to the pointed-to variable. For example, *p = 42
will set some_int
to have the value 42
.
You'll notice, in the description above, I have not used the word "pointer" in describing an array, nor have I used the word "array" to describe a pointer. They are completely different things.
However, they can be used in ways that makes them seem the same, because of a few rules in the language. Firstly, there is a conversion called the "array-to-pointer" conversion. Because of this, it is possible to do
int x[5];
int *p = x;
The initialisation of p
actually works by using the array-to-pointer conversion. Because it is being used to initialise a pointer, the compiler implicitly converts x
to a pointer, equal to the address of x[0]
. To do this explicitly (without the compiler silently and sneakily doing a conversion) you could have written
int *p = &x[0];
and got exactly the same effect. Either way, the assignment *p = 42
will subsequently have the effect of assigning x[0]
to 42
.
That suggests there is a relationship between expressions involving pointers and expressions involving (the name of) arrays. If p
is equal to &x[0]
, then
p + i
is equivalent to &x[i]
; AND
*(p + i)
is equivalent to x[i]
.
The language rules of C and C++ make these relationships symmetric, so (look carefully here)
x + i
is equivalent to &x[i]
; AND
*(x + i)
is equivalent to x[i]
and, with pointers
p + i
is equivalent to &p[i]
; AND
*(p + i)
is equivalent to p[i]
Which basically means that pointer syntax can be used to work with arrays (thanks to the pointer-to-array conversion) AND array syntax can be used to work with pointers.
Really bad textbooks then go on from this and conclude that pointers are arrays and that arrays are pointers. But they are not. If you find textbooks which say such things, burn them. Arrays and pointers are different things entirely. What we have here is a syntactic equivalence - even though arrays and pointers are different things entirely, they can be worked on using the same syntax.
One of the differences - where the syntactic equivalence does not apply - is that arrays cannot be reassigned. For example;
int x[5];
int y[5];
int *p = y; // OK - pointer to array conversion
x = y; // error since x is an array
x = p; // error since x is an array
The last two statements will be diagnosed by a C or C++ compiler as an error, because x
is an array.
Your example
int *pointer = new int[10];
is a little different again. pointer
is still not an array. It is a pointer, initialised with a "new expression", which dynamically allocates an array of 10
integers. But because of the syntactic equivalence of pointers and arrays, pointer
can be treated syntactically AS IF it is an array of 10
elements.
Note: the above is concerned with raw arrays. The C++ standard library also has a type named std::array
which is a data structure which contains an array, but behaves somewhat differently than described here.