在我看到的许多矢量实现中,使用了以下矢量结构的定义:
struct vector {
void **data;
int size;
int count;
};
为什么我们这里需要指针到指针成员?
因为它可以是指针元素的向量,指针元素可以具有任何类型(包括指针),因为void *
可以转换为c1中的任何指针类型。此外,元素将以指针的大小分隔,使操作更简单。
然后,您可以通过在转换为适当的指针类型后取消引用指向元素的void *
指针来获得实际值,或者如果元素是指针,则只需获得一个指针。
示例实现(当然还远未完成2)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vector
{
void **data;
size_t count;
size_t size;
};
void
vector_new(struct vector *vector, size_t size, size_t nmemb)
{
vector->data = NULL;
vector->count = 0;
vector->size = size;
}
void
vector_push_back(struct vector *vector, void *value)
{
unsigned char **data;
data = realloc(vector->data, sizeof(*data) * (vector->count + 1));
if (data == NULL)
return; // Probably return an error indicator
vector->data = (void *) data;
data[vector->count] = malloc(vector->size);
if (data[vector->count] == NULL)
return; // Probably return an error indicator
memcpy(data[vector->count], value, vector->size);
vector->count++;
}
void *
vector_get(struct vector *vector, size_t index)
{
return (unsigned char *) vector->data[index];
}
int
main(void)
{
struct vector vector;
vector_new(&vector, sizeof(float), 100);
for (int i = 0 ; i < 10 ; ++i)
{
float value;
value = (float) rand() / RAND_MAX;
fprintf(stdout, "vector[%d] %fn", i, value);
vector_push_back(&vector, &value);
}
fprintf(stdout, "Read them to check!n");
for (int i = 0 ; i < 10 ; ++i)
{
float value;
value = *(float *) vector_get(&vector, i);
fprintf(stdout, "vector[%d] %fn", i, value);
}
return 0;
}
1这种构造通常是一种糟糕的设计选择,因为它很难维护,也很难编写访问器函数。尽管如此,它还是有一些天才的用例。c语言不应该用于泛型类型,试图强制执行泛型类型的好处通常比问题少
2例如,它缺少一个自由/破坏功能
请查看向量上vector
所需功能的精彩回顾(链接指向C++中的vector
,但有关其功能的信息通常适用于C或C++或任何其他语言中的vector
)。
重点如下。该功能为您提供了有关数据结构为何如此的线索。
矢量是表示数组的序列容器,这些数组可以在大小
就像数组一样。。。它们的元素也可以使用偏移来访问在指向其元素的常规指针上。。。但与阵列不同的是,它们的大小可以动态更改。。。
矢量容器可能会分配一些额外的存储空间来容纳可能的增长。。。因此,矢量不会每次都重新分配元素被添加到容器中。
struct vector {
void **data; // needs to act like an array of pointers i.e. void *data[]
int size; // actual memory allocated may be in access of count
int count; // current count of elements in data
};
这很常见。您可以将其视为:
char *data[size];
因此,每个元素都是一个字符串,或者任何在运行时之前大小未知的存储类型。例如int i=123;
data=malloc(sizeof(int));
memcpy(data, &i, sizeof(i));