проверить, является ли элемент массивом c - PullRequest
1 голос
/ 25 апреля 2011

как мне определить, является ли элемент массивом? Кроме того, как бы я объявить массив, как это: [1, 2, 3, [4, 5, 6]]?

Ответы [ 2 ]

3 голосов
/ 25 апреля 2011

Вы не.

В C многомерные массивы - это массивы массивов, а не массив, где один элемент - это другой массив, а остальные - числа. int x[10][10] объявляет x как массив из 10 массивов по 10 int с, то есть всего 100 элементов в матрице 10 x 10.

Чтобы сделать то, что вы описываете, вам понадобится массив void * s:

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

Вы выделяете len элементов для arr с x.arr = malloc(x.len * sizeof(void *)). Тогда каждый элемент может быть чем угодно - возможно, числом, возможно, другим struct myarr для дальнейшего вложения.

Однако на практике вы не сможете узнать, является ли void * числом или другим массивом. Так что вам понадобится какая-то динамическая проверка типов.

enum mytype {
  INT,
  ARR,
};

Затем вы делаете struct myint и повтор struct myarr для совместимости:

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

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

Когда вы делаете struct myint, всегда устанавливайте x.type = INT, а когда вы делаете struct myarr, всегда устанавливайте x.type = ARR.

struct указатели всегда можно привести к указателю на первый элемент, поэтому и struct myint *, и struct myarr * можно привести к указателю enum mytype *, который содержит ваш массив в myarr. Затем, когда вы обращаетесь к элементу массива с помощью .arr[n], вы можете проверить (во время выполнения), какой тип он содержит, соответствующим образом привести указатель и использовать по желанию:

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 */;
  }

Существуют и другие способы достижения того же самого.

2 голосов
/ 25 апреля 2011

Массивы в C абсолютно не могут этого сделать - они не могут содержать коллекции объектов, которые не все одного типа.То же самое относится и к классам коллекций в стандартной библиотеке C ++.Чтобы создать такого рода «гетерогенную» коллекцию, вам действительно нужно определить некую структуру (или класс в C ++) - например, назвать ее DataObject - и затем организовать DataObject, чтобы иметь возможность представлять различныетипы, часто используя union.Тогда все в массиве может быть DataObject, но некоторые могут быть DataObject s, которые содержат int, а другие могут содержать другой DataObject массив.

...