They are not the same. The first (int a[100][100]
) is a single variable that is a compound object. The other (int **p
) is a collection of arrays that you are using as a data structure for matrices.
If you want to have an actual 2D array in dynamic storage, this is how you do it:
#include <stdlib.h>
int main()
{
int (*m)[100][100];
m = malloc(sizeof *m);
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
(*m)[i][j] = 0;
}
Of course, the syntax is a bit weird, and you would rather have a dynamic matrix with variadic number of columns and rows, which is why you would prefer to declare a matrix pointed by int **p
.
The reason why a
and *a
give the same output is because both decay to a pointer to the first element of a
, which is a[0][0]
. On the other hand, p
is a pointer itself, and *p
is the contents of the variable pointed by p
. They are just as different as they would be if you did this:
int d = 0;
int *p = &d;
printf("%p\n", p);
printf("%d\n", *p);
Now back to your int **p
.
Yes, you can access both int a[][100]
and int **p
with double indexing. However, there is a fundamental difference in the way the compiler treats a[i][j]
and p[i][j]
.
In a[i][j]
, each a[i]
is an array of 100 integer objects. So in order to access the i
-th element, and then the j
-th element, the compiler has to acess the i*100+j
-th element from a[0][0]
. This access can be performed in a single step with some index arithmetic.
In v[i][j]
, each v[i]
is a pointer which may point to objects far from each other in memory. In order to acess the element v[i][j]
, the compiler must first follow p
to the array *p
, then find the i
-th element in this array, which is a pointer to the array p[i]
. And then with some pointer arithmetic it will find the j
-th element of this array.