2011-01-24 5 views
2

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

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; 

Когда препроцессор Престола атом список с типом LT_ARRAY, он преобразует его void* (корд в LISP выражении) к указанной выше структуре. Там, где возникают проблемы, выясняется, как обращаться к многомерным массивам. Я думал о вычислении значения шага для перемещения массива, но могу ли я гарантировать, что все переданные массивы будут смежно распределены?

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

+0

Не можете ли вы просто использовать шаблоны C++? – ch0kee

ответ

0

Встроенные (одиночные и многомерные) массивы C гарантированно сохраняются в одной смежной области памяти в основном режиме. Однако это может не ответить на ваш вопрос. Каков ожидаемый макет структуры данных, на который указывает элемент _lisp_array :: data?

+0

Ожидаемый макет зависит от типа _lisp_array ::. если это FLOAT, CHAR, INT или любой другой тип, тогда данные будут массивом этих типов. Если тип ARRAY, тогда он должен обозначать несколько измерений. это где я застрял, как я должен это представлять? btw Я ожидаю динамически распределенных массивов, а также статических смежных. – jmgunn87

+0

Когда это тип массива (который вы не показывали), каков ожидаемый макет? –

+0

Как я уже сказал, у меня так далеко. Я думал о другом указателе lisp_array. – jmgunn87

0

Поскольку вы пишете интерпретатор, вам решать, как это сделать, и сделать массив смежным - то есть, если вам нужно, чтобы он был смежным. Если вы сделаете это смежный, вы можете получить доступ к элементам, например (при условии, отсчитываемое от нуля индексы а, b, c ... и измерение размера SA, SB, SC ...):

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

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

0

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

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

Заметим, однако, что суб-массивы не одинаковой длины. Но по своей сути они не нужны, и я не думаю, что есть способ заставить проблему ...

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

Cheers!

Смежные вопросы