These are arrays:
int a[10];
int b[10][20];
These are pointers:
int *p1;
int (*p2)[20];
They are different. They are not the same.
However, even though they're different, you can do this:
p1 = a;
p2 = b;
Now p1
points at a
, and p2
points at b
.
When you said p1 = a
it was shorthand. It was as if you had written
p1 = &a[0];
Strictly speaking, p1
points to the first element of a
. Similarly, p2 = b
is like p2 = &b[0]
and makes p2 point at the first element of b
. However, since b
is an array of arrays, the first element of b
is an array of 20 ints.
Also, if you pass a
and b
to a function, like this:
f(a, b);
what should the definition of the function look like? It turns out there are two ways to look at it. You can declare
void f(int a[], int b[20][]) { ... }
which makes f
's parameters look like what you think you're passing. But it turns out it's actually pointers that get passed, so f
can also be declared like this:
void f(int *a, int (*b)[20]) { ... }
Anyway, this is why that page you read suggested that there was some kind of equivalence between the array int a[10][20]
and the pointer int (*p2)[20]
. There is "some kind of equivalence", but it doesn't mean that they're the same type. (Not at all. For this reason, most people prefer not to use the word "equivalence" in this context any more.)