I am working on a simple lisp-style pre-processor language. In the API i want users to be able to pass arrays of any dimension and size to the pre-processor which can be manipulated using the language. Currently i have an enum of types;
typedef enum LISP_TYPE
{
LT_UINT,
LT_FLOAT,
LT_ARRAY
...,
...
} _LISP_TYPE;
I am having trouble finding an efficient and easy to use method of storing arrays and also accessing them. There is another structure i use specifically for arrays;
typedef struct _lisp_array
{
LISP_TYPE type;
unsigned int length;
void* data;
} lisp_array;
When the pre-processor See's a list atom with type LT_ARRAY, it will convert its void*
(cdr in lisp terms) to the above structure. Where i am having problems is figuring out how to access multi-dimensional ar开发者_如何学运维rays. I have thought of calculating a step value to traverse the array but can i guarantee that all arrays passed will be contiguously allocated?
Any help is appreciated.
C built-in (singe and multi-dimensional) arrays are guaranteed to be stored in one contiguous region of memory in row-major mode. This may not answer your question, however. What is the expected layout of the data structure pointed to by _lisp_array::data member?
Since you're writing the interpreter, it's up to you to decide on the representation and make the array contiguous - that is, if you need it to be contiguous. If you make it contiguous, you can access elements by, for example (assuming zero-based indices a, b, c... and dimension size sa, sb, sc...):
(a*sb + b) * sc + c ... (row major order)
(c * sb + b) * sa + a ... (column major order)
There are other ways of representing arrays, of course - you could use arrays-of-pointers-to-arrays, etc. Each has its own advantages and disadvantages; without any specifics on the use case, if the bounds of the array are fixed, and the array is not expected to be sparse, then a contiguous buffer is usually a reasonable approach.
It would depend on how lisp-like you wanted to make it, really. Lisp doesn't have the strict definition of multi-dimensional arrays you're thinking of - everything is either an atom or a list. The closest thing it would have is an array of arrays:
((1 2 3) (4) (5 6))
Note, though, that the sub-arrays aren't the same length. But it's inherently lispy that they don't have to be, and I don't think there's a way to force the issue...
If you need strictly "rectangular" arrays this won't work, obviously, but if you've got wiggle-room, this is how I'd implement it - it's a nice, clean structure (check out the Wikipedia page for more details).
Cheers!
精彩评论