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

时间:2012-01-30 14:53:33

标签: c void-pointers

我试图在C中自己实现常见的数据结构,以获得自己的学习效益。我目前的努力是一个向量,我希望它能够保存一个任意类型(或者至少是类型大小,但是在C中真的不重要吗?)。我的结构如下:

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

但是,我不明白的是,如果类型应该是任意的,我可以如何引用* item数组中的特定元素。我知道element_size,但这对索引引用没有帮助(例如item [5]),因为void不是一个类型。我认为最简单的方法是将元素称为字节偏移量。因此,如果我持有大小为12的结构向量,则项目[5]将在项目*的12 * 5 = 60字节处。但是,我不明白如何检索该数据。我知道我需要来自item + 60的12个字节,但是如何让编译器理解呢?我是否进入预处理器领域?

3 个答案:

答案 0 :(得分:2)

sizeof是字符中的度量,因此您可以执行此操作:

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

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

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

在应用偏移量5之前知道正确类型的代码,可以这样做:

unsigned char*

void不是类型

这是一种类型,它不是“完整类型”。 “不完整类型”几乎意味着编译器不知道correct_type *sixth_element = ((correct_type *)item) + 5; 真正指向的是什么。

答案 1 :(得分:0)

void *是任何对象指针类型的通用指针类型。你必须知道它指向的是什么类型才能正确地转换void *并取消引用指针。

以下是使用不同指针类型的void *对象的示例。

void *p;
int a = 42, b;
double f = 3.14159, g;

p = &a;
b = *(int *) a;

p = &f;
g = *(double *) f; 

答案 2 :(得分:0)

  

因此,如果我持有大小为12的结构向量,则项目[5]将在项目*的12 * 5 = 60字节处。但是,我不明白如何检索该数据。我知道我需要来自item + 60的12个字节,但是如何让编译器理解呢?

假设您的给定类型为foo。如您所知,您需要到达item + (5 * 12)处的地址,然后在将其转换为foo*后取消引用该空指针。

foo my_stuff = *(foo *)(item + 5 * 12);

如果您可以在编译时确定数据类型,也可以使用sizeof()

foo my_stuff = *(foo *)(item + 5 * sizeof(foo));