在 C 语言中,您想要做的问题是您需要知道如何浏览结构(即您需要知道类型)。
std::vector<T>
之所以能够按照其方式工作是因为它使用了模板(一个
C++
概念)。现在,话虽如此,您可以尝试比您建议的略微不同的方法。如果您不想使用任何数组,您可以存储通用类型。但是,在检索数据并使用它时,用户必须知道他或她期望的数据类型。以下避免了数组(尽管在使用它们时存在潜在的更清晰的解决方案),并具有链表实现的东西,它给您几乎与
std::vector<T>
相同的灵活性(除了性能优势之外,因为这是一个具有
O(n)
操作的链表,对于所有内容(您可以聪明地反转列表以实现,也许,
O(1)
插入,但这仅仅是举个例子))。
#include <stdio.h>
#include <stdlib.h>
typedef struct _item3_t
{
void *x, *y, *z;
struct _item3_t* next;
} item3_t;
typedef struct
{
item3_t* head;
} vec3_t;
void insert_vec3(vec3_t* vec, void* x, void* y, void* z)
{
item3_t* item = NULL;
item3_t* tmp = NULL;
int i = 0;
if(vec == NULL)
return;
item = malloc(sizeof(item3_t));
item->x = x;
item->y = y;
item->z = z;
item->next = NULL;
tmp = vec->head;
if(tmp == NULL) {
vec->head = item;
} else {
while(tmp->next != NULL)
tmp = item->next;
tmp->next = item;
}
}
void insert_vec3_float(vec3_t* vec, float x, float y, float z)
{
float* xv, *yv, *zv;
if(vec == NULL)
return;
xv = malloc(sizeof(float));
yv = malloc(sizeof(float));
zv = malloc(sizeof(float));
*xv = x;
*yv = y;
*zv = z;
insert_vec3(vec, xv, yv, zv);
}
void init_vec3(vec3_t* vec)
{
if(vec == NULL)
return;
vec->head = NULL;
}
void destroy_vec3(vec3_t* vec)
{
item3_t* item = NULL, *next = NULL;
if(vec == NULL)
return;
item = vec->head;
while(item != NULL) {
next = item->next;
free(item->x);
free(item->y);
free(item->z);
free(item);
item = next;
}
}
item3_t* vec3_get(vec3_t* vec, int idx)
{
int i = 0;
item3_t* item = NULL;
if(vec == NULL)
return NULL;
item = vec->head;
for(i = 0 ; i < idx && item != NULL ; ++i)
item = item->next;
return item;
}
void do_something(item3_t* item)
{
if(item == NULL)
return;
float x = *((float*)item->x);
float y = *((float*)item->y);
float z = *((float*)item->z);
}
int main()
{
vec3_t vector;
init_vec3(&vector);
insert_vec3_float(&vector, 1.2, 2.3, 3.4);
printf("%f %f %f\n", *((float*)vec3_get(&vector, 0)->x), *((float*)vec3_get(&vector, 0)->y), *((float*)vec3_get(&vector, 0)->z));
do_something(vec3_get(&vector, 0));
destroy_vec3(&vector);
return 0;
}
这段代码应该可以直接编译。你所拥有的是一个链表,它是你的“向量”(特别是vec3结构)。链表中的每个节点(即在std::vector<T>中的每个元素)都有三个元素,它们都是void指针。因此,你可以在这里存储任何数据类型。唯一的问题是,你需要为那些指针分配内存,并且在删除元素时,你需要释放那些内存(参考vec3_destroy方法的示例)。希望这能更好地帮助理解这些void指针在你的情况下如何工作。
要检索数据,你将无法使用[]符号,但你可以以同样的方式使用vec3_get方法。do_something方法是一种类似于你在OP中提到的方法的示例存根。