i have some bidimensional arrays like:
int shape1[3][5] = {1,0,0,
1,0,0,
1,0,0,
1,0,0,
1,0,0};
int shape2[3]
I believe I just verified what I wrote was correct. The following works as expected:
#include <stdio.h>
int main(int argc, char **argv) {
int shape1[5][3] = {1,0,0,
1,0,0,
1,0,0,
1,0,0,
1,0,0};
int shape2[5][3] = {0,0,0,
0,0,0,
0,1,1,
1,1,0,
0,1,0};
typedef int (*shapes_p)[3];
shapes_p shapes[2] = { shape1, shape2 };
shapes[0][1][0] = 5;
shapes[1][1][0] = 5;
printf("shape1[1][0] == %d\n", shape1[1][0]);
printf("shape2[1][0] == %d\n", shape2[1][0]);
}
The thing to remember is that the type of shape1
and shape2
is actually:
int *shape1[5];
What you have in memory is 3 adjacent arrays of 5 ints each. But the actual type is pointer to array of 5 ints. When you write:
shape1[1][2] = 1;
you're telling the compiler to index to the second array of int[5] and then access the 3rd element of that array. What the compiler actually does is pointer arithmetic on the underlying type pointed to, in this case int[5]. You could do the same with the following code:
int *p = shapes1[0];
p+7 = 1; // same as shape1[1][2] = 1;
So if you want an array of pointers to int *[5] then you would do:
typedef int (*shapes_p)[5];
shapes_p shapes[2];
Updated Fixed type. Thanks j_radom_hacker
for bringing this to my attention!
[EDIT: Actually the type here was not correct -- see Robert S. Barnes' answer for the correct type to use.]
Figure out the type of shape1
and shape2
first:
typedef int (*shape_array_t)[5];
Now use this:
shape_array_t sat[] = { shape1, shape2 };
First of all, the first array bound refers to the outermost array dimension, so you should probably declare shape1
as:
int shape1[5][3] = {1,0,0,
1,0,0,
1,0,0,
1,0,0,
1,0,0};
and similarly for shape2
.
[EDIT: I've changed the type of shapes
below to correspond to Robert Barnes' answer -- we don't want the outermost subscript to be included in this type!]
The slightly strange-looking typename you need is:
int (*shapes[])[3] = { shape1, shape2 };
This allows the element at row 4, column 1 of shape2
to be addressed using
shapes[1][3][0]
Breakdown of subexpressions and their C types:
shapes // has type "int (*x[2])[3]" (decays to "(**x)[3]")
shapes[1] // has type "int (*x)[3]"
shapes[1][3] // has type "int x[3]" (decays to "int *x")
shapes[1][3][0] // has type "int x"
(Note that a dummy x
has been included in the types above to make them clearer -- in fact this identifier is not part of the type.)
A rule of thumb for decoding C/C++ types is "starting from the variable name, read right when you can and left when you hit a closing parenthesis." So the decoded typename for shapes
is:
An array of pointers to an array of 3 integers.
In general it's much nicer to use typedef
s for these complicated types, as dirkgently suggests.