简体   繁体   English

c中的类型转换

[英]typecasting in c

I would like to know if it is possible to get the type to which I would like to cast dynamically. 我想知道是否有可能将我想动态转换的类型。 For eg. 例如。

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

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

Now I want to know if I can typecast ptr to type some or some_other dynamically. 现在,我想知道是否可以通过类型转换ptr来动态键入some或some_other。

precisely what I want to know is if it is possible to have a macro, TYPE_CAST(comdition) which gives me the type like shown below: 正是我想知道的是,是否可以有一个宏TYPE_CAST(comdition) ,它为我提供了如下所示的类型:

(TYPE_CAST(condition)) ptr->common_field

should be equivalent to 应该等于

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

based on the condition 根据condition

The following doesn't work, just giving this so that it might be clear to understand c than english: 下面的代码行不通,只是给它一个代码,以使您比英语更清楚地了解c:

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

Can something along these lines can be done. 可以按照这些思路做些什么。

Thanks. 谢谢。

That's pretty much not possible. 那几乎是不可能的。 The type of an expression is determined at compile time; 表达式的类型在编译时确定。 it can't depend on any execution time condition. 它不能取决于任何执行时间条件。

You can, given a void* that you know points to an object of one type or the other, do something similar (I have not tested this): 给定一个已知的void* ,您可以指向一种类型的对象或另一种类型的对象,您可以执行类似的操作(我尚未对此进行测试):

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

Note that the ->common_field part of the expression has to be repeated; 注意,表达式的->common_field部分必须重复; the compiler has to know the type of the left operand of the -> operator. 编译器必须知道->运算符的左操作数的类型。

(Depending on the context, an if/else statement might be clearer.) (取决于上下文,if / else语句可能更清晰。)

A way to design your data structures to avoid your problem could be: 设计数据结构以避免问题的一种方法可能是:

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

Then you can easily access the common member with ptr->common_field regardless of which of the two variants you have. 然后,您可以使用ptr->common_field轻松访问common成员,而不管您拥有两个变体中的哪一个。 I would imagine that the value of this common field will tell you which of the two members of the union you need to use to access the remaining members, which you will then access as ptr->some.member1 or ptr->some_other.member2 . 我想像一下,该公共字段的值将告诉您需要使用工会的两个成员中的哪个来访问其余成员,然后您将以ptr->some.member1ptr->some_other.member2

C90 does not support this directly C90不直接支持此功能

I assume you want to write a generic list of some sort in c90. 我假设您想在c90中编写某种通用列表。 Here are some snippets i use in a generic c90 list of mine: 这是我在通用的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)) 

using this you can access the content when calling it and always get the rigth type back. 使用此方法,您可以在调用内容时访问其内容,并始终返回原始类型。 Here are some examples: 这里有些例子:

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

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

there are obviousely some parts missing , but what i want to point out is that NODEVALA, NODEVALB and NODEVALC have whatever type you want them to have and the list saves them in form of a void pointer. 显然有一些部分缺失,但是我要指出的是NODEVALA,NODEVALB和NODEVALC具有您想要的任何类型,并且列表以空指针的形式保存它们。

in your case this could be done with recursive calls during runtime 在您的情况下,可以在运行时通过递归调用来完成

switch(condition){
    case condition_structA:
    structA *X;
    getValPtr(&X);
    ...
    break;
    structB *X;
    getValPtr(&X);
    ...
    case condition_structB:
    break;

}

In C90 there is no way the compiler can be used to do things like that automatically. 在C90中,无法使用编译器自动执行类似的操作。 To do this you would need polymorphism and that would be C++ or better. 要做到这一点,您将需要多态性,那将是C ++或更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM