如何检测元素是否为数组?另外,我如何声明这样的数组:[1, 2, 3, [4, 5, 6]]
?
答案 0 :(得分:3)
你没有。
在C中,多维数组是数组的数组,而不是一个数组,其中一个元素是另一个数组,但其他数组是数字。 int x[10][10]
将x
声明为包含10个int
s的10个数组的数组,即10 x 10矩阵中的100个元素。
要做你所描述的,你需要一个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 */;
}
还有其他各种方法可以从根本上实现同样的目标。
答案 1 :(得分:2)
C中的数组绝对不能这样做 - 它们不能保存不完全相同类型的对象集合。 C ++标准库中的集合类也是如此。要创建这种“异构”集合,您实际上需要定义某种结构(或C ++中的类) - 例如将其称为DataObject
- 然后安排DataObject
为能够代表不同的类型,通常使用union
。然后,数组中的所有内容都可以是DataObject
,但有些可以是DataObject
,其中包含int
,而其他可以包含另一个DataObject
数组。