我正在用C语言编写一个动态数组:
struct array {
int len;
int cap;
void *data;
};
如果我知道类型,则很容易存储值:
void set(array* a, int idx, int val) {
((int*)a->data)[idx] = val;
}
但是我想接受任何类型(void *):
void set(array* a, int idx, void* val) {
a->data[idx] = val;
}
这显然不能编译,因为'void' is not assignable
据我了解,编译器需要有关类型的信息以获取其大小并计算偏移量以访问数据。
有没有办法自己做?直接按字节操作,类似
void set(array* a, int idx, void* val, int size) {
*((char*)a->data + size * idx) = val;
}
基本上,我想使它们类似于Go切片。您可以在此处了解其内置的泛型类型:
https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics
没有模板,没有拆箱。他们使用void*
进行数据存储。
答案 0 :(得分:2)
我想memcpy
应该可以满足您的需求:
void set(array* a, int idx, void* val, int size) {
memcpy(a->data + size * idx, val, size);
}
答案 1 :(得分:0)
首先,您需要使用void * *数据-存储数组,而不是单个指向元素的指针。
从你所拥有的 [a-> data =(void *)val; ]应该可以正常运行。
它只是指向数据的指针,可以存储为void。当您想取消引用数据时,您将需要知道如何读取数据。
如果val指向一个int-以便读取它,则必须将其强制转换以让编译器知道要读取多少字节。 所以:*(int *)(a-> data);