Search code examples
carraysmultidimensional-arraydetection

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]] ?


Solution

  • 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.