我想根据变量的值将指针强制转换为两个结构中的一个。我正在尝试这个但它不起作用 -
struct typeA
{
int a;
int x;
}
struct typeB
{
int b;
int a;
int x;
int z;
}
int band=1;
void *ptr;
if(band == 1)
ptr = (struct typeA *)malloc(sizeof(struct typeA));
else if(band == 2)
ptr = (struct typeB *)malloc(sizeof(struct typeB));
printf("A:%d",ptr->a);//error: structure type required instead of void
最好的方法是什么?
编辑:添加结构定义和错误(在代码注释中)以使其更有意义。
答案 0 :(得分:2)
正如其他人所建议的那样,您可能需要更改设计,因为它有一些缺陷。
但是,要解决编译错误,您可以执行以下操作:
printf("A:%d",(band == 1) ? ((struct typeA *)ptr)->a : ((struct typeB *)ptr)->a);
您收到错误是因为您在a
时尝试从void *
访问成员ptr->a
。
您需要明确地说明ptr
指向struct typeA
或struct typeB
。
答案 1 :(得分:1)
如果您不需要知道自己的结构类型,请使用
if(band == 1)
ptr = malloc(sizeof(struct typeA));
else if(band == 2)
ptr = malloc(sizeof(struct typeB));
malloc
的返回类型已为void *
。
但是,这是一个code smell ---您真的在创建结构后不需要知道结构的大小或类型吗?我会重新考虑你的设计。
修改根据您发布的其他代码,我强烈推荐一种新方法。例如,typeA
和typeB
中的字段的顺序不同,因此无论ptr->a
的类型如何,ptr
都无法引用这两个字段。如果您遇到普通C,请考虑一个struct
a
和x
,以及指向b
和z
的单独结构的可选指针。或者,只需使用typeB
即可,然后移除typeA
!
答案 2 :(得分:1)
你永远不应该投射malloc
的结果,因为这样做会掩盖其他问题。它也会在这里引起警告,因为类型不匹配。
摆脱演员阵容,你不应该收到任何警告。
编辑:
错误是因为您试图取消引用void *
,这是非法的。
不使用一个变量,而是使用两个(每种类型之一)并将另一个设置为NULL。或者,如果您知道void *
指向的数据类型,则可以将其转换为正确的类型,然后取消引用它。
答案 3 :(得分:1)
这里的演员阵容什么都不买,因为每个演员阵容的结果会立即转换为ptr
的类型。无论哪种方式,指向malloc
ed对象的指针最终都存储在ptr
中,而ptr
只有一个与malloc
返回的完全匹配的静态类型。唯一不同的行为是malloc
- ed区域的大小。
你的逻辑可以简化为一行:
void *ptr = malloc(band == 1 ? sizeof (struct typeA) : sizeof (struct typeB));
需要更多的上下文来确定这是否是一个关于周围代码的好方法,或者是否更加严格的“类OOP”会更好,或者是否在两个单独的代码段之间进行简单切换在不同的结构上。
实际对象无法在没有额外强制转换的情况下以typeA
或typeB
的形式进行访问,因此可以想象许多丑陋的代码如下所示,例如
if (band == 1)
do_this_A_version((struct typeA *) ptr)->foo, x);
else
do_this_B_version((struct typeB *) ptr)->bar, y);
有很好的方法可以避免这类问题,超出了这个问题的范围。
答案 4 :(得分:1)
[编辑] 编辑OP后更新了代码段。
这是第二次猜测实际的问题,但也许以下是什么 你在追求。
java.lang.RuntimeException: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for org.openxmlformats.schemas.officeDocument.x2006.docPropsVTypes.CTArray not found