如何在C中没有赋值的情况下转换指针?

时间:2014-11-18 06:26:51

标签: c pointers casting void-pointers

我有void *类型的指针,但我知道它们实际上是指向一个结构。当我将它们分配给另一个指针并使用它时,一切正常,但我无法直接使用转换的void指针。

以下是一个例子:

typedef struct {
    int x1;
    int x2;
} TwoX;

main()
{
   void * vp;
   TwoX xx, *np, *nvp;
   xx.x1 = 1;
   xx.x2 = 2;

   vp = (void *)&xx;
   np = &xx;
   nvp = (TwoX *)vp;
   printf ("test normal pointer: %d %d\n", np->x1, np->x2);
   printf ("test recast void pointer: %d %d\n", nvp->x1, nvp->x2);
   //printf ("test void pointer: %d %d\n", (TwoX *)(vp)->x1, (TwoX *)(vp)->x2); // this line doesn't compile

}

最后printf行无法编译,我收到以下错误和警告两次(每次投射一次):

warning: dereferencing void * pointer [enabled by default]
error: request for member x1 in something not a structure or union

没有那一行,一切正常,输出是:

test normal pointer: 1 2
test recast void pointer: 1 2

如何在不将其分配给新变量的情况下转换void *指针?

2 个答案:

答案 0 :(得分:4)

在您的代码中,更改

printf ("test void pointer: %d %d\n", (TwoX *)(vp)->x1, (TwoX *)(vp)->x2);

printf ("test void pointer: %d %d\n", ((TwoX *)(vp))->x1, ((TwoX *)(vp))->x2);
                                      ^            ^      ^            ^
                                      |            |      |            |

如果没有额外的括号对,则dererence运算符->优先于类型转换,因此(Two *)在解除引用之前无效。

根据逻辑,您不能取消引用void类型指针。这就是警告的原因。接下来,当您请求访问结构指针的某个成员变量时,指针应该是该结构的类型,这不会发生(因为它仍然是void类型),所以错误。< / p>

您可以检查运算符优先级here

答案 1 :(得分:4)

我认为这只是一个操作顺序问题。试试((TwoX*)vp)->x1。请注意,强制转换和指针与括号组合在一起。