将 void 指针转换为任意类型指针

标签 c void-pointers

为了我自己的学习利益,我正在尝试用 C 语言自己实现常见数据结构。我当前的工作是一个 vector ,我希望它能够保存单个任意类型(或者至少是类型大小,但这在 C 中不是真正重要的吗?)。我的结构如下:

struct vector
{
    void *item;
    size_t element_size;
    size_t num_elements;
}

但是,我不明白的是,如果类型应该是任意的,我如何引用 *item 数组中的特定元素。我知道 element_size,但这对我进行索引引用(例如 item[5])没有帮助,因为 void 不是类型。我认为将元素称为字节偏移量是最简单的。因此,如果我持有大小为 12 的结构体 vector ,则 item[5] 将位于距离 item* 12*5=60 字节的位置。但是,我不明白如何检索该数据。我知道我想要 item+60 中的 12 个字节,但是如何让编译器理解这一点?我是否进入了预处理器领域?

最佳答案

sizeof 是以字符为单位的,所以你可以这样做:

void *start_of_sixth_element = ((char*)item) + (5 * element_size);

知道每个元素类型的人可以将 start_of_sixth_element 转换为正确的类型来使用它。

void* 在某种程度上是一个糟糕的选择,因为你不能使用标准 C 中的 void* 指针进行指针算术(有一个 GNU 扩展允许它,但对于可移植代码,至少在算术中使用 char*unsigned char* )。

在应用偏移量 5 之前知道正确类型的代码可以执行以下操作:

correct_type *sixth_element = ((correct_type *)item) + 5;

void 不是类型

它是一种类型,只是不是“完整类型”。 “不完整类型”几乎意味着编译器不知道 void* 真正指向什么。

关于将 void 指针转换为任意类型指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9065777/

相关文章:

c++ - 将一个dll的Class对象传递给另一个dll c++

c - 跨平台使用 void 指针

c - 修复了标记字符串时的错误

c - 位掩码与位中的 "accessing an array"相当吗?

c - VS 2013错误C1853尝试构建DLL(但不使用预编译头集)

C++,bool 转换是否总是退回到 void* 的隐式转换?

c - 在 C 语言中,memcpy() 是否不需要/不建议强制转换为 (void*),就像 malloc() 不需要一样?

c++ - 为什么对于来自客户端的每条写入消息,此程序都会在 C/C++ 中创建一个新进程?

c - 这个程序的输出是什么

c - 不兼容的指针类型警告