我有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 *
指针?
答案 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
。请注意,强制转换和指针与括号组合在一起。