хранение многомерных массивов в c - PullRequest
2 голосов
/ 24 января 2011

Я работаю над простым языком препроцессора в стиле lisp. В API я хочу, чтобы пользователи могли передавать массивы любого размера и размера в препроцессор, которыми можно управлять с помощью языка. В настоящее время у меня есть перечисление типов;

typedef enum LISP_TYPE
{
  LT_UINT,
  LT_FLOAT,
  LT_ARRAY
  ...,
  ...
} _LISP_TYPE;

У меня проблемы с поиском эффективного и простого метода хранения массивов, а также доступа к ним. Есть еще одна структура, которую я использую специально для массивов;

typedef struct _lisp_array
{
  LISP_TYPE type;
  unsigned int length;
  void* data;

} lisp_array;

Когда препроцессор See представляет собой список атомов с типом LT_ARRAY, он преобразует его void* (cdr в терминах lisp) в указанную выше структуру. Где у меня возникли проблемы, так это выяснить, как получить доступ к многомерным массивам. Я думал о вычислении значения шага для обхода массива, но могу ли я гарантировать, что все переданные массивы будут распределены непрерывно?

Любая помощь приветствуется.

Ответы [ 3 ]

0 голосов
/ 24 января 2011

Поскольку вы пишете интерпретатор, вы сами решаете, какое из представлений сделать массив смежным - то есть, если вам нужно, чтобы он был смежным. Если вы сделаете его смежным, вы можете получить доступ к элементам, например, (предполагая, что индексы a, b, c ... и размер размера, начинающиеся с sa, sb, sc ...) равны нулю:

(a*sb + b) * sc + c   ... (row major order)
(c * sb + b) * sa + a ... (column major order)

Конечно, существуют и другие способы представления массивов - вы можете использовать массивы указателей на массивы и т. Д. Каждый из них имеет свои преимущества и недостатки; без каких-либо подробностей в случае использования, если границы массива являются фиксированными, и ожидается, что массив не будет разреженным, тогда разумным подходом обычно является смежный буфер.

0 голосов
/ 26 января 2011

Это будет зависеть от того, насколько вы хотели сделать это, на самом деле.Lisp не имеет строгого определения многомерных массивов, о которых вы думаете - все это либо атом, либо список.Самое близкое, что у него было бы - это массив массивов:

((1 2 3) (4) (5 6))

Обратите внимание, что подмассивы не имеют одинаковую длину.Но по своей сути это не очень удобно, и я не думаю, что есть способ форсировать проблему ...

Если вам нужны строго "прямоугольные" массивы, это не сработает, очевидно, но если у вас есть комната для маневра, это то, как я ее реализую - это хорошая, чистая структура (подробнее см. страницу Википедии ).

Cheers!

0 голосов
/ 24 января 2011

C встроенные (одиночные и многомерные) массивы гарантированно хранятся в одной смежной области памяти в режиме строки-майора.Это может не ответить на ваш вопрос, однако.На какой ожидаемый макет структуры данных указывает _lisp_array :: data member?

...