There are many different ways to create so-called 2D matrices of int
, each defining a very different type of object:
as an array of arrays of int
:
int A[ROWS][COLS] = { 0 };
as an array of pointers to arrays of int
:
int *A[ROWS];
for (int i = 0; i < ROWS; i++)
A[i] = calloc(sizeof(int), COLS);
as pointer to an array of arrays of int
:
int (*A)[COLS] = calloc(sizeof(*A), ROWS);
as a pointer to an array of pointers to arrays of int
:
int **A = calloc(sizeof(*A), ROWS);
for (int i = 0; i < ROWS; i++)
A[i] = calloc(sizeof(int), COLS);
In all cases, the syntax to access the matrix elements is the same: A[row][col]
, or any of the equivalent pointer notation variants:
*(*(A + row) + col)
*(A[row] + col)
(*(A + row))[col]
In all cases, A
, and A[row]
can be used where a pointer is expected, either because they are indeed pointers (cases 3 and 4) or because arrays (cases 1 and 2) decay to a pointer to their first element when used in an expression context (except as an argument to sizeof
), such as when passed as an argument to printf
.
Printing pointer values with printf
requires the %p
conversion format.
%d
expects an int
, which is not the same as a pointer, may have a different size and may be passed to printf
differently, all causing undefined behavior. The compiler emits a very useful warning about this. It is a good idea to configure the compiler with as many warnings as possible to detect silly mistakes.These warnings are sometimes difficult to understand, but are almost always an indication of something that needs fixing.
You can use printf("%p", (void*)A)
which is equivalent to printf("%p", (void*)&A[0])
and printf("%p", (void*)A[0])
, equivalent to printf("%p", (void*)&A[0][0])
. All 4 should print the same address.