Reputation: 510
I have many constant 2D arrays of all possible permutation of integer in [0,LEN) for many LEN:
static const char permu2[][2] = {{0, 1}, {1, 0}};
static const char permu3[][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
{1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
static const char permu4[][4] = {
{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2},
{0, 3, 2, 1}, {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0},
{1, 3, 0, 2}, {1, 3, 2, 0}, {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3},
{2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, {3, 0, 1, 2}, {3, 0, 2, 1},
{3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}};
static const char permu5[][5] = {{0, 1, 2, 3, 4}, {0, 1, 2, 4, 3}, {0, 1, 3, 2, 4}, /*... */}
// and many more as you can imagine...
And I'd like to store the pointers to those arrays in another array:
static const char *permu[] = {0, 0, permu2, permu3, permu4,
permu5, permu6, permu7, permu8};
static const int fac_seq[] = {1, 1, 2, 6, 24, 120,
720, 5040, 40320, 362880, 3628800, 39916800};
So that for a given LEN=n, I can access those constants in this way:
const int n = 8;
for ( size_t i = 0; i < fac_seq[n]; i++ ) {
for ( size_t j = 0; j < n; j++ ) {
printf( "%2d", *( permu[n] + n*i + j ) );
}
putchar( '\n' );
}
Although this will compile and work correctly, the compiler (gcc) complains like:
30.c:1966:47: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
static const char *permu[] = {0, 0, permu2, permu3, permu4,
^~~~~~
30.c:1966:47: note: (near initialization for ‘permu[2]’)
30.c:1966:55: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
static const char *permu[] = {0, 0, permu2, permu3, permu4,
^~~~~~
30.c:1966:55: note: (near initialization for ‘permu[3]’)
What should be the right type for the permu
array? I tried const char **permu[]
and still got the same warnings.
Upvotes: 2
Views: 57
Reputation: 29193
The correct declaration is
static const char (*permu[9])[] = {0, 0, permu2, permu3, permu4,
permu5, permu6, permu7, permu8};
permu
is an array of 9 pointers to arrays of unknown numbers of const char
s. Writing the 9
is optional; it can be inferred from the initializer. You could instead make it an array of pointers to void
, as in the other answer, but it's best to preserve as much information as possible. You use it like this:
const int n = 4;
const char (*perms)[n] = permu[n];
for (size_t i = 0; i < fac_seq[n]; i++) {
for (size_t j = 0; j < n; j++) {
printf("%2d", perms[i][j]);
}
putchar('\n');
}
Note that I perform a cast with the assignment to perms
. I take a pointer to an array of unknown size and convert it to a pointer where the array size is actually n
. This is what allows the double []
syntax later: the type const char[n]
has a defined size (sizeof(char)*n
), so we know how far we need to skip for perms[i]
.
Upvotes: 1
Reputation: 34583
You could try
static const void *permu[] = { };
You would then have to cast it when accessed.
Alternatively you can make each array one-dimensional and work out the indexing yourself.
Upvotes: 1