Question

How could I do the following?

double layer1[][3] = {
    {0.1,0.1,0.8},
    {0.1,0.1,0.8},
    {0.1,0.1,0.8},
    {0.1,0.1,0.8}
};
double layer2[][5] = {
    {0.1,0.1,0.1,0.1,0.8}
};
double *upper[] = {layer1, layer2};

I read the following after trying different ideas; to no avail. Do jagged arrays exist in C/C++?

I understand (I hope) that

double **upper[] = {layer1, layer2};

Is similar to what I'd like, but would not work because the layers are not arrays of pointers. I am using C intentionally.


I am trying to abstain from doing this (which works).

double l10[] = {0.1,0.1,0.8};
//l11 etc
double *l1[] = {l10,l11,l12,l13};
double l20[] = {0.1,0.1,0.1,0.1,0.8};
double *l2[] = {l20};

double **both[] = {l1, l2};
Was it helpful?

Solution

In modern C there is a tool call compound literal to achieve at least partially what you seem to want:

double (*(layer1[])) = {
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8}
};
double (*(layer2[])) = {
    (double[]){0.1,0.1,0.1,0.1,0.8}
};
double (*(*(upper[]))) = {layer1, layer2};

I have put in () to the types to show you the rules of bindings for the types. But beware that with this type of programming you'd always have to remember the array bounds by yourself.

Edit: A construct as (double[]){ 0.0 } is called a compound literal and as the same effect as your temporary arrays that you had declared in your second version. The advantage is that you don't have to invent a naming convention for them and that the only way to access these temporary variables is then through the bigger array. Maybe it would be better to put in const into all of this so you wouldn't accidentally change the pointers:

double (*const(layer1[])) = {
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8}
};
double (*const(layer2[])) = {
    (double[]){0.1,0.1,0.1,0.1,0.8}
};
double (*const(*const(upper[]))) = {layer1, layer2};

This still lets you change the contents (all the doubles) but not the pointers. If you know that the doubles themselves don't change during the whole program, change double into double const everywhere.

OTHER TIPS

struct {
  size_t length;
  size_t stride;
  double *data;
} upper = {
  {
    sizeof(layer1) / sizeof(layer1[0]),
    sizeof(layer1[0]) / sizeof(layer1[0][0]),
    (double *)layer1,
  },
  {
    sizeof(layer2) / sizeof(layer2[0]),
    sizeof(layer2[0]) / sizeof(layer2[0][0]),
    (double *)layer2,
  },
};

int i, j, k;
for (i = 0; i < sizeof(upper) / sizeof(upper[0]); i++) {
  for (j = 0; j < upper[i].length; j++) {
    for (k = 0; i < upper[i].stride; k++)
      printf(" %d" + !k, upper[i].data[upper[i].stride * j + k]);
    printf("\n");
  }
  printf("\n");
}

You have to realize that multi-dimensional arrays in C are just row-major packed into linear piece of storage. The actual dimensions are only known by the types at compile-time: they're not anywhere to be found in data at runtime.

Layer1 and Layer2 are arrays of pointers, by very definition of jagged arrays. There is no reason for

double ** upper[] = {layer1, layer2}

Not to work. If it doesn't, post the error message.

The only problem is that your arrays decay to pointers. If that is a problem to you you need to use C99 and read this post in the thread you already mentioned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top