Reputation: 11032
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]]
?
Upvotes: 1
Views: 371
Reputation: 75479
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 int
s, 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.
Upvotes: 3
Reputation: 81734
Arrays in C absolutely can't do that -- they can't hold collections of objects that aren't all the same type. The same is true of the collections classes in the C++ standard library. To create this kind of "heterogeneous" collection, you actually need to define some kind of struct (or class in C++) -- call it DataObject
, for example -- and then arrange for DataObject
to be able to represent different types, often by using a union
. Then everything in the array can be a DataObject
, but some can be DataObject
s that hold an int
, and others that hold another DataObject
array.
Upvotes: 2