What is the difference between
int a1[9];
and
int a2[3][3];
(I've changed the names so I can talk about the declarations more easily.)
The difference is that they're of different types. They both have the same underlying memory layout,each consisting of a contiguous region of memory 9 times the size of an int
. But a1
is an array of 9 int
objects, while a2
is an array of 3 objects each of which is an array of 3 int
objects. It's a multidimensional array, which in C is precisely an array of array, nothing more, nothing less.
The difference is not just syntactic sugar. You might get the same generated code for certain operations, for example a1[1]
and a2[0][1]
. But, for example, a1[3]
refers to the 4th element of the array a1
, while a2[0][3]
, though you might think it refers to the same thing, actually has undefined behavior. (Compilers are permitted, but not required, to perform run-time array bound checking, and are permitted to assume that array references do not go past the end of the indexed array object.)
printf("%d\n", a2[1]);
As others have mentioned, this has undefined behavior. a2[1]
is an array object of type int[3]
. An expression of array type is, in most contexts, converted to an expression of pointer type, so a2[1]
ends up being of type int*
, and yields a pointer to the initial element of the second row of a2
. To print a pointer value, use %p
-- which requires an argument of type void*
, so you need to cast it:
printf("%p\n", a2[1]);
Recommended reading: Section 6 of the comp.lang.c FAQ.