tekknolagi
tekknolagi

Reputation: 11032

test if element is array c

how would i detect if an element is an array? also, how would i declare an array like this: [1, 2, 3, [4, 5, 6]] ?

Upvotes: 1

Views: 371

Answers (2)

Chris Lutz
Chris Lutz

Reputation: 75479

You don't.

In C, multidimensional arrays are arrays of arrays, not an array where one element is another array but the others are numbers. int x[10][10] declares x as an array of 10 arrays of 10 ints, i.e. 100 total elements in a 10 x 10 matrix.

To do what you describe, you'd need an array of void *s:

struct myarr {
  size_t len;
  void **arr;
};

You allocate len elements for arr with x.arr = malloc(x.len * sizeof(void *)). Then each element can be anything you want - perhaps a number, perhaps another struct myarr for further nesting.

In practice, however, you'll have no way of knowing whether the void * is a number or another array. So you'll need some sort of dynamic type checking.

enum mytype {
  INT,
  ARR,
};

Then you make a struct myint and redo struct myarr to be compatible:

struct myint {
  enum mytype type;
  int i;
};

struct myarr {
  enum mytype type;
  size_t len;
  enum mytype **arr;
};

When you make a struct myint, always set x.type = INT, and when you make a struct myarr, always set x.type = ARR.

struct pointers can always be cast to a pointer to the first element, so both struct myint * and struct myarr * can be cast to an enum mytype * pointer, which is what your array in myarr holds. Then, when you access an element of the array with .arr[n], you can test (at runtime) what type it holds, cast the pointer accordingly, and use at will:

for(size_t i = 0; i < x.len, i++)
  {
    enum mytype *j = x.arr[i];
    if(*j == INT)
      {
        printf("%i", ((struct myint *)j)->i);
      }
    else if(*j == ARR)
      {
        printf("[");
        // recurse
        printf("]");
      }
    else /* this should not happen, you messed up */;
  }

There are various other ways to achieve fundamentally the same thing.

Upvotes: 3

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81734

Arrays in C absolutely can't do that -- they can't hold collections of objects that aren't all the same type. The same is true of the collections classes in the C++ standard library. To create this kind of "heterogeneous" collection, you actually need to define some kind of struct (or class in C++) -- call it DataObject, for example -- and then arrange for DataObject to be able to represent different types, often by using a union. Then everything in the array can be a DataObject, but some can be DataObjects that hold an int, and others that hold another DataObject array.

Upvotes: 2

Related Questions