在c中进行类型转换

时间:2011-08-30 23:53:31

标签: c casting

我想知道是否有可能获得我想要动态投射的类型。例如。

void *ptr;
typedef struct {
..
common_field;
..
} some;

typedef struct {
    ..
    common_field;
    ..
    } some_other;

现在我想知道我是否可以强制ptr动态输入some或some_other。

正是我想知道的是,如果有可能有一个宏TYPE_CAST(comdition),它给我的类型如下所示:

(TYPE_CAST(condition)) ptr->common_field

应该相当于

((some *) ptr)->common_field or ((some_other *) ptr)->common_field

基于condition

以下内容不起作用,只是这样做,以便理解c而不是英语:

TYPE_CAST(condition) ((condition) ? (some *) : (some_other *))

可以做这些事情。

感谢。

3 个答案:

答案 0 :(得分:2)

这几乎是不可能的。表达式的类型在编译时确定;它不能依赖于任何执行时间条件。

如果你知道某个类型或另一个对象的void*,你可以做类似的事情(我没有测试过):

condition ? ((some*)ptr)->common_field : ((some_other*)ptr)->common_field

请注意,必须重复表达式的->common_field部分;编译器必须知道->运算符的左操作数的类型。

(根据上下文,if / else语句可能更清楚。)

答案 1 :(得分:1)

设计数据结构以避免问题的方法可能是:

typedef struct {
    int common_field;
    union {
        struct {
            int member1;
        } some;
        struct {
            char* member2;
        } some_other;
    };
} common_struct;
common_struct* ptr;

然后,您可以使用ptr->common_field轻松访问公共成员,无论您拥有哪两种变体。我想这个公共字段的价值会告诉你需要使用哪两个工会成员来访问剩下的成员,然后你将以ptr->some.member1ptr->some_other.member2的身份访问这些成员。 / p>

答案 2 :(得分:0)

C90不直接支持

我假设您想在c90中编写某种通用列表。以下是我在我的通用c90列表中使用的一些片段:

typedef struct {
void *rigth;
void *left;
void *value;
int index;
}GENLIST_node;
#define GENLIST_getValuePtr(NODE, index, valptr) __GENLIST_getValuePtr ((NODE), (index), (void*)(valptr)) 

使用此功能,您可以在调用内容时访问该内容,并始终返回该类型。以下是一些例子:

int *NODEVALA = NULL;
double *NODEVALB = NULL;
char *NODEVALC = NULL;

GENLIST_getValuePtr(&AnyNode, -1, &NODEVALA);
GENLIST_getValuePtr(&AnyNode, -1, &NODEVALB);
GENLIST_getValuePtr(&AnyNode, -1, &NODEVALC);

显然缺少一些部分,但我想指出的是NODEVALA,NODEVALB和NODEVALC有你想要的任何类型,列表以void指针的形式保存它们。

在你的情况下,可以在运行时

期间使用递归调用来完成
switch(condition){
    case condition_structA:
    structA *X;
    getValPtr(&X);
    ...
    break;
    structB *X;
    getValPtr(&X);
    ...
    case condition_structB:
    break;

}

在C90中,编译器无法自动执行此类操作。要做到这一点,你需要多态,那将是C ++或更好。